Auto merge with /home/aegl/GIT/linus
authorTony Luck <tony.luck@intel.com>
Wed, 15 Jun 2005 21:06:48 +0000 (14:06 -0700)
committerTony Luck <tony.luck@intel.com>
Wed, 15 Jun 2005 21:06:48 +0000 (14:06 -0700)
1223 files changed:
CREDITS
Documentation/00-INDEX
Documentation/BK-usage/00-INDEX [deleted file]
Documentation/BK-usage/bk-kernel-howto.txt [deleted file]
Documentation/BK-usage/bk-make-sum [deleted file]
Documentation/BK-usage/bksend [deleted file]
Documentation/BK-usage/bz64wrap [deleted file]
Documentation/BK-usage/cpcset [deleted file]
Documentation/BK-usage/cset-to-linus [deleted file]
Documentation/BK-usage/csets-to-patches [deleted file]
Documentation/BK-usage/gcapatch [deleted file]
Documentation/BK-usage/unbz64wrap [deleted file]
Documentation/DocBook/libata.tmpl
Documentation/SubmittingPatches
Documentation/aoe/aoe.txt
Documentation/aoe/status.sh
Documentation/cpu-freq/cpufreq-stats.txt [new file with mode: 0644]
Documentation/cpusets.txt
Documentation/dontdiff
Documentation/dvb/README.flexcop [new file with mode: 0644]
Documentation/dvb/bt8xx.txt
Documentation/dvb/ci.txt [new file with mode: 0644]
Documentation/dvb/get_dvb_firmware
Documentation/feature-removal-schedule.txt
Documentation/filesystems/sysfs-pci.txt
Documentation/networking/DLINK.txt
Documentation/networking/vortex.txt
Documentation/pci.txt
Documentation/power/devices.txt
Documentation/power/pci.txt
Documentation/powerpc/hvcs.txt
Documentation/x86_64/boot-options.txt
MAINTAINERS
Makefile
arch/alpha/Kconfig
arch/alpha/kernel/osf_sys.c
arch/arm/Kconfig
arch/arm/boot/compressed/head-xscale.S
arch/arm/configs/badge4_defconfig
arch/arm/configs/h3600_defconfig
arch/arm/configs/hackkit_defconfig
arch/arm/kernel/entry-armv.S
arch/arm/kernel/head.S
arch/arm/kernel/process.c
arch/arm/kernel/sys_arm.c
arch/arm/kernel/traps.c
arch/arm/kernel/vmlinux.lds.S
arch/arm/lib/io-writesw-armv4.S
arch/arm/mach-clps711x/Kconfig
arch/arm/mach-footbridge/Kconfig
arch/arm/mach-imx/Kconfig
arch/arm/mach-ixp4xx/common-pci.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-s3c2410/clock.c
arch/arm/mach-s3c2410/dma.c
arch/arm/mach-s3c2410/s3c2440.c
arch/arm/mach-sa1100/Kconfig
arch/arm/mm/Kconfig
arch/arm/mm/Makefile
arch/arm/mm/copypage-v4mc.S [deleted file]
arch/arm/mm/copypage-v4mc.c [new file with mode: 0644]
arch/arm/mm/copypage-v6.c
arch/arm/mm/copypage-xscale.S [deleted file]
arch/arm/mm/copypage-xscale.c [new file with mode: 0644]
arch/arm/mm/flush.c
arch/arm/mm/minicache.c [deleted file]
arch/arm/mm/mm-armv.c
arch/arm26/Kconfig
arch/h8300/kernel/process.c
arch/i386/Kconfig
arch/i386/Makefile
arch/i386/boot/bootsect.S
arch/i386/boot/video.S
arch/i386/kernel/Makefile
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/apm.c
arch/i386/kernel/cpu/amd.c
arch/i386/kernel/cpu/common.c
arch/i386/kernel/cpu/cpufreq/Kconfig
arch/i386/kernel/cpu/cpufreq/Makefile
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
arch/i386/kernel/cpu/cpufreq/sc520_freq.c [new file with mode: 0644]
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
arch/i386/kernel/cpu/intel_cacheinfo.c
arch/i386/kernel/cpu/mtrr/cyrix.c
arch/i386/kernel/i386_ksyms.c
arch/i386/kernel/kprobes.c
arch/i386/kernel/process.c
arch/i386/kernel/ptrace.c
arch/i386/kernel/setup.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/timers/common.c
arch/i386/kernel/timers/timer_tsc.c
arch/i386/mach-voyager/voyager_smp.c
arch/i386/mm/ioremap.c
arch/i386/pci/fixup.c
arch/i386/pci/irq.c
arch/ia64/Kconfig
arch/ia64/configs/tiger_defconfig
arch/ia64/hp/common/sba_iommu.c
arch/ia64/ia32/ia32_ioctl.c
arch/ia64/ia32/sys_ia32.c
arch/ia64/kernel/acpi.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/fsys.S
arch/ia64/kernel/mca.c
arch/ia64/kernel/mca_drv.c
arch/ia64/kernel/mca_drv_asm.S
arch/ia64/kernel/minstate.h
arch/ia64/kernel/module.c
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/process.c
arch/ia64/kernel/ptrace.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/signal.c
arch/ia64/kernel/smpboot.c
arch/ia64/kernel/sys_ia64.c
arch/ia64/kernel/traps.c
arch/ia64/lib/flush.S
arch/ia64/lib/memcpy_mck.S
arch/ia64/lib/memset.S
arch/ia64/mm/init.c
arch/ia64/sn/kernel/Makefile
arch/ia64/sn/kernel/io_init.c
arch/ia64/sn/kernel/mca.c
arch/ia64/sn/kernel/setup.c
arch/ia64/sn/kernel/tiocx.c
arch/ia64/sn/kernel/xp_main.c [new file with mode: 0644]
arch/ia64/sn/kernel/xp_nofault.S [new file with mode: 0644]
arch/ia64/sn/kernel/xpc.h [new file with mode: 0644]
arch/ia64/sn/kernel/xpc_channel.c [new file with mode: 0644]
arch/ia64/sn/kernel/xpc_main.c [new file with mode: 0644]
arch/ia64/sn/kernel/xpc_partition.c [new file with mode: 0644]
arch/ia64/sn/kernel/xpnet.c [new file with mode: 0644]
arch/ia64/sn/pci/pcibr/pcibr_dma.c
arch/ia64/sn/pci/tioca_provider.c
arch/m68k/configs/amiga_defconfig
arch/m68k/configs/apollo_defconfig
arch/m68k/configs/atari_defconfig
arch/m68k/configs/bvme6000_defconfig
arch/m68k/configs/hp300_defconfig
arch/m68k/configs/mac_defconfig
arch/m68k/configs/mvme147_defconfig
arch/m68k/configs/mvme16x_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/configs/sun3_defconfig
arch/m68k/configs/sun3x_defconfig
arch/m68k/defconfig
arch/m68knommu/Kconfig
arch/m68knommu/kernel/process.c
arch/mips/Kconfig
arch/mips/kernel/ptrace.c
arch/mips/vr41xx/common/pmu.c
arch/parisc/Kconfig
arch/ppc/Kconfig
arch/ppc/boot/images/Makefile
arch/ppc/configs/mpc8555_cds_defconfig
arch/ppc/kernel/cputable.c
arch/ppc/kernel/head_44x.S
arch/ppc/kernel/head_fsl_booke.S
arch/ppc/kernel/misc.S
arch/ppc/kernel/setup.c
arch/ppc/kernel/traps.c
arch/ppc/kernel/vmlinux.lds.S
arch/ppc/lib/string.S
arch/ppc/mm/init.c
arch/ppc/platforms/83xx/mpc834x_sys.c
arch/ppc/platforms/83xx/mpc834x_sys.h
arch/ppc/platforms/85xx/mpc8540_ads.c
arch/ppc/platforms/85xx/mpc85xx_cds_common.c
arch/ppc/platforms/85xx/mpc85xx_cds_common.h
arch/ppc/platforms/85xx/sbc8560.c
arch/ppc/platforms/pmac_cpufreq.c
arch/ppc/platforms/pq2ads.h
arch/ppc/syslib/Makefile
arch/ppc/syslib/ipic.c
arch/ppc/syslib/m8260_pci.c [deleted file]
arch/ppc/syslib/m8260_pci.h [deleted file]
arch/ppc/syslib/m8260_pci_erratum9.c
arch/ppc/syslib/m8260_setup.c
arch/ppc/syslib/m82xx_pci.c [new file with mode: 0644]
arch/ppc/syslib/m82xx_pci.h [new file with mode: 0644]
arch/ppc/syslib/mpc83xx_devices.c
arch/ppc/syslib/mpc85xx_devices.c
arch/ppc/syslib/open_pic.c
arch/ppc/syslib/ppc83xx_setup.c
arch/ppc/syslib/ppc85xx_setup.c
arch/ppc/syslib/prom_init.c
arch/ppc64/Kconfig
arch/ppc64/Kconfig.debug
arch/ppc64/boot/main.c
arch/ppc64/boot/prom.c
arch/ppc64/boot/start.c [deleted file]
arch/ppc64/configs/g5_defconfig
arch/ppc64/configs/iSeries_defconfig
arch/ppc64/configs/maple_defconfig
arch/ppc64/configs/pSeries_defconfig
arch/ppc64/defconfig
arch/ppc64/kernel/entry.S
arch/ppc64/kernel/head.S
arch/ppc64/kernel/iSeries_setup.c
arch/ppc64/kernel/idle.c
arch/ppc64/kernel/kprobes.c
arch/ppc64/kernel/mf.c
arch/ppc64/kernel/misc.S
arch/ppc64/kernel/pSeries_reconfig.c
arch/ppc64/kernel/pSeries_smp.c
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/pmac_smp.c
arch/ppc64/kernel/process.c
arch/ppc64/kernel/prom.c
arch/ppc64/kernel/prom_init.c
arch/ppc64/kernel/ptrace.c
arch/ppc64/kernel/rtc.c
arch/ppc64/kernel/setup.c
arch/ppc64/kernel/signal.c
arch/ppc64/kernel/smp.c
arch/ppc64/kernel/sys_ppc32.c
arch/ppc64/kernel/syscalls.c
arch/ppc64/kernel/sysfs.c
arch/ppc64/kernel/time.c
arch/ppc64/kernel/xics.c
arch/ppc64/mm/hash_native.c
arch/ppc64/mm/hash_utils.c
arch/ppc64/mm/imalloc.c
arch/ppc64/mm/init.c
arch/ppc64/mm/stab.c
arch/s390/appldata/appldata_base.c
arch/s390/appldata/appldata_mem.c
arch/s390/appldata/appldata_net_sum.c
arch/s390/appldata/appldata_os.c
arch/s390/kernel/ptrace.c
arch/s390/mm/fault.c
arch/sh/Kconfig
arch/sparc/kernel/process.c
arch/sparc/prom/memory.c
arch/sparc/prom/sun4prom.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/pci_iommu.c
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/process.c
arch/sparc64/kernel/sbus.c
arch/sparc64/kernel/setup.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/traps.c
arch/sparc64/mm/init.c
arch/um/Kconfig.debug
arch/um/Kconfig_char
arch/um/Kconfig_x86_64
arch/um/Makefile
arch/um/Makefile-i386
arch/um/Makefile-x86_64
arch/um/drivers/Makefile
arch/um/drivers/chan_kern.c
arch/um/drivers/chan_user.c
arch/um/drivers/line.c
arch/um/drivers/mcast_kern.c
arch/um/drivers/mcast_user.c
arch/um/drivers/mmapper_kern.c
arch/um/drivers/net_user.c
arch/um/drivers/random.c
arch/um/drivers/slip.h
arch/um/drivers/slip_common.c [new file with mode: 0644]
arch/um/drivers/slip_common.h [new file with mode: 0644]
arch/um/drivers/slip_kern.c
arch/um/drivers/slip_proto.h [deleted file]
arch/um/drivers/slip_user.c
arch/um/drivers/slirp.h
arch/um/drivers/slirp_kern.c
arch/um/drivers/slirp_user.c
arch/um/drivers/ssl.c
arch/um/drivers/stderr_console.c
arch/um/drivers/stdio_console.c
arch/um/drivers/ubd_kern.c
arch/um/drivers/xterm_kern.c
arch/um/include/2_5compat.h [deleted file]
arch/um/include/common-offsets.h [new file with mode: 0644]
arch/um/include/kern_util.h
arch/um/include/mconsole.h
arch/um/include/net_user.h
arch/um/include/os.h
arch/um/include/skas_ptrace.h
arch/um/include/sysdep-i386/checksum.h
arch/um/include/sysdep-i386/faultinfo.h [new file with mode: 0644]
arch/um/include/sysdep-i386/ptrace.h
arch/um/include/sysdep-i386/sigcontext.h
arch/um/include/sysdep-i386/signal.h
arch/um/include/sysdep-i386/skas_ptrace.h [new file with mode: 0644]
arch/um/include/sysdep-ia64/skas_ptrace.h [new file with mode: 0644]
arch/um/include/sysdep-ppc/skas_ptrace.h [new file with mode: 0644]
arch/um/include/sysdep-x86_64/checksum.h
arch/um/include/sysdep-x86_64/faultinfo.h [new file with mode: 0644]
arch/um/include/sysdep-x86_64/ptrace.h
arch/um/include/sysdep-x86_64/sigcontext.h
arch/um/include/sysdep-x86_64/signal.h
arch/um/include/sysdep-x86_64/skas_ptrace.h [new file with mode: 0644]
arch/um/include/sysrq.h
arch/um/include/user_util.h
arch/um/kernel/Makefile
arch/um/kernel/checksum.c [deleted file]
arch/um/kernel/exec_kern.c
arch/um/kernel/initrd.c [new file with mode: 0644]
arch/um/kernel/initrd_kern.c [deleted file]
arch/um/kernel/initrd_user.c [deleted file]
arch/um/kernel/irq.c
arch/um/kernel/irq_user.c
arch/um/kernel/ksyms.c
arch/um/kernel/main.c
arch/um/kernel/mem.c
arch/um/kernel/process.c
arch/um/kernel/process_kern.c
arch/um/kernel/ptrace.c
arch/um/kernel/sigio_user.c
arch/um/kernel/skas/include/mode_kern-skas.h
arch/um/kernel/skas/include/skas.h
arch/um/kernel/skas/include/uaccess-skas.h
arch/um/kernel/skas/process.c
arch/um/kernel/skas/process_kern.c
arch/um/kernel/skas/trap_user.c
arch/um/kernel/skas/uaccess.c
arch/um/kernel/skas/util/Makefile
arch/um/kernel/skas/util/mk_ptregs-i386.c
arch/um/kernel/skas/util/mk_ptregs-x86_64.c
arch/um/kernel/syscall_kern.c
arch/um/kernel/sysrq.c
arch/um/kernel/time_kern.c
arch/um/kernel/trap_kern.c
arch/um/kernel/trap_user.c
arch/um/kernel/tt/Makefile
arch/um/kernel/tt/include/mode_kern-tt.h
arch/um/kernel/tt/include/uaccess-tt.h
arch/um/kernel/tt/ksyms.c
arch/um/kernel/tt/mem.c
arch/um/kernel/tt/process_kern.c
arch/um/kernel/tt/syscall_user.c
arch/um/kernel/tt/tracer.c
arch/um/kernel/tt/trap_user.c
arch/um/kernel/um_arch.c
arch/um/kernel/uml.lds.S
arch/um/kernel/vmlinux.lds.S [new file with mode: 0644]
arch/um/os-Linux/elf_aux.c
arch/um/os-Linux/file.c
arch/um/os-Linux/process.c
arch/um/os-Linux/signal.c
arch/um/os-Linux/util/Makefile
arch/um/os-Linux/util/mk_user_constants.c
arch/um/scripts/Makefile.rules
arch/um/sys-i386/Makefile
arch/um/sys-i386/checksum.S
arch/um/sys-i386/delay.c
arch/um/sys-i386/kernel-offsets.c [new file with mode: 0644]
arch/um/sys-i386/ksyms.c
arch/um/sys-i386/ldt.c
arch/um/sys-i386/ptrace.c
arch/um/sys-i386/signal.c
arch/um/sys-i386/sysrq.c
arch/um/sys-i386/user-offsets.c [new file with mode: 0644]
arch/um/sys-i386/util/Makefile
arch/um/sys-i386/util/mk_sc.c
arch/um/sys-i386/util/mk_thread.c [new file with mode: 0644]
arch/um/sys-i386/util/mk_thread_kern.c [deleted file]
arch/um/sys-i386/util/mk_thread_user.c [deleted file]
arch/um/sys-ppc/ptrace.c
arch/um/sys-ppc/sysrq.c
arch/um/sys-x86_64/Makefile
arch/um/sys-x86_64/delay.c
arch/um/sys-x86_64/kernel-offsets.c [new file with mode: 0644]
arch/um/sys-x86_64/ksyms.c [new file with mode: 0644]
arch/um/sys-x86_64/ptrace.c
arch/um/sys-x86_64/signal.c
arch/um/sys-x86_64/syscalls.c
arch/um/sys-x86_64/sysrq.c
arch/um/sys-x86_64/um_module.c [new file with mode: 0644]
arch/um/sys-x86_64/user-offsets.c [new file with mode: 0644]
arch/um/sys-x86_64/util/Makefile
arch/um/sys-x86_64/util/mk_sc.c
arch/um/sys-x86_64/util/mk_thread.c [new file with mode: 0644]
arch/um/sys-x86_64/util/mk_thread_kern.c [deleted file]
arch/um/sys-x86_64/util/mk_thread_user.c [deleted file]
arch/um/util/Makefile
arch/um/util/mk_constants.c [new file with mode: 0644]
arch/um/util/mk_constants_kern.c [deleted file]
arch/um/util/mk_constants_user.c [deleted file]
arch/um/util/mk_task.c [new file with mode: 0644]
arch/um/util/mk_task_kern.c [deleted file]
arch/um/util/mk_task_user.c [deleted file]
arch/x86_64/Kconfig
arch/x86_64/boot/bootsect.S
arch/x86_64/defconfig
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/aperture.c
arch/x86_64/kernel/apic.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/kprobes.c
arch/x86_64/kernel/module.c
arch/x86_64/kernel/mpparse.c
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/pmtimer.c [new file with mode: 0644]
arch/x86_64/kernel/ptrace.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/signal.c
arch/x86_64/kernel/smpboot.c
arch/x86_64/kernel/time.c
arch/x86_64/kernel/traps.c
arch/x86_64/kernel/vsyscall.c
arch/x86_64/kernel/x8664_ksyms.c
arch/x86_64/mm/fault.c
arch/x86_64/mm/ioremap.c
crypto/crypto_null.c
crypto/internal.h
drivers/acpi/Kconfig
drivers/acpi/pci_irq.c
drivers/atm/Makefile
drivers/atm/fore200e.c
drivers/atm/he.c
drivers/atm/nicstar.c
drivers/atm/zatm.c
drivers/base/Makefile
drivers/base/bus.c
drivers/base/core.c
drivers/base/interface.c [deleted file]
drivers/base/power/power.h
drivers/base/power/resume.c
drivers/base/power/shutdown.c
drivers/base/power/suspend.c
drivers/block/DAC960.c
drivers/block/DAC960.h
drivers/block/Kconfig
drivers/block/aoe/aoe.h
drivers/block/aoe/aoeblk.c
drivers/block/aoe/aoedev.c
drivers/block/aoe/aoenet.c
drivers/block/floppy.c
drivers/block/genhd.c
drivers/block/ioctl.c
drivers/block/pktcdvd.c
drivers/block/ub.c
drivers/cdrom/cdu31a.c
drivers/cdrom/mcdx.c
drivers/cdrom/sbpcd.c
drivers/cdrom/viocd.c
drivers/char/Kconfig
drivers/char/agp/agp.h
drivers/char/agp/ali-agp.c
drivers/char/agp/amd-k7-agp.c
drivers/char/agp/amd64-agp.c
drivers/char/agp/ati-agp.c
drivers/char/agp/backend.c
drivers/char/agp/efficeon-agp.c
drivers/char/agp/generic.c
drivers/char/agp/hp-agp.c
drivers/char/agp/i460-agp.c
drivers/char/agp/intel-agp.c
drivers/char/agp/sgi-agp.c
drivers/char/agp/sworks-agp.c
drivers/char/agp/uninorth-agp.c
drivers/char/drm/drm_pciids.h
drivers/char/drm/radeon_irq.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/ipmi/ipmi_si_sm.h
drivers/char/keyboard.c
drivers/char/mbcs.c
drivers/char/mbcs.h
drivers/char/mxser.c
drivers/char/raw.c
drivers/char/sonypi.c
drivers/char/tty_io.c
drivers/char/watchdog/i8xx_tco.c
drivers/cpufreq/Kconfig
drivers/cpufreq/Makefile
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c [new file with mode: 0644]
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_stats.c
drivers/firmware/pcdp.c
drivers/i2c/busses/i2c-ali1563.c
drivers/i2c/busses/i2c-keywest.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-floppy.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide-tape.c
drivers/ide/ide.c
drivers/ide/pci/amd74xx.c
drivers/ide/pci/sis5513.c
drivers/ieee1394/Kconfig
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_transactions.c
drivers/ieee1394/ieee1394_transactions.h
drivers/ieee1394/nodemgr.c
drivers/ieee1394/ohci1394.c
drivers/ieee1394/ohci1394.h
drivers/ieee1394/pcilynx.c
drivers/ieee1394/pcilynx.h
drivers/ieee1394/video1394.c
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/include/ib_sa.h
drivers/input/gameport/Kconfig
drivers/input/joydev.c
drivers/input/keyboard/atkbd.c
drivers/input/mouse/alps.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/synaptics.c
drivers/input/mousedev.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/serio/serio.c
drivers/input/serio/serport.c
drivers/input/touchscreen/gunze.c
drivers/macintosh/therm_adt746x.c
drivers/macintosh/via-pmu.c
drivers/md/dm-emc.c
drivers/md/dm-hw-handler.c
drivers/md/dm-mpath.c
drivers/md/dm-path-selector.c
drivers/md/dm-table.c
drivers/md/dm-zero.c
drivers/md/dm.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/md/raid6main.c
drivers/media/common/saa7146_core.c
drivers/media/dvb/Kconfig
drivers/media/dvb/b2c2/Kconfig
drivers/media/dvb/b2c2/Makefile
drivers/media/dvb/b2c2/b2c2-common.c [deleted file]
drivers/media/dvb/b2c2/b2c2-usb-core.c [deleted file]
drivers/media/dvb/b2c2/flexcop-common.h [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-dma.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-eeprom.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-fe-tuner.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-hw-filter.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-i2c.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-misc.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-pci.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-reg.h [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-sram.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-usb.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop-usb.h [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop.c [new file with mode: 0644]
drivers/media/dvb/b2c2/flexcop.h [new file with mode: 0644]
drivers/media/dvb/b2c2/skystar2.c
drivers/media/dvb/bt8xx/Kconfig
drivers/media/dvb/bt8xx/Makefile
drivers/media/dvb/bt8xx/bt878.c
drivers/media/dvb/bt8xx/bt878.h
drivers/media/dvb/bt8xx/dst.c
drivers/media/dvb/bt8xx/dst.h [deleted file]
drivers/media/dvb/bt8xx/dst_ca.c [new file with mode: 0644]
drivers/media/dvb/bt8xx/dst_ca.h [new file with mode: 0644]
drivers/media/dvb/bt8xx/dst_common.h [new file with mode: 0644]
drivers/media/dvb/bt8xx/dst_priv.h
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/bt8xx/dvb-bt8xx.h
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
drivers/media/dvb/dibusb/dvb-dibusb.h
drivers/media/dvb/dvb-core/dmxdev.c
drivers/media/dvb/dvb-core/dvb_ca_en50221.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-core/dvb_net.c
drivers/media/dvb/dvb-core/dvbdev.c
drivers/media/dvb/dvb-core/dvbdev.h
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/frontends/at76c651.c
drivers/media/dvb/frontends/cx22700.c
drivers/media/dvb/frontends/cx22702.c
drivers/media/dvb/frontends/cx24110.c
drivers/media/dvb/frontends/dib3000mb.c
drivers/media/dvb/frontends/dib3000mc.c
drivers/media/dvb/frontends/dvb-pll.h
drivers/media/dvb/frontends/dvb_dummy_fe.c
drivers/media/dvb/frontends/l64781.c
drivers/media/dvb/frontends/mt312.c
drivers/media/dvb/frontends/mt352.c
drivers/media/dvb/frontends/mt352.h
drivers/media/dvb/frontends/nxt2002.c
drivers/media/dvb/frontends/nxt6000.c
drivers/media/dvb/frontends/nxt6000_priv.h
drivers/media/dvb/frontends/or51132.c
drivers/media/dvb/frontends/sp8870.c
drivers/media/dvb/frontends/sp887x.c
drivers/media/dvb/frontends/stv0297.c
drivers/media/dvb/frontends/stv0299.c
drivers/media/dvb/frontends/tda10021.c
drivers/media/dvb/frontends/tda1004x.c
drivers/media/dvb/frontends/tda1004x.h
drivers/media/dvb/frontends/tda8083.c
drivers/media/dvb/frontends/tda80xx.c
drivers/media/dvb/frontends/ves1820.c
drivers/media/dvb/frontends/ves1x93.c
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/av7110.h
drivers/media/dvb/ttpci/av7110_av.c
drivers/media/dvb/ttpci/av7110_ca.c
drivers/media/dvb/ttpci/av7110_hw.c
drivers/media/dvb/ttpci/av7110_hw.h
drivers/media/dvb/ttpci/av7110_ir.c
drivers/media/dvb/ttpci/av7110_v4l.c
drivers/media/dvb/ttpci/budget-av.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttpci/budget-core.c
drivers/media/dvb/ttpci/budget-patch.c
drivers/media/dvb/ttpci/budget.c
drivers/media/dvb/ttpci/budget.h
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/dvb/ttusb-dec/ttusb_dec.c
drivers/media/video/Kconfig
drivers/media/video/bttv-cards.c
drivers/media/video/bttv-i2c.c
drivers/media/video/saa7134/saa6752hs.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/tuner-core.c
drivers/media/video/video-buf-dvb.c
drivers/message/i2o/i2o_block.c
drivers/mmc/Kconfig
drivers/mmc/mmc_block.c
drivers/mmc/wbsd.c
drivers/mmc/wbsd.h
drivers/net/3c59x.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/Space.c
drivers/net/amd8111e.c
drivers/net/appletalk/Kconfig
drivers/net/appletalk/cops.c
drivers/net/appletalk/cops_ffdrv.h
drivers/net/appletalk/cops_ltdrv.h
drivers/net/appletalk/ltpc.c
drivers/net/arcnet/capmode.c
drivers/net/bnx2.c [new file with mode: 0644]
drivers/net/bnx2.h [new file with mode: 0644]
drivers/net/bnx2_fw.h [new file with mode: 0644]
drivers/net/bonding/bond_main.c
drivers/net/e100.c
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_main.c
drivers/net/e1000/e1000_osdep.h
drivers/net/e1000/e1000_param.c
drivers/net/forcedeth.c
drivers/net/hamradio/Kconfig
drivers/net/hamradio/baycom_epp.c
drivers/net/ibm_emac/ibm_emac_core.c
drivers/net/irda/Kconfig
drivers/net/iseries_veth.c
drivers/net/ixgb/ixgb.h
drivers/net/ixgb/ixgb_ee.c
drivers/net/ixgb/ixgb_ethtool.c
drivers/net/ixgb/ixgb_main.c
drivers/net/ixgb/ixgb_osdep.h
drivers/net/loopback.c
drivers/net/natsemi.c
drivers/net/ns83820.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcnet32.c
drivers/net/r8169.c
drivers/net/shaper.c
drivers/net/sis900.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tlan.c
drivers/net/tulip/media.c
drivers/net/tulip/tulip_core.c
drivers/net/wan/Kconfig
drivers/net/wireless/Kconfig
drivers/net/wireless/airo.c
drivers/net/wireless/atmel_cs.c
drivers/parport/Kconfig
drivers/parport/parport_pc.c
drivers/pci/hotplug.c
drivers/pci/hotplug/cpci_hotplug.h
drivers/pci/hotplug/cpci_hotplug_core.c
drivers/pci/hotplug/cpci_hotplug_pci.c
drivers/pci/hotplug/ibmphp.h
drivers/pci/hotplug/ibmphp_hpc.c
drivers/pci/hotplug/ibmphp_pci.c
drivers/pci/hotplug/pci_hotplug.h
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/pcihp_skeleton.c
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_ctrl.c
drivers/pci/hotplug/shpchprm_acpi.c
drivers/pci/msi.c
drivers/pci/pci-acpi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pci.ids
drivers/pci/pcie/portdrv_bus.c
drivers/pci/probe.c
drivers/pci/proc.c
drivers/pci/quirks.c
drivers/pcmcia/ds.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/ti113x.h
drivers/s390/block/dasd.c
drivers/s390/net/Makefile
drivers/s390/net/ctcdbug.h
drivers/s390/net/ctcmain.c
drivers/s390/net/ctcmain.h [new file with mode: 0644]
drivers/s390/net/ctctty.c
drivers/s390/net/cu3088.c
drivers/s390/net/cu3088.h
drivers/s390/net/iucv.c
drivers/s390/net/lcs.c
drivers/s390/net/qeth.h
drivers/s390/net/qeth_eddp.c
drivers/s390/net/qeth_main.c
drivers/s390/net/qeth_tso.c [deleted file]
drivers/s390/net/qeth_tso.h
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_def.h
drivers/sbus/char/aurora.c
drivers/scsi/Kconfig
drivers/scsi/NCR53C9x.c
drivers/scsi/aacraid/linit.c
drivers/scsi/ahci.c
drivers/scsi/aic7xxx/aic7770_osm.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.h
drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
drivers/scsi/aic7xxx/aic7xxx_proc.c
drivers/scsi/aic7xxx/aiclib.c
drivers/scsi/ata_piix.c
drivers/scsi/ide-scsi.c
drivers/scsi/libata-core.c
drivers/scsi/libata-scsi.c
drivers/scsi/libata.h
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/sata_nv.c
drivers/scsi/sata_promise.c
drivers/scsi/sata_qstor.c
drivers/scsi/sata_sil.c
drivers/scsi/sata_sis.c
drivers/scsi/sata_svw.c
drivers/scsi/sata_sx4.c
drivers/scsi/sata_uli.c
drivers/scsi/sata_via.c
drivers/scsi/sata_vsc.c
drivers/scsi/scsi.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_transport_spi.c
drivers/scsi/sr_ioctl.c
drivers/scsi/sym53c416.c
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/serial/21285.c
drivers/serial/8250.c
drivers/serial/8250_pci.c
drivers/serial/amba-pl010.c
drivers/serial/amba-pl011.c
drivers/serial/clps711x.c
drivers/serial/pxa.c
drivers/serial/s3c2410.c
drivers/serial/sa1100.c
drivers/serial/serial_cs.c
drivers/serial/serial_lh7a40x.c
drivers/serial/serial_txx9.c
drivers/serial/sunsab.c
drivers/serial/sunsab.h
drivers/serial/vr41xx_siu.c
drivers/telephony/ixj.c
drivers/telephony/ixj.h
drivers/usb/atm/speedtch.c
drivers/usb/core/message.c
drivers/usb/core/sysfs.c
drivers/usb/core/urb.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/gadget/serial.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci.h
drivers/usb/host/hc_crisv10.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/sl811_cs.c [new file with mode: 0644]
drivers/usb/image/mdc800.c
drivers/usb/input/aiptek.c
drivers/usb/input/hid-core.c
drivers/usb/input/mtouchusb.c
drivers/usb/media/ov511.c
drivers/usb/media/pwc/ChangeLog [deleted file]
drivers/usb/media/pwc/Makefile
drivers/usb/media/pwc/pwc-ctrl.c
drivers/usb/media/pwc/pwc-dec1.c [deleted file]
drivers/usb/media/pwc/pwc-dec1.h [deleted file]
drivers/usb/media/pwc/pwc-dec23.c [deleted file]
drivers/usb/media/pwc/pwc-dec23.h [deleted file]
drivers/usb/media/pwc/pwc-if.c
drivers/usb/media/pwc/pwc-ioctl.h
drivers/usb/media/pwc/pwc-kiara.c
drivers/usb/media/pwc/pwc-timon.c
drivers/usb/media/pwc/pwc-uncompress.c
drivers/usb/misc/legousbtower.c
drivers/usb/net/Kconfig
drivers/usb/net/usbnet.c
drivers/usb/net/zd1201.c
drivers/usb/serial/Kconfig
drivers/usb/serial/Makefile
drivers/usb/serial/airprime.c [new file with mode: 0644]
drivers/usb/serial/cp2101.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/cypress_m8.h
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/io_usbvend.h
drivers/usb/serial/keyspan_usa90msg.h
drivers/usb/serial/option.c [new file with mode: 0644]
drivers/usb/serial/usb-serial.c
drivers/usb/storage/debug.c
drivers/usb/storage/shuttle_usbat.c
drivers/usb/storage/unusual_devs.h
drivers/video/aty/radeon_base.c
drivers/video/fbmem.c
drivers/video/fbsysfs.c
drivers/video/i810/i810_main.c
drivers/video/intelfb/intelfbdrv.c
drivers/video/macmodes.c
drivers/video/sis/init.c
drivers/video/sis/init.h
drivers/video/sis/init301.c
drivers/video/sis/init301.h
drivers/video/sis/sis_main.c
fs/bad_inode.c
fs/binfmt_elf.c
fs/binfmt_flat.c
fs/block_dev.c
fs/buffer.c
fs/char_dev.c
fs/cifs/CHANGES
fs/cifs/README
fs/cifs/cifsfs.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/misc.c
fs/dcache.c
fs/eventpoll.c
fs/exec.c
fs/ext3/inode.c
fs/ext3/super.c
fs/hostfs/hostfs_kern.c
fs/inode.c
fs/jbd/checkpoint.c
fs/jffs2/compr_rubin.c
fs/jffs2/compr_zlib.c
fs/jfs/jfs_xtree.c
fs/locks.c
fs/mbcache.c
fs/mpage.c
fs/namei.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/idmap.c
fs/nfs/inode.c
fs/nls/nls_base.c
fs/partitions/msdos.c
fs/proc/base.c
fs/proc/mmu.c
fs/proc/proc_devtree.c
fs/reiserfs/namei.c
fs/reiserfs/stree.c
fs/reiserfs/super.c
fs/select.c
fs/udf/udftime.c
fs/xfs/Makefile
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/linux-2.6/xfs_file.c
fs/xfs/linux-2.6/xfs_ioctl32.c
fs/xfs/linux-2.6/xfs_ioctl32.h
fs/xfs/linux-2.6/xfs_lrw.c
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_vnode.c
fs/xfs/linux-2.6/xfs_vnode.h
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_iget.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_iomap.c
fs/xfs/xfs_iomap.h
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_types.h
fs/xfs/xfs_utils.c
fs/xfs/xfs_utils.h
fs/xfs/xfs_vfsops.c
fs/xfs/xfs_vnodeops.c
include/asm-alpha/agp.h
include/asm-alpha/signal.h
include/asm-arm/arch-imx/imx-regs.h
include/asm-arm/arch-imx/imxfb.h [new file with mode: 0644]
include/asm-arm/arch-ixp2000/io.h
include/asm-arm/arch-pxa/pxa-regs.h
include/asm-arm/arch-s3c2410/regs-nand.h
include/asm-arm/elf.h
include/asm-arm/page.h
include/asm-arm/processor.h
include/asm-arm/signal.h
include/asm-arm/thread_info.h
include/asm-arm26/elf.h
include/asm-arm26/signal.h
include/asm-cris/signal.h
include/asm-frv/signal.h
include/asm-generic/sections.h
include/asm-generic/signal.h [new file with mode: 0644]
include/asm-h8300/kmap_types.h
include/asm-h8300/mman.h
include/asm-h8300/signal.h
include/asm-i386/agp.h
include/asm-i386/floppy.h
include/asm-i386/linkage.h
include/asm-i386/mach-numaq/mach_ipi.h
include/asm-i386/module.h
include/asm-i386/signal.h
include/asm-i386/timer.h
include/asm-ia64/agp.h
include/asm-ia64/ioctl32.h [deleted file]
include/asm-ia64/perfmon.h
include/asm-ia64/pgtable.h
include/asm-ia64/processor.h
include/asm-ia64/signal.h
include/asm-ia64/sn/addrs.h
include/asm-ia64/sn/arch.h
include/asm-ia64/sn/fetchop.h [deleted file]
include/asm-ia64/sn/l1.h
include/asm-ia64/sn/nodepda.h
include/asm-ia64/sn/pda.h
include/asm-ia64/sn/shub_mmr.h
include/asm-ia64/sn/shubio.h
include/asm-ia64/sn/sn_cpuid.h
include/asm-ia64/sn/sn_fru.h [deleted file]
include/asm-ia64/sn/sn_sal.h
include/asm-ia64/sn/sndrv.h [deleted file]
include/asm-ia64/sn/xp.h [new file with mode: 0644]
include/asm-m32r/signal.h
include/asm-m68k/signal.h
include/asm-m68knommu/signal.h
include/asm-mips/signal.h
include/asm-parisc/floppy.h
include/asm-ppc/agp.h
include/asm-ppc/cpm2.h
include/asm-ppc/m8260_pci.h
include/asm-ppc/mpc8260.h
include/asm-ppc/sigcontext.h
include/asm-ppc/signal.h
include/asm-ppc64/agp.h
include/asm-ppc64/elf.h
include/asm-ppc64/iSeries/mf.h
include/asm-ppc64/imalloc.h [new file with mode: 0644]
include/asm-ppc64/mmu.h
include/asm-ppc64/mmu_context.h
include/asm-ppc64/page.h
include/asm-ppc64/pgtable.h
include/asm-ppc64/processor.h
include/asm-ppc64/prom.h
include/asm-ppc64/signal.h
include/asm-ppc64/thread_info.h
include/asm-ppc64/xics.h
include/asm-s390/signal.h
include/asm-s390/user.h
include/asm-sh/floppy.h
include/asm-sh/signal.h
include/asm-sh/thread_info.h
include/asm-sh64/signal.h
include/asm-sh64/thread_info.h
include/asm-sparc/floppy.h
include/asm-sparc/signal.h
include/asm-sparc/uaccess.h
include/asm-sparc64/agp.h
include/asm-sparc64/iommu.h
include/asm-sparc64/parport.h
include/asm-sparc64/pbm.h
include/asm-sparc64/pgalloc.h
include/asm-sparc64/signal.h
include/asm-sparc64/spitfire.h
include/asm-um/arch-signal-i386.h [deleted file]
include/asm-um/archparam-i386.h
include/asm-um/archparam-ppc.h
include/asm-um/archparam-x86_64.h
include/asm-um/delay.h
include/asm-um/elf-i386.h [new file with mode: 0644]
include/asm-um/elf-ppc.h [new file with mode: 0644]
include/asm-um/elf-x86_64.h [new file with mode: 0644]
include/asm-um/elf.h [deleted file]
include/asm-um/fixmap.h
include/asm-um/ipc.h
include/asm-um/linkage.h
include/asm-um/page.h
include/asm-um/pgtable-3level.h
include/asm-um/pgtable.h
include/asm-um/processor-generic.h
include/asm-um/processor-i386.h
include/asm-um/processor-x86_64.h
include/asm-um/ptrace-i386.h
include/asm-um/ptrace-x86_64.h
include/asm-um/setup.h
include/asm-um/thread_info.h
include/asm-v850/signal.h
include/asm-x86_64/agp.h
include/asm-x86_64/apicdef.h
include/asm-x86_64/bug.h
include/asm-x86_64/floppy.h
include/asm-x86_64/io_apic.h
include/asm-x86_64/ioctl32.h [deleted file]
include/asm-x86_64/nmi.h
include/asm-x86_64/processor.h
include/asm-x86_64/proto.h
include/asm-x86_64/signal.h
include/asm-x86_64/vsyscall.h
include/linux/acpi.h
include/linux/audit.h
include/linux/awe_voice.h
include/linux/binfmts.h
include/linux/cpufreq.h
include/linux/device.h
include/linux/err.h
include/linux/etherdevice.h
include/linux/ethtool.h
include/linux/fddidevice.h
include/linux/fs.h
include/linux/gameport.h
include/linux/hardirq.h
include/linux/hippidevice.h
include/linux/ide.h
include/linux/if.h
include/linux/if_arp.h
include/linux/if_ltalk.h
include/linux/if_shaper.h
include/linux/if_tr.h
include/linux/inetdevice.h
include/linux/ixjuser.h
include/linux/kprobes.h
include/linux/libata.h
include/linux/mii.h
include/linux/mm.h
include/linux/mmc/protocol.h
include/linux/mpage.h
include/linux/net.h
include/linux/netdevice.h
include/linux/netlink.h
include/linux/notifier.h
include/linux/patchkey.h [new file with mode: 0644]
include/linux/pci.h
include/linux/pci_ids.h
include/linux/pkt_sched.h
include/linux/sched.h
include/linux/serial_core.h
include/linux/signal.h
include/linux/sockios.h
include/linux/soundcard.h
include/linux/spinlock.h
include/linux/sysctl.h
include/linux/tc_ematch/tc_em_meta.h
include/linux/trdevice.h
include/linux/usb.h
include/linux/vmalloc.h
include/linux/wait.h
include/media/video-buf-dvb.h
include/net/act_generic.h
include/net/addrconf.h
include/net/icmp.h
include/net/ip.h
include/net/route.h
include/net/sock.h
include/net/tcp.h
include/net/udp.h
include/net/xfrm.h
include/scsi/scsi_transport_spi.h
init/Kconfig
kernel/Makefile
kernel/audit.c
kernel/auditsc.c
kernel/cpuset.c
kernel/exit.c
kernel/irq/handle.c
kernel/itimer.c
kernel/kallsyms.c
kernel/kprobes.c
kernel/module.c
kernel/power/main.c
kernel/printk.c
kernel/profile.c
kernel/sched.c
kernel/signal.c
kernel/spinlock.c
kernel/sys.c
lib/Kconfig.debug
lib/sort.c
lib/string.c
mm/filemap.c
mm/memory.c
mm/mmap.c
mm/mremap.c
mm/nommu.c
mm/page_alloc.c
mm/rmap.c
mm/swapfile.c
mm/vmalloc.c
net/802/fddi.c
net/802/hippi.c
net/802/tr.c
net/appletalk/dev.c
net/bridge/br_device.c
net/bridge/br_if.c
net/bridge/br_input.c
net/bridge/br_notify.c
net/bridge/br_private.h
net/bridge/br_stp_bpdu.c
net/core/dev.c
net/core/ethtool.c
net/core/net-sysfs.c
net/core/sock.c
net/decnet/dn_dev.c
net/ethernet/eth.c
net/ipv4/af_inet.c
net/ipv4/devinet.c
net/ipv4/esp4.c
net/ipv4/icmp.c
net/ipv4/ip_input.c
net/ipv4/ip_output.c
net/ipv4/ipvs/Makefile
net/ipv4/ipvs/ip_vs_proto.c
net/ipv4/ipvs/ip_vs_proto_icmp.c [deleted file]
net/ipv4/ipvs/ip_vs_xmit.c
net/ipv4/multipath_drr.c
net/ipv4/multipath_random.c
net/ipv4/multipath_rr.c
net/ipv4/multipath_wrandom.c
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_queue.c
net/ipv4/protocol.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/icmp.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ipv6_syms.c
net/ipv6/xfrm6_output.c
net/ipv6/xfrm6_policy.c
net/irda/irda_device.c
net/netlink/af_netlink.c
net/packet/af_packet.c
net/sched/Kconfig
net/sched/act_api.c
net/sched/cls_basic.c
net/sched/em_meta.c
net/sched/sch_dsmark.c
net/sched/sch_netem.c
net/sctp/input.c
net/sctp/ipv6.c
net/sctp/proc.c
net/sctp/protocol.c
net/sctp/socket.c
net/socket.c
net/unix/af_unix.c
net/xfrm/xfrm_algo.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c
scripts/kallsyms.c
scripts/kconfig/Makefile
scripts/kconfig/POTFILES.in [new file with mode: 0644]
scripts/kconfig/conf.c
scripts/kconfig/confdata.c
scripts/kconfig/gconf.c
scripts/kconfig/kxgettext.c [new file with mode: 0644]
scripts/kconfig/lkc.h
scripts/kconfig/mconf.c
scripts/kconfig/menu.c
scripts/kconfig/qconf.cc
scripts/patch-kernel
security/selinux/ss/services.c
sound/isa/Kconfig
sound/oss/Kconfig
sound/oss/ac97_codec.c
sound/pci/intel8x0.c
sound/pci/via82xx.c
sound/ppc/pmac.c
sound/usb/usbaudio.c
sound/usb/usx2y/usbusx2y.c

diff --git a/CREDITS b/CREDITS
index c9068febcffcd0d111dbf0771f5a09b149be7012..d65ffe5a4d0803c59159592b258f0dfc049ec8d3 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -339,7 +339,7 @@ W: http://tomas.nocrew.org/
 D: dsp56k device driver
 
 N: Ross Biro
-E: bir7@leland.Stanford.Edu
+E: ross.biro@gmail.com
 D: Original author of the Linux networking code
 
 N: Anton Blanchard
@@ -882,13 +882,12 @@ S: Blacksburg, Virginia 24061
 S: USA
 
 N: Randy Dunlap
-E: rddunlap@osdl.org
+E: rdunlap@xenotime.net
 W: http://www.xenotime.net/linux/linux.html
 W: http://www.linux-usb.org
 D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers
 D: x86 SMP, ACPI, bootflag hacking
-S: 12725 SW Millikan Way, Suite 400
-S: Beaverton, Oregon 97005
+S: (ask for current address)
 S: USA
 
 N: Bob Dunlop
@@ -2476,13 +2475,9 @@ S: Potsdam, New York 13676
 S: USA
 
 N: Dave Neuer
-E: dneuer@innovation-charter.com
-E: mr_fred_smoothie@yahoo.com
+E: dave.neuer@pobox.com
 D: Helped implement support for Compaq's H31xx series iPAQs
 D: Other mostly minor tweaks & bugfixes
-S: 325 E. Main St., Suite 3
-S: Carnegie, PA 15105
-S: USA
 
 N: Michael Neuffer
 E: mike@i-Connect.Net
index 72dc90f8f4a7046dd542da61bebcbca10e90cf94..8de8a01a2474bc4ab429e6d97225a1f61af957c0 100644 (file)
@@ -12,8 +12,6 @@ Following translations are available on the WWW:
 
 00-INDEX
        - this file.
-BK-usage/
-       - directory with info on BitKeeper.
 BUG-HUNTING
        - brute force method of doing binary search of patches to find bug.
 Changes
diff --git a/Documentation/BK-usage/00-INDEX b/Documentation/BK-usage/00-INDEX
deleted file mode 100644 (file)
index 8276878..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-bk-kernel-howto.txt: Description of kernel workflow under BitKeeper
-
-bk-make-sum: Create summary of changesets in one repository and not
-another, typically in preparation to be sent to an upstream maintainer.
-Typical usage:
-       cd my-updated-repo
-       bk-make-sum ~/repo/original-repo
-       mv /tmp/linus.txt ../original-repo.txt
-
-bksend: Create readable text output containing summary of changes, GNU
-patch of the changes, and BK metadata of changes (as needed for proper
-importing into BitKeeper by an upstream maintainer).  This output is
-suitable for emailing BitKeeper changes.  The recipient of this output
-may pipe it directly to 'bk receive'.
-
-bz64wrap: helper script. Uncompressed input is piped to this script,
-which compresses its input, and then outputs the uu-/base64-encoded
-version of the compressed input.
-
-cpcset: Copy changeset between unrelated repositories.
-Attempts to preserve changeset user, user address, description, in
-addition to the changeset (the patch) itself.
-Typical usage:
-       cd my-updated-repo
-       bk changes      # looking for a changeset...
-       cpcset 1.1511 . ../another-repo
-
-csets-to-patches: Produces a delta of two BK repositories, in the form
-of individual files, each containing a single cset as a GNU patch.
-Output is several files, each with the filename "/tmp/rev-$REV.patch"
-Typical usage:
-       cd my-updated-repo
-       bk changes -L ~/repo/original-repo 2>&1 | \
-               perl csets-to-patches
-
-cset-to-linus: Produces a delta of two BK repositories, in the form of
-changeset descriptions, with 'diffstat' output created for each
-individual changset.
-Typical usage:
-       cd my-updated-repo
-       bk changes -L ~/repo/original-repo 2>&1 | \
-               perl cset-to-linus > summary.txt
-
-gcapatch:  Generates patch containing changes in local repository.
-Typical usage:
-       cd my-updated-repo
-       gcapatch > foo.patch
-
-unbz64wrap: Reverse an encoded, compressed data stream created by
-bz64wrap into an uncompressed, typically text/plain output.
-
diff --git a/Documentation/BK-usage/bk-kernel-howto.txt b/Documentation/BK-usage/bk-kernel-howto.txt
deleted file mode 100644 (file)
index b7b9075..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-
-                  Doing the BK Thing, Penguin-Style
-
-
-
-
-This set of notes is intended mainly for kernel developers, occasional
-or full-time, but sysadmins and power users may find parts of it useful
-as well.  It assumes at least a basic familiarity with CVS, both at a
-user level (use on the cmd line) and at a higher level (client-server model).
-Due to the author's background, an operation may be described in terms
-of CVS, or in terms of how that operation differs from CVS.
-
-This is -not- intended to be BitKeeper documentation.  Always run
-"bk help <command>" or in X "bk helptool <command>" for reference
-documentation.
-
-
-BitKeeper Concepts
-------------------
-
-In the true nature of the Internet itself, BitKeeper is a distributed
-system.  When applied to revision control, this means doing away with
-client-server, and changing to a parent-child model... essentially
-peer-to-peer.  On the developer's end, this also represents a
-fundamental disruption in the standard workflow of changes, commits,
-and merges.  You will need to take a few minutes to think about
-how to best work under BitKeeper, and re-optimize things a bit.
-In some sense it is a bit radical, because it might described as
-tossing changes out into a maelstrom and having them magically
-land at the right destination... but I'm getting ahead of myself.
-
-Let's start with this progression:
-Each BitKeeper source tree on disk is a repository unto itself.
-Each repository has a parent (except the root/original, of course).
-Each repository contains a set of a changesets ("csets").
-Each cset is one or more changed files, bundled together.
-
-Each tree is a repository, so all changes are checked into the local
-tree.  When a change is checked in, all modified files are grouped
-into a logical unit, the changeset.  Internally, BK links these
-changesets in a tree, representing various converging and diverging
-lines of development.  These changesets are the bread and butter of
-the BK system.
-
-After the concept of changesets, the next thing you need to get used
-to is having multiple copies of source trees lying around.  This -really-
-takes some getting used to, for some people.  Separate source trees
-are the means in BitKeeper by which you delineate parallel lines
-of development, both minor and major.  What would be branches in
-CVS become separate source trees, or "clones" in BitKeeper [heh,
-or Star Wars] terminology.
-
-Clones and changesets are the tools from which most of the power of
-BitKeeper is derived.  As mentioned earlier, each clone has a parent,
-the tree used as the source when the new clone was created.  In a
-CVS-like setup, the parent would be a remote server on the Internet,
-and the child is your local clone of that tree.
-
-Once you have established a common baseline between two source trees --
-a common parent -- then you can merge changesets between those two
-trees with ease.  Merging changes into a tree is called a "pull", and
-is analagous to 'cvs update'.  A pull downloads all the changesets in
-the remote tree you do not have, and merges them.  Sending changes in
-one tree to another tree is called a "push".  Push sends all changes
-in the local tree the remote does not yet have, and merges them.
-
-From these concepts come some initial command examples:
-
-1) bk clone -q http://linux.bkbits.net/linux-2.5 linus-2.5
-Download a 2.5 stock kernel tree, naming it "linus-2.5" in the local dir.
-The "-q" disables listing every single file as it is downloaded.
-
-2) bk clone -ql linus-2.5 alpha-2.5
-Create a separate source tree for the Alpha AXP architecture.
-The "-l" uses hard links instead of copying data, since both trees are
-on the local disk.  You can also replace the above with "bk lclone -q ..."
-
-You only clone a tree -once-.  After cloning the tree lives a long time
-on disk, being updating by pushes and pulls.
-
-3) cd alpha-2.5 ; bk pull http://gkernel.bkbits.net/alpha-2.5
-Download changes in "alpha-2.5" repository which are not present
-in the local repository, and merge them into the source tree.
-
-4) bk -r co -q
-Because every tree is a repository, files must be checked out before
-they will be in their standard places in the source tree.
-
-5)     bk vi fs/inode.c                                # example change...
-       bk citool                                       # checkin, using X tool
-       bk push bk://gkernel@bkbits.net/alpha-2.5       # upload change
-Typical example of a BK sequence that would replace the analagous CVS
-situation,
-       vi fs/inode.c
-       cvs commit
-
-As this is just supposed to be a quick BK intro, for more in-depth
-tutorials, live working demos, and docs, see http://www.bitkeeper.com/
-
-
-
-BK and Kernel Development Workflow
-----------------------------------
-Currently the latest 2.5 tree is available via "bk clone $URL"
-and "bk pull $URL" at http://linux.bkbits.net/linux-2.5
-This should change in a few weeks to a kernel.org URL.
-
-
-A big part of using BitKeeper is organizing the various trees you have
-on your local disk, and organizing the flow of changes among those
-trees, and remote trees.  If one were to graph the relationships between
-a desired BK setup, you are likely to see a few-many-few graph, like
-this:
-
-                   linux-2.5
-                       |
-              merge-to-linus-2.5
-                /    |      |
-               /     |      |
-       vm-hacks  bugfixes  filesys   personal-hacks
-             \       |      |          /
-              \      |      |         /
-               \     |      |        /
-                testing-and-validation
-
-Since a "bk push" sends all changes not in the target tree, and
-since a "bk pull" receives all changes not in the source tree, you want
-to make sure you are only pushing specific changes to the desired tree,
-not all changes from "peer parent" trees.  For example, pushing a change
-from the testing-and-validation tree would probably be a bad idea,
-because it will push all changes from vm-hacks, bugfixes, filesys, and
-personal-hacks trees into the target tree.
-
-One would typically work on only one "theme" at a time, either
-vm-hacks or bugfixes or filesys, keeping those changes isolated in
-their own tree during development, and only merge the isolated with
-other changes when going upstream (to Linus or other maintainers) or
-downstream (to your "union" trees, like testing-and-validation above).
-
-It should be noted that some of this separation is not just recommended
-practice, it's actually [for now] -enforced- by BitKeeper.  BitKeeper
-requires that changesets maintain a certain order, which is the reason
-that "bk push" sends all local changesets the remote doesn't have.  This
-separation may look like a lot of wasted disk space at first, but it
-helps when two unrelated changes may "pollute" the same area of code, or
-don't follow the same pace of development, or any other of the standard
-reasons why one creates a development branch.
-
-Small development branches (clones) will appear and disappear:
-
-       -------- A --------- B --------- C --------- D -------
-                 \                                 /
-                  -----short-term devel branch-----
-
-While long-term branches will parallel a tree (or trees), with period
-merge points.  In this first example, we pull from a tree (pulls,
-"\") periodically, such as what occurs when tracking changes in a
-vendor tree, never pushing changes back up the line:
-
-       -------- A --------- B --------- C --------- D -------
-                 \                       \           \
-                  ----long-term devel branch-----------------
-
-And then a more common case in Linux kernel development, a long term
-branch with periodic merges back into the tree (pushes, "/"):
-
-       -------- A --------- B --------- C --------- D -------
-                 \                       \         / \
-                  ----long-term devel branch-----------------
-
-
-
-
-
-Submitting Changes to Linus
----------------------------
-There's a bit of an art, or style, of submitting changes to Linus.
-Since Linus's tree is now (you might say) fully integrated into the
-distributed BitKeeper system, there are several prerequisites to
-properly submitting a BitKeeper change.  All these prereq's are just
-general cleanliness of BK usage, so as people become experts at BK, feel
-free to optimize this process further (assuming Linus agrees, of
-course).
-
-
-
-0) Make sure your tree was originally cloned from the linux-2.5 tree
-created by Linus.  If your tree does not have this as its ancestor, it
-is impossible to reliably exchange changesets.
-
-
-
-1) Pay attention to your commit text.  The commit message that
-accompanies each changeset you submit will live on forever in history,
-and is used by Linus to accurately summarize the changes in each
-pre-patch.  Remember that there is no context, so
-       "fix for new scheduler changes"
-would be too vague, but
-       "fix mips64 arch for new scheduler switch_to(), TIF_xxx semantics"
-would be much better.
-
-You can and should use the command "bk comment -C<rev>" to update the
-commit text, and improve it after the fact.  This is very useful for
-development: poor, quick descriptions during development, which get
-cleaned up using "bk comment" before issuing the "bk push" to submit the
-changes.
-
-
-
-2) Include an Internet-available URL for Linus to pull from, such as
-
-       Pull from:  http://gkernel.bkbits.net/net-drivers-2.5
-
-
-
-3) Include a summary and "diffstat -p1" of each changeset that will be
-downloaded, when Linus issues a "bk pull".  The author auto-generates
-these summaries using "bk changes -L <parent>", to obtain a listing
-of all the pending-to-send changesets, and their commit messages.
-
-It is important to show Linus what he will be downloading when he issues
-a "bk pull", to reduce the time required to sift the changes once they
-are downloaded to Linus's local machine.
-
-IMPORTANT NOTE:  One of the features of BK is that your repository does
-not have to be up to date, in order for Linus to receive your changes.
-It is considered a courtesy to keep your repository fairly recent, to
-lessen any potential merge work Linus may need to do.
-
-
-4) Split up your changes.  Each maintainer<->Linus situation is likely
-to be slightly different here, so take this just as general advice.  The
-author splits up changes according to "themes" when merging with Linus.
-Simultaneous pushes from local development go to special trees which
-exist solely to house changes "queued" for Linus.  Example of the trees:
-
-       net-drivers-2.5 -- on-going net driver maintenance
-       vm-2.5 -- VM-related changes
-       fs-2.5 -- filesystem-related changes
-
-Linus then has much more freedom for pulling changes.  He could (for
-example) issue a "bk pull" on vm-2.5 and fs-2.5 trees, to merge their
-changes, but hold off net-drivers-2.5 because of a change that needs
-more discussion.
-
-Other maintainers may find that a single linus-pull-from tree is
-adequate for passing BK changesets to him.
-
-
-
-Frequently Answered Questions
------------------------------
-1) How do I change the e-mail address shown in the changelog?
-A. When you run "bk citool" or "bk commit", set environment
-   variables BK_USER and BK_HOST to the desired username
-   and host/domain name.
-
-
-2) How do I use tags / get a diff between two kernel versions?
-A. Pass the tags Linus uses to 'bk export'.
-
-ChangeSets are in a forward-progressing order, so it's pretty easy
-to get a snapshot starting and ending at any two points in time.
-Linus puts tags on each release and pre-release, so you could use
-these two examples:
-
-    bk export -tpatch -hdu -rv2.5.4,v2.5.5 | less
-        # creates patch-2.5.5 essentially
-    bk export -tpatch -du -rv2.5.5-pre1,v2.5.5 | less
-        # changes from pre1 to final
-
-A tag is just an alias for a specific changeset... and since changesets
-are ordered, a tag is thus a marker for a specific point in time (or
-specific state of the tree).
-
-
-3) Is there an easy way to generate One Big Patch versus mainline,
-   for my long-lived kernel branch?
-A. Yes.  This requires BK 3.x, though.
-
-       bk export -tpatch -r`bk repogca bk://linux.bkbits.net/linux-2.5`,+
-
diff --git a/Documentation/BK-usage/bk-make-sum b/Documentation/BK-usage/bk-make-sum
deleted file mode 100755 (executable)
index 58ca46a..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh -e
-# DIR=$HOME/BK/axp-2.5
-# cd $DIR
-
-LINUS_REPO=$1
-DIRBASE=`basename $PWD`
-
-{
-cat <<EOT
-Please do a
-
-       bk pull bk://gkernel.bkbits.net/$DIRBASE
-
-This will update the following files:
-
-EOT
-
-bk export -tpatch -hdu -r`bk repogca $LINUS_REPO`,+ | diffstat -p1 2>/dev/null
-
-cat <<EOT
-
-through these ChangeSets:
-
-EOT
-
-bk changes -L -d'$unless(:MERGE:){ChangeSet|:CSETREV:\n}' $LINUS_REPO |
-bk -R prs -h -d'$unless(:MERGE:){<:P:@:HOST:> (:D: :I:)\n$each(:C:){   (:C:)\n}\n}' -
-
-} > /tmp/linus.txt
-
-cat <<EOT
-Mail text in /tmp/linus.txt; please check and send using your favourite
-mailer.
-EOT
diff --git a/Documentation/BK-usage/bksend b/Documentation/BK-usage/bksend
deleted file mode 100755 (executable)
index 836ca94..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-# A script to format BK changeset output in a manner that is easy to read.
-# Andreas Dilger <adilger@turbolabs.com>  13/02/2002
-#
-# Add diffstat output after Changelog <adilger@turbolabs.com>   21/02/2002
-
-PROG=bksend
-
-usage() {
-       echo "usage: $PROG -r<rev>"
-       echo -e "\twhere <rev> is of the form '1.23', '1.23..', '1.23..1.27',"
-       echo -e "\tor '+' to indicate the most recent revision"
-
-       exit 1
-}
-
-case $1 in
--r) REV=$2; shift ;;
--r*) REV=`echo $1 | sed 's/^-r//'` ;;
-*) echo "$PROG: no revision given, you probably don't want that";;
-esac
-
-[ -z "$REV" ] && usage
-
-echo "You can import this changeset into BK by piping this whole message to:"
-echo "'| bk receive [path to repository]' or apply the patch as usual."
-
-SEP="\n===================================================================\n\n"
-echo -e $SEP
-env PAGER=/bin/cat bk changes -r$REV
-echo
-bk export -tpatch -du -h -r$REV | diffstat
-echo; echo
-bk export -tpatch -du -h -r$REV
-echo -e $SEP
-bk send -wgzip_uu -r$REV -
diff --git a/Documentation/BK-usage/bz64wrap b/Documentation/BK-usage/bz64wrap
deleted file mode 100755 (executable)
index be78087..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-
-# bz64wrap - the sending side of a bzip2 | base64 stream
-# Andreas Dilger <adilger@clusterfs.com>   Jan 2002
-
-
-PATH=$PATH:/usr/bin:/usr/local/bin:/usr/freeware/bin
-
-# A program to generate base64 encoding on stdout
-BASE64_ENCODE="uuencode -m /dev/stdout"
-BASE64_BEGIN=
-BASE64_END=
-
-BZIP=NO
-BASE64=NO
-
-# Test if we have the bzip program installed
-bzip2 -c /dev/null > /dev/null 2>&1 && BZIP=YES
-
-# Test if uuencode can handle the -m (MIME) encoding option
-$BASE64_ENCODE < /dev/null > /dev/null 2>&1 && BASE64=YES
-
-if [ $BASE64 = NO ]; then
-       BASE64_ENCODE=mimencode
-       BASE64_BEGIN="begin-base64 644 -"
-       BASE64_END="===="
-
-       $BASE64_ENCODE < /dev/null > /dev/null 2>&1 && BASE64=YES
-fi
-
-if [ $BZIP = NO -o $BASE64 = NO ]; then
-       echo "$0: can't use bz64 encoding: bzip2=$BZIP, $BASE64_ENCODE=$BASE64"
-       exit 1
-fi
-
-# Sadly, mimencode does not appear to have good "begin" and "end" markers
-# like uuencode does, and it is picky about getting the right start/end of
-# the base64 stream, so we handle this internally.
-echo "$BASE64_BEGIN"
-bzip2 -9 | $BASE64_ENCODE
-echo "$BASE64_END"
diff --git a/Documentation/BK-usage/cpcset b/Documentation/BK-usage/cpcset
deleted file mode 100755 (executable)
index b8faca9..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-#
-# Purpose: Copy changeset patch and description from one
-#         repository to another, unrelated one.
-#
-# usage:  cpcset [revision] [from-repository] [to-repository]
-#
-
-REV=$1
-FROM=$2
-TO=$3
-TMPF=/tmp/cpcset.$$
-
-rm -f $TMPF*
-
-CWD_SAVE=`pwd`
-cd $FROM
-bk changes -r$REV                      |       \
-       grep -v '^ChangeSet'            |       \
-       sed -e 's/^  //g' > $TMPF.log
-
-USERHOST=`bk changes -r$REV | grep '^ChangeSet' | awk '{print $4}'`
-export BK_USER=`echo $USERHOST | awk '-F@' '{print $1}'`
-export BK_HOST=`echo $USERHOST | awk '-F@' '{print $2}'`
-
-bk export -tpatch -hdu -r$REV > $TMPF.patch && \
-cd $CWD_SAVE && \
-cd $TO && \
-bk import -tpatch -CFR -y"`cat $TMPF.log`" $TMPF.patch . && \
-bk commit -y"`cat $TMPF.log`"
-
-rm -f $TMPF*
-
-echo changeset $REV copied.
-echo ""
-
diff --git a/Documentation/BK-usage/cset-to-linus b/Documentation/BK-usage/cset-to-linus
deleted file mode 100755 (executable)
index d28a96f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-
-my ($lhs, $rev, $tmp, $rhs, $s);
-my @cset_text = ();
-my @pipe_text = ();
-my $have_cset = 0;
-
-while (<>) {
-       next if /^---/;
-
-       if (($lhs, $tmp, $rhs) = (/^(ChangeSet\@)([^,]+)(, .*)$/)) {
-               &cset_rev if ($have_cset);
-
-               $rev = $tmp;
-               $have_cset = 1;
-
-               push(@cset_text, $_);
-       }
-
-       elsif ($have_cset) {
-               push(@cset_text, $_);
-       }
-}
-&cset_rev if ($have_cset);
-exit(0);
-
-
-sub cset_rev {
-       my $empty_cset = 0;
-
-       open PIPE, "bk export -tpatch -hdu -r $rev | diffstat -p1 2>/dev/null |" or die;
-       while ($s = <PIPE>) {
-               $empty_cset = 1 if ($s =~ /0 files changed/);
-               push(@pipe_text, $s);
-       }
-       close(PIPE);
-
-       if (! $empty_cset) {
-               print @cset_text;
-               print @pipe_text;
-               print "\n\n";
-       }
-
-       @pipe_text = ();
-       @cset_text = ();
-}
-
diff --git a/Documentation/BK-usage/csets-to-patches b/Documentation/BK-usage/csets-to-patches
deleted file mode 100755 (executable)
index e2b81c3..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-
-my ($lhs, $rev, $tmp, $rhs, $s);
-my @cset_text = ();
-my @pipe_text = ();
-my $have_cset = 0;
-
-while (<>) {
-       next if /^---/;
-
-       if (($lhs, $tmp, $rhs) = (/^(ChangeSet\@)([^,]+)(, .*)$/)) {
-               &cset_rev if ($have_cset);
-
-               $rev = $tmp;
-               $have_cset = 1;
-
-               push(@cset_text, $_);
-       }
-
-       elsif ($have_cset) {
-               push(@cset_text, $_);
-       }
-}
-&cset_rev if ($have_cset);
-exit(0);
-
-
-sub cset_rev {
-       my $empty_cset = 0;
-
-       system("bk export -tpatch -du -r $rev > /tmp/rev-$rev.patch");
-
-       if (! $empty_cset) {
-               print @cset_text;
-               print @pipe_text;
-               print "\n\n";
-       }
-
-       @pipe_text = ();
-       @cset_text = ();
-}
-
diff --git a/Documentation/BK-usage/gcapatch b/Documentation/BK-usage/gcapatch
deleted file mode 100755 (executable)
index aaeb17d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-#
-# Purpose: Generate GNU diff of local changes versus canonical top-of-tree
-#
-# Usage: gcapatch > foo.patch
-#
-
-bk export -tpatch -hdu -r`bk repogca bk://linux.bkbits.net/linux-2.5`,+
diff --git a/Documentation/BK-usage/unbz64wrap b/Documentation/BK-usage/unbz64wrap
deleted file mode 100755 (executable)
index 4fc3e73..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-# unbz64wrap - the receiving side of a bzip2 | base64 stream
-# Andreas Dilger <adilger@clusterfs.com>   Jan 2002
-
-# Sadly, mimencode does not appear to have good "begin" and "end" markers
-# like uuencode does, and it is picky about getting the right start/end of
-# the base64 stream, so we handle this explicitly here.
-
-PATH=$PATH:/usr/bin:/usr/local/bin:/usr/freeware/bin
-
-if mimencode -u < /dev/null > /dev/null 2>&1 ; then
-       SHOW=
-       while read LINE; do
-               case $LINE in
-               begin-base64*) SHOW=YES ;;
-               ====) SHOW= ;;
-               *) [ "$SHOW" ] && echo "$LINE" ;;
-               esac
-       done | mimencode -u | bunzip2
-       exit $?
-else
-       cat - | uudecode -o /dev/stdout | bunzip2
-       exit $?
-fi
index cf2fce7707da202e7f408f40929dde7255cf742e..6df1dfd18b651fce1224fe0e127cf7e777981d34 100644 (file)
@@ -14,7 +14,7 @@
   </authorgroup>
 
   <copyright>
-   <year>2003</year>
+   <year>2003-2005</year>
    <holder>Jeff Garzik</holder>
   </copyright>
 
 
 <toc></toc>
 
-  <chapter id="libataThanks">
-     <title>Thanks</title>
+  <chapter id="libataIntroduction">
+     <title>Introduction</title>
   <para>
-  The bulk of the ATA knowledge comes thanks to long conversations with
-  Andre Hedrick (www.linux-ide.org).
+  libATA is a library used inside the Linux kernel to support ATA host
+  controllers and devices.  libATA provides an ATA driver API, class
+  transports for ATA and ATAPI devices, and SCSI&lt;-&gt;ATA translation
+  for ATA devices according to the T10 SAT specification.
   </para>
   <para>
-  Thanks to Alan Cox for pointing out similarities 
-  between SATA and SCSI, and in general for motivation to hack on
-  libata.
-  </para>
-  <para>
-  libata's device detection
-  method, ata_pio_devchk, and in general all the early probing was
-  based on extensive study of Hale Landis's probe/reset code in his
-  ATADRVR driver (www.ata-atapi.com).
+  This Guide documents the libATA driver API, library functions, library
+  internals, and a couple sample ATA low-level drivers.
   </para>
   </chapter>
 
   <chapter id="libataDriverApi">
      <title>libata Driver API</title>
+     <para>
+     struct ata_port_operations is defined for every low-level libata
+     hardware driver, and it controls how the low-level driver
+     interfaces with the ATA and SCSI layers.
+     </para>
+     <para>
+     FIS-based drivers will hook into the system with ->qc_prep() and
+     ->qc_issue() high-level hooks.  Hardware which behaves in a manner
+     similar to PCI IDE hardware may utilize several generic helpers,
+     defining at a bare minimum the bus I/O addresses of the ATA shadow
+     register blocks.
+     </para>
      <sect1>
         <title>struct ata_port_operations</title>
 
+       <sect2><title>Disable ATA port</title>
        <programlisting>
 void (*port_disable) (struct ata_port *);
        </programlisting>
@@ -78,6 +86,9 @@ void (*port_disable) (struct ata_port *);
        unplug).
        </para>
 
+       </sect2>
+
+       <sect2><title>Post-IDENTIFY device configuration</title>
        <programlisting>
 void (*dev_config) (struct ata_port *, struct ata_device *);
        </programlisting>
@@ -88,6 +99,9 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
        issue of SET FEATURES - XFER MODE, and prior to operation.
        </para>
 
+       </sect2>
+
+       <sect2><title>Set PIO/DMA mode</title>
        <programlisting>
 void (*set_piomode) (struct ata_port *, struct ata_device *);
 void (*set_dmamode) (struct ata_port *, struct ata_device *);
@@ -108,6 +122,9 @@ void (*post_set_mode) (struct ata_port *ap);
        ->set_dma_mode() is only called if DMA is possible.
        </para>
 
+       </sect2>
+
+       <sect2><title>Taskfile read/write</title>
        <programlisting>
 void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
 void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
@@ -120,6 +137,9 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
        taskfile register values.
        </para>
 
+       </sect2>
+
+       <sect2><title>ATA command execute</title>
        <programlisting>
 void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
        </programlisting>
@@ -129,17 +149,37 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
        ->tf_load(), to be initiated in hardware.
        </para>
 
+       </sect2>
+
+       <sect2><title>Per-cmd ATAPI DMA capabilities filter</title>
+       <programlisting>
+int (*check_atapi_dma) (struct ata_queued_cmd *qc);
+       </programlisting>
+
+       <para>
+Allow low-level driver to filter ATA PACKET commands, returning a status
+indicating whether or not it is OK to use DMA for the supplied PACKET
+command.
+       </para>
+
+       </sect2>
+
+       <sect2><title>Read specific ATA shadow registers</title>
        <programlisting>
 u8   (*check_status)(struct ata_port *ap);
-void (*dev_select)(struct ata_port *ap, unsigned int device);
+u8   (*check_altstatus)(struct ata_port *ap);
+u8   (*check_err)(struct ata_port *ap);
        </programlisting>
 
        <para>
-       Reads the Status ATA shadow register from hardware.  On some
-       hardware, this has the side effect of clearing the interrupt
-       condition.
+       Reads the Status/AltStatus/Error ATA shadow register from
+       hardware.  On some hardware, reading the Status register has
+       the side effect of clearing the interrupt condition.
        </para>
 
+       </sect2>
+
+       <sect2><title>Select ATA device on bus</title>
        <programlisting>
 void (*dev_select)(struct ata_port *ap, unsigned int device);
        </programlisting>
@@ -147,9 +187,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
        <para>
        Issues the low-level hardware command(s) that causes one of N
        hardware devices to be considered 'selected' (active and
-       available for use) on the ATA bus.
+       available for use) on the ATA bus.  This generally has no
+meaning on FIS-based devices.
        </para>
 
+       </sect2>
+
+       <sect2><title>Reset ATA bus</title>
        <programlisting>
 void (*phy_reset) (struct ata_port *ap);
        </programlisting>
@@ -162,17 +206,31 @@ void (*phy_reset) (struct ata_port *ap);
        functions ata_bus_reset() or sata_phy_reset() for this hook.
        </para>
 
+       </sect2>
+
+       <sect2><title>Control PCI IDE BMDMA engine</title>
        <programlisting>
 void (*bmdma_setup) (struct ata_queued_cmd *qc);
 void (*bmdma_start) (struct ata_queued_cmd *qc);
+void (*bmdma_stop) (struct ata_port *ap);
+u8   (*bmdma_status) (struct ata_port *ap);
        </programlisting>
 
        <para>
-       When setting up an IDE BMDMA transaction, these hooks arm
-       (->bmdma_setup) and fire (->bmdma_start) the hardware's DMA
-       engine.
+When setting up an IDE BMDMA transaction, these hooks arm
+(->bmdma_setup), fire (->bmdma_start), and halt (->bmdma_stop)
+the hardware's DMA engine.  ->bmdma_status is used to read the standard
+PCI IDE DMA Status register.
        </para>
 
+       <para>
+These hooks are typically either no-ops, or simply not implemented, in
+FIS-based drivers.
+       </para>
+
+       </sect2>
+
+       <sect2><title>High-level taskfile hooks</title>
        <programlisting>
 void (*qc_prep) (struct ata_queued_cmd *qc);
 int (*qc_issue) (struct ata_queued_cmd *qc);
@@ -190,20 +248,26 @@ int (*qc_issue) (struct ata_queued_cmd *qc);
        ->qc_issue is used to make a command active, once the hardware
        and S/G tables have been prepared.  IDE BMDMA drivers use the
        helper function ata_qc_issue_prot() for taskfile protocol-based
-       dispatch.  More advanced drivers roll their own ->qc_issue
-       implementation, using this as the "issue new ATA command to
-       hardware" hook.
+       dispatch.  More advanced drivers implement their own ->qc_issue.
        </para>
 
+       </sect2>
+
+       <sect2><title>Timeout (error) handling</title>
        <programlisting>
 void (*eng_timeout) (struct ata_port *ap);
        </programlisting>
 
        <para>
-       This is a high level error handling function, called from the
-       error handling thread, when a command times out.
+This is a high level error handling function, called from the
+error handling thread, when a command times out.  Most newer
+hardware will implement its own error handling code here.  IDE BMDMA
+drivers may use the helper function ata_eng_timeout().
        </para>
 
+       </sect2>
+
+       <sect2><title>Hardware interrupt handling</title>
        <programlisting>
 irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
 void (*irq_clear) (struct ata_port *);
@@ -216,6 +280,9 @@ void (*irq_clear) (struct ata_port *);
        is quiet.
        </para>
 
+       </sect2>
+
+       <sect2><title>SATA phy read/write</title>
        <programlisting>
 u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
 void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
@@ -227,6 +294,9 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
        if ->phy_reset hook called the sata_phy_reset() helper function.
        </para>
 
+       </sect2>
+
+       <sect2><title>Init and shutdown</title>
        <programlisting>
 int (*port_start) (struct ata_port *ap);
 void (*port_stop) (struct ata_port *ap);
@@ -240,15 +310,17 @@ void (*host_stop) (struct ata_host_set *host_set);
        tasks.  
        </para>
        <para>
-       ->host_stop() is called when the rmmod or hot unplug process
-       begins.  The hook must stop all hardware interrupts, DMA
-       engines, etc.
-       </para>
-       <para>
        ->port_stop() is called after ->host_stop().  It's sole function
        is to release DMA/memory resources, now that they are no longer
        actively being used.
        </para>
+       <para>
+       ->host_stop() is called after all ->port_stop() calls
+have completed.  The hook must finalize hardware shutdown, release DMA
+and other resources, etc.
+       </para>
+
+       </sect2>
 
      </sect1>
   </chapter>
@@ -279,4 +351,24 @@ void (*host_stop) (struct ata_host_set *host_set);
 !Idrivers/scsi/sata_sil.c
   </chapter>
 
+  <chapter id="libataThanks">
+     <title>Thanks</title>
+  <para>
+  The bulk of the ATA knowledge comes thanks to long conversations with
+  Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA
+  and SCSI specifications.
+  </para>
+  <para>
+  Thanks to Alan Cox for pointing out similarities 
+  between SATA and SCSI, and in general for motivation to hack on
+  libata.
+  </para>
+  <para>
+  libata's device detection
+  method, ata_pio_devchk, and in general all the early probing was
+  based on extensive study of Hale Landis's probe/reset code in his
+  ATADRVR driver (www.ata-atapi.com).
+  </para>
+  </chapter>
+
 </book>
index 9838d32b2fe70ac6cff1f1b6cd03785af00cab3b..4d35562b1cf976d7f63f7f555440686e44ae5db4 100644 (file)
@@ -271,7 +271,7 @@ patch, which certifies that you wrote it or otherwise have the right to
 pass it on as a open-source patch.  The rules are pretty simple: if you
 can certify the below:
 
-        Developer's Certificate of Origin 1.0
+        Developer's Certificate of Origin 1.1
 
         By making a contribution to this project, I certify that:
 
@@ -291,6 +291,12 @@ can certify the below:
             person who certified (a), (b) or (c) and I have not modified
             it.
 
+       (d) I understand and agree that this project and the contribution
+           are public and that a record of the contribution (including all
+           personal information I submit with it, including my sign-off) is
+           maintained indefinitely and may be redistributed consistent with
+           this project or the open source license(s) involved.
+
 then you just add a line saying
 
        Signed-off-by: Random J Developer <random@developer.org>
index 43e50108d0e21c56ec5bcd873916c9f547a765c8..3a4dbe4663c9556f15fd062cfafcd1f6e3dddd1d 100644 (file)
@@ -4,6 +4,16 @@ The EtherDrive (R) HOWTO for users of 2.6 kernels is found at ...
 
   It has many tips and hints!
 
+The aoetools are userland programs that are designed to work with this
+driver.  The aoetools are on sourceforge.
+
+  http://aoetools.sourceforge.net/
+
+The scripts in this Documentation/aoe directory are intended to
+document the use of the driver and are not necessary if you install
+the aoetools.
+
+
 CREATING DEVICE NODES
 
   Users of udev should find the block device nodes created
@@ -35,14 +45,15 @@ USING DEVICE NODES
 
   "echo eth2 eth4 > /dev/etherd/interfaces" tells the aoe driver to
   limit ATA over Ethernet traffic to eth2 and eth4.  AoE traffic from
-  untrusted networks should be ignored as a matter of security.
+  untrusted networks should be ignored as a matter of security.  See
+  also the aoe_iflist driver option described below.
 
   "echo > /dev/etherd/discover" tells the driver to find out what AoE
   devices are available.
 
   These character devices may disappear and be replaced by sysfs
-  counterparts, so distribution maintainers are encouraged to create
-  scripts that use these devices.
+  counterparts.  Using the commands in aoetools insulates users from
+  these implementation details.
 
   The block devices are named like this:
 
@@ -66,7 +77,8 @@ USING SYSFS
   through which we are communicating with the remote AoE device.
 
   There is a script in this directory that formats this information
-  in a convenient way.
+  in a convenient way.  Users with aoetools can use the aoe-stat
+  command.
 
   root@makki root# sh Documentation/aoe/status.sh 
      e10.0            eth3              up
@@ -89,3 +101,23 @@ USING SYSFS
       e4.7            eth1              up
       e4.8            eth1              up
       e4.9            eth1              up
+
+  Use /sys/module/aoe/parameters/aoe_iflist (or better, the driver
+  option discussed below) instead of /dev/etherd/interfaces to limit
+  AoE traffic to the network interfaces in the given
+  whitespace-separated list.  Unlike the old character device, the
+  sysfs entry can be read from as well as written to.
+
+  It's helpful to trigger discovery after setting the list of allowed
+  interfaces.  The aoetools package provides an aoe-discover script
+  for this purpose.  You can also directly use the
+  /dev/etherd/discover special file described above.
+
+DRIVER OPTIONS
+
+  There is a boot option for the built-in aoe driver and a
+  corresponding module parameter, aoe_iflist.  Without this option,
+  all network interfaces may be used for ATA over Ethernet.  Here is a
+  usage example for the module parameter.
+
+    modprobe aoe_iflist="eth1 eth3"
index 6628116d4a9f7b4da22a8991cf5426c6e92b8d22..751f3be514b831296b038fd343443c15d0aa5b32 100644 (file)
@@ -14,10 +14,6 @@ test ! -d "$sysd/block" && {
        echo "$me Error: sysfs is not mounted" 1>&2
        exit 1
 }
-test -z "`lsmod | grep '^aoe'`" && {
-       echo  "$me Error: aoe module is not loaded" 1>&2
-       exit 1
-}
 
 for d in `ls -d $sysd/block/etherd* 2>/dev/null | grep -v p` end; do
        # maybe ls comes up empty, so we use "end"
diff --git a/Documentation/cpu-freq/cpufreq-stats.txt b/Documentation/cpu-freq/cpufreq-stats.txt
new file mode 100644 (file)
index 0000000..e2d1e76
--- /dev/null
@@ -0,0 +1,128 @@
+
+     CPU frequency and voltage scaling statictics in the Linux(TM) kernel
+
+
+             L i n u x    c p u f r e q - s t a t s   d r i v e r
+
+                       - information for users -
+
+
+             Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+
+Contents
+1. Introduction
+2. Statistics Provided (with example)
+3. Configuring cpufreq-stats
+
+
+1. Introduction
+
+cpufreq-stats is a driver that provices CPU frequency statistics for each CPU.
+This statistics is provided in /sysfs as a bunch of read_only interfaces. This
+interface (when configured) will appear in a seperate directory under cpufreq
+in /sysfs (<sysfs root>/devices/system/cpu/cpuX/cpufreq/stats/) for each CPU.
+Various statistics will form read_only files under this directory.
+
+This driver is designed to be independent of any particular cpufreq_driver
+that may be running on your CPU. So, it will work with any cpufreq_driver.
+
+
+2. Statistics Provided (with example)
+
+cpufreq stats provides following statistics (explained in detail below).
+-  time_in_state
+-  total_trans
+-  trans_table
+
+All the statistics will be from the time the stats driver has been inserted 
+to the time when a read of a particular statistic is done. Obviously, stats 
+driver will not have any information about the the frequcny transitions before
+the stats driver insertion.
+
+--------------------------------------------------------------------------------
+<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # ls -l
+total 0
+drwxr-xr-x  2 root root    0 May 14 16:06 .
+drwxr-xr-x  3 root root    0 May 14 15:58 ..
+-r--r--r--  1 root root 4096 May 14 16:06 time_in_state
+-r--r--r--  1 root root 4096 May 14 16:06 total_trans
+-r--r--r--  1 root root 4096 May 14 16:06 trans_table
+--------------------------------------------------------------------------------
+
+-  time_in_state
+This gives the amount of time spent in each of the frequencies supported by
+this CPU. The cat output will have "<frequency> <time>" pair in each line, which
+will mean this CPU spent <time> usertime units of time at <frequency>. Output
+will have one line for each of the supported freuencies. usertime units here 
+is 10mS (similar to other time exported in /proc).
+
+--------------------------------------------------------------------------------
+<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat time_in_state 
+3600000 2089
+3400000 136
+3200000 34
+3000000 67
+2800000 172488
+--------------------------------------------------------------------------------
+
+
+-  total_trans
+This gives the total number of frequency transitions on this CPU. The cat 
+output will have a single count which is the total number of frequency
+transitions.
+
+--------------------------------------------------------------------------------
+<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat total_trans
+20
+--------------------------------------------------------------------------------
+
+-  trans_table
+This will give a fine grained information about all the CPU frequency
+transitions. The cat output here is a two dimensional matrix, where an entry
+<i,j> (row i, column j) represents the count of number of transitions from 
+Freq_i to Freq_j. Freq_i is in descending order with increasing rows and 
+Freq_j is in descending order with increasing columns. The output here also 
+contains the actual freq values for each row and column for better readability.
+
+--------------------------------------------------------------------------------
+<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat trans_table
+   From  :    To
+         :   3600000   3400000   3200000   3000000   2800000 
+  3600000:         0         5         0         0         0 
+  3400000:         4         0         2         0         0 
+  3200000:         0         1         0         2         0 
+  3000000:         0         0         1         0         3 
+  2800000:         0         0         0         2         0 
+--------------------------------------------------------------------------------
+
+
+3. Configuring cpufreq-stats
+
+To configure cpufreq-stats in your kernel
+Config Main Menu
+       Power management options (ACPI, APM)  --->
+               CPU Frequency scaling  --->
+                       [*] CPU Frequency scaling
+                       <*>   CPU frequency translation statistics 
+                       [*]     CPU frequency translation statistics details
+
+
+"CPU Frequency scaling" (CONFIG_CPU_FREQ) should be enabled to configure
+cpufreq-stats.
+
+"CPU frequency translation statistics" (CONFIG_CPU_FREQ_STAT) provides the
+basic statistics which includes time_in_state and total_trans.
+
+"CPU frequency translation statistics details" (CONFIG_CPU_FREQ_STAT_DETAILS)
+provides fine grained cpufreq stats by trans_table. The reason for having a
+seperate config option for trans_table is:
+- trans_table goes against the traditional /sysfs rule of one value per
+  interface. It provides a whole bunch of value in a 2 dimensional matrix
+  form.
+
+Once these two options are enabled and your CPU supports cpufrequency, you
+will be able to see the CPU frequency statistics in /sysfs.
+
+
+
+
index 1ad26d2c20ae61e0fabafefdee24ef5bb35b50e0..2f8f24eaefd9ac746f8a1e98b6e2c99abcc23b58 100644 (file)
@@ -252,8 +252,7 @@ in a tasks processor placement.
 There is an exception to the above.  If hotplug funtionality is used
 to remove all the CPUs that are currently assigned to a cpuset,
 then the kernel will automatically update the cpus_allowed of all
-tasks attached to CPUs in that cpuset with the online CPUs of the
-nearest parent cpuset that still has some CPUs online.  When memory
+tasks attached to CPUs in that cpuset to allow all CPUs.  When memory
 hotplug functionality for removing Memory Nodes is available, a
 similar exception is expected to apply there as well.  In general,
 the kernel prefers to violate cpuset placement, over starving a task
index 7c2496426ab9bd319065392a00d3fdb45270c6c5..9a33bb94f74fef59de103db9cc92adeaeb030680 100644 (file)
@@ -27,6 +27,7 @@
 *.so
 *.tex
 *.ver
+*.xml
 *_MODULES
 *_vga16.c
 *cscope*
@@ -110,6 +111,7 @@ mkdep
 mktables
 modpost
 modversions.h*
+offsets.h
 oui.c*
 parse.c*
 parse.h*
@@ -134,4 +136,5 @@ vmlinux-*
 vmlinux.lds
 vsyscall.lds
 wanxlfw.inc
+uImage
 zImage
diff --git a/Documentation/dvb/README.flexcop b/Documentation/dvb/README.flexcop
new file mode 100644 (file)
index 0000000..a50c70f
--- /dev/null
@@ -0,0 +1,205 @@
+This README escorted the skystar2-driver rewriting procedure. It describes the
+state of the new flexcop-driver set and some internals are written down here
+too.
+
+This document hopefully describes things about the flexcop and its
+device-offsprings. Goal was to write an easy-to-write and easy-to-read set of
+drivers based on the skystar2.c and other information.
+
+Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been
+touched and rewritten.
+
+History & News
+==============
+  2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana)
+
+
+
+
+General coding processing
+=========================
+
+We should proceed as follows (as long as no one complains):
+
+0) Think before start writing code!
+
+1) rewriting the skystar2.c with the help of the flexcop register descriptions
+and splitting up the files to a pci-bus-part and a flexcop-part.
+The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the
+device-specific part and b2c2-flexcop.ko for the common flexcop-functions.
+
+2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c
+and other pci drivers)
+
+3) make some beautification (see 'Improvements when rewriting (refactoring) is
+done')
+
+4) Testing the new driver and maybe substitute the skystar2.c with it, to reach
+a wider tester audience.
+
+5) creating an usb-bus-part using the already written flexcop code for the pci
+card.
+
+Idea: create a kernel-object for the flexcop and export all important
+functions. This option saves kernel-memory, but maybe a lot of functions have
+to be exported to kernel namespace.
+
+
+Current situation
+=================
+
+0) Done :)
+1) Done (some minor issues left)
+2) Done
+3) Not ready yet, more information is necessary
+4) next to be done (see the table below)
+5) USB driver is working (yes, there are some minor issues)
+
+What seems to be ready?
+-----------------------
+
+1) Rewriting
+1a) i2c is cut off from the flexcop-pci.c and seems to work
+1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c
+1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c
+1e) eeprom (reading MAC address)
+1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me))
+1f) misc. register accesses for reading parameters (e.g. resetting, revision)
+1g) pid/mac filter (flexcop-hw-filter.c)
+1i) dvb-stuff initialization in flexcop.c (done)
+1h) dma stuff (now just using the size-irq, instead of all-together, to be done)
+1j) remove flexcop initialization from flexcop-pci.c completely (done)
+1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO')
+1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from
+non-static where possible, moved code to proper places)
+
+2) Search for errors in the leftover of flexcop-pci.c (partially done)
+5a) add MAC address reading
+5c) feeding of ISOC data to the software demux (format of the isochronous data
+and speed optimization, no real error) (thanks to Vadim Catana)
+
+What to do in the near future?
+--------------------------------------
+(no special order here)
+
+5) USB driver
+5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting)
+
+Testing changes
+---------------
+
+O             = item is working
+P             = item is partially working
+X             = item is not working
+N             = item does not apply here
+<empty field> = item need to be examined
+
+       | PCI                               | USB
+item   | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312
+-------+-------+---------+---------+-------+-------+---------+---------+-------
+1a)    | O     |         |         |       | N     | N       | N       | N
+1b)    | O     |         |         |       |       |         | O       |
+1c)    | N     | N       |         |       | N     | N       | O       |
+1d)    |                 O                 |                 O
+1e)    |                 O                 |                 O
+1f)    |                                   P
+1g)    |                                   O
+1h)    |                 P                 |
+1i)    |                 O                 |                 N
+1j)    |                 O                 |                 N
+1l)    |                 O                 |                 N
+2)     |                 O                 |                 N
+5a)    |                 N                 |                 O
+5b)*   |                 N                 |
+5c)    |                 N                 |                 O
+
+* - not done yet
+
+Known bugs and problems and TODO
+--------------------------------
+
+1g/h/l) when pid filtering is enabled on the pci card
+
+DMA usage currently:
+  The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first
+  address and triggers an IRQ when it's full and starts writing to the second
+  address. When the second address is full, the IRQ is triggered again, and
+  the flexcop writes to first address again, and so on.
+  The buffersize of each address is currently 640*188 bytes.
+
+  Problem is, when using hw-pid-filtering and doing some low-bandwidth
+  operation (like scanning) the buffers won't be filled enough to trigger
+  the IRQ. That's why:
+
+  When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ
+  is triggered.  Is the current write address of DMA1 different to the one
+  during the last IRQ, then the data is passed to the demuxer.
+
+  There is an additional DMA-IRQ-method: packet count IRQ. This isn't
+  implemented correctly yet.
+
+  The solution is to disable HW PID filtering, but I don't know how the DVB
+  API software demux behaves on slow systems with 45MBit/s TS.
+
+Solved bugs :)
+--------------
+1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't
+working)
+SOLUTION: also index 0 was affected, because net_translation is done for
+these indexes by default
+
+5b) isochronous transfer does only work in the first attempt (for the Sky2PC
+USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really
+woke up again (don't know if this need fixes, see
+flexcop-fe-tuner.c:flexcop_sleep)
+
+NEWS: when the driver is loaded and unloaded and loaded again (w/o doing
+anything in the while the driver is loaded the first time), no transfers take
+place anymore.
+
+Improvements when rewriting (refactoring) is done
+=================================================
+
+- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control
+  (enable sleeping for other demods than dvb-s)
+- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA)
+
+Debugging
+---------
+- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it
+  with this flexcop, this is important, because i2c is now using the
+  flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for
+  that, please tell us so).
+
+Everything which is identical in the following table, can be put into a common
+flexcop-module.
+
+                  PCI                  USB
+-------------------------------------------------------------------------------
+Different:
+Register access:  accessing IO memory  USB control message
+I2C bus:          I2C bus of the FC    USB control message
+Data transfer:    DMA                  isochronous transfer
+EEPROM transfer:  through i2c bus      not clear yet
+
+Identical:
+Streaming:                 accessing registers
+PID Filtering:             accessing registers
+Sram destinations:         accessing registers
+Tuner/Demod:                     I2C bus
+DVB-stuff:            can be written for common use
+
+Acknowledgements (just for the rewriting part)
+================
+
+Bjarne Steinsbo thought a lot in the first place of the pci part for this code
+sharing idea.
+
+Andreas Oberritter for providing a recent PCI initialization template
+(pluto2.c).
+
+Boleslaw Ciesielski for pointing out a problem with firmware loader.
+
+Vadim Catana for correcting the USB transfer.
+
+comments, critics and ideas to linux-dvb@linuxtv.org.
index e3cacf4f2345e48258317bc23925e66a757a4a53..d64430bf4bb6ec5d681c2f7c30cc71905a72bd67 100644 (file)
@@ -17,74 +17,53 @@ Because of this, you need to enable
 "Device drivers" => "Multimedia devices"
   => "Video For Linux" => "BT848 Video For Linux"
 
+Furthermore you need to enable
+"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
+  => "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
+
 2) Loading Modules
 ==================
 
 In general you need to load the bttv driver, which will handle the gpio and
-i2c communication for us. Next you need the common dvb-bt8xx device driver
-and one frontend driver.
-
-The bttv driver will HANG YOUR SYSTEM IF YOU DO NOT SPECIFY THE CORRECT 
-CARD ID!
-
-(If you don't get your card running and you suspect that the card id you're
-using is wrong, have a look at "bttv-cards.c" for a list of possible card
-ids.)
-
-Pay attention to failures when you load the frontend drivers
-(e.g. dmesg, /var/log/messages).
+i2c communication for us, plus the common dvb-bt8xx device driver.
+The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and
+TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
 
 3a) Nebula / Pinnacle PCTV
 --------------------------
 
-   $ modprobe bttv i2c_hw=1 card=0x68
-   $ modprobe dvb-bt8xx
-   
-For Nebula cards use the "nxt6000" frontend driver:
-   $ modprobe nxt6000
+   $ modprobe bttv (normally bttv is being loaded automatically by kmod)
+   $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading)
 
-For Pinnacle PCTV cards use the "cx24110" frontend driver:
-   $ modprobe cx24110
 
-3b) TwinHan
------------
+3b) TwinHan and Clones
+--------------------------
 
    $ modprobe bttv i2c_hw=1 card=0x71
    $ modprobe dvb-bt8xx
    $ modprobe dst
 
-The value 0x71 will override the PCI type detection for dvb-bt8xx, which 
-is necessary for TwinHan cards.#
+The value 0x71 will override the PCI type detection for dvb-bt8xx,
+which  is necessary for TwinHan cards.
 
-If you're having an older card (blue color circuit) and card=0x71 locks your
-machine, try using 0x68, too. If that does not work, ask on the DVB mailing list.
+If you're having an older card (blue color circuit) and card=0x71 locks
+your machine, try using 0x68, too. If that does not work, ask on the
+mailing list.
 
-The DST module takes a couple of useful parameters, in case the
-dst drivers fails to detect your type of card correctly.
+The DST module takes a couple of useful parameters.
 
-dst_type takes values 0 (satellite), 1 (terrestial TV), 2 (cable).
+verbose takes values 0 to 5. These values control the verbosity level.
 
-dst_type_flags takes bit combined values:
-1 = new tuner type packets. You can use this if your card is detected
-    and you have debug and you continually see the tuner packets not
-    working (make sure not a basic problem like dish alignment etc.)
+debug takes values 0 and 1. You can either disable or enable debugging.
 
-2 = TS 204. If your card tunes OK, but the picture is terrible, seemingly
-    breaking up in one half continually, and crc fails a lot, then
-    this is worth a try (or trying to turn off)
+dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
+0x20 means it has a Conditional Access slot.
 
-4 = has symdiv. Some cards, mostly without new tuner packets, require
-    a symbol division algorithm. Doesn't apply to terrestial TV.
-
-You can also specify a value to have the autodetected values turned off
-(e.g. 0). The autodected values are determined bythe cards 'response
+The autodected values are determined bythe cards 'response
 string' which you can see in your logs e.g.
 
-dst_check_ci: recognize DST-MOT
-
-or 
+dst_get_device_id: Recognise [DSTMCI]
 
-dst_check_ci: unable to recognize DSTXCI or STXCI
 
 --
-Authors: Richard Walker, Jamie Honan, Michael Hunold
+Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham
diff --git a/Documentation/dvb/ci.txt b/Documentation/dvb/ci.txt
new file mode 100644 (file)
index 0000000..62e0701
--- /dev/null
@@ -0,0 +1,219 @@
+* For the user
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+NOTE: This document describes the usage of the high level CI API as
+in accordance to the Linux DVB API. This is a not a documentation for the,
+existing low level CI API.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To utilize the High Level CI capabilities,
+
+(1*) This point is valid only for the Twinhan/clones
+  For the Twinhan/Twinhan clones, the dst_ca module handles the CI
+  hardware handling.This module is loaded automatically if a CI
+  (Common Interface, that holds the CAM (Conditional Access Module)
+  is detected.
+
+(2) one requires a userspace application, ca_zap. This small userland
+  application is in charge of sending the descrambling related information
+  to the CAM.
+
+This application requires the following to function properly as of now.
+
+       (a) Tune to a valid channel, with szap.
+         eg: $ szap -c channels.conf -r "TMC" -x
+
+       (b) a channels.conf containing a valid PMT PID
+
+         eg: TMC:11996:h:0:27500:278:512:650:321
+
+         here 278 is a valid PMT PID. the rest of the values are the
+         same ones that szap uses.
+
+       (c) after running a szap, you have to run ca_zap, for the
+         descrambler to function,
+
+         eg: $ ca_zap patched_channels.conf "TMC"
+
+         The patched means a patch to apply to scan, such that scan can
+         generate a channels.conf_with pmt, which has this PMT PID info
+         (NOTE: szap cannot use this channels.conf with the PMT_PID)
+
+
+       (d) Hopeflly Enjoy your favourite subscribed channel as you do with
+         a FTA card.
+
+(3) Currently ca_zap, and dst_test, both are meant for demonstration
+  purposes only, they can become full fledged applications if necessary.
+
+
+* Cards that fall in this category
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+At present the cards that fall in this category are the Twinhan and it's
+clones, these cards are available as VVMER, Tomato, Hercules, Orange and
+so on.
+
+* CI modules that are supported
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The CI module support is largely dependant upon the firmware on the cards
+Some cards do support almost all of the available CI modules. There is
+nothing much that can be done in order to make additional CI modules
+working with these cards.
+
+Modules that have been tested by this driver at present are
+
+(1) Irdeto 1 and 2 from SCM
+(2) Viaccess from SCM
+(3) Dragoncam
+
+* The High level CI API
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* For the programmer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+With the High Level CI approach any new card with almost any random
+architecture can be implemented with this style, the definitions
+insidethe switch statement can be easily adapted for any card, thereby
+eliminating the need for any additional ioctls.
+
+The disadvantage is that the driver/hardware has to manage the rest. For
+the application programmer it would be as simple as sending/receiving an
+array to/from the CI ioctls as defined in the Linux DVB API. No changes
+have been made in the API to accomodate this feature.
+
+
+* Why the need for another CI interface ?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This is one of the most commonly asked question. Well a nice question.
+Strictly speaking this is not a new interface.
+
+The CI interface is defined in the DVB API in ca.h as
+
+typedef struct ca_slot_info {
+       int num;               /* slot number */
+
+       int type;              /* CA interface this slot supports */
+#define CA_CI            1     /* CI high level interface */
+#define CA_CI_LINK       2     /* CI link layer level interface */
+#define CA_CI_PHYS       4     /* CI physical layer level interface */
+#define CA_DESCR         8     /* built-in descrambler */
+#define CA_SC          128     /* simple smart card interface */
+
+       unsigned int flags;
+#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
+#define CA_CI_MODULE_READY   2
+} ca_slot_info_t;
+
+
+
+This CI interface follows the CI high level interface, which is not
+implemented by most applications. Hence this area is revisited.
+
+This CI interface is quite different in the case that it tries to
+accomodate all other CI based devices, that fall into the other categories
+
+This means that this CI interface handles the EN50221 style tags in the
+Application layer only and no session management is taken care of by the
+application. The driver/hardware will take care of all that.
+
+This interface is purely an EN50221 interface exchanging APDU's. This
+means that no session management, link layer or a transport layer do
+exist in this case in the application to driver communication. It is
+as simple as that. The driver/hardware has to take care of that.
+
+
+With this High Level CI interface, the interface can be defined with the
+regular ioctls.
+
+All these ioctls are also valid for the High level CI interface
+
+#define CA_RESET          _IO('o', 128)
+#define CA_GET_CAP        _IOR('o', 129, ca_caps_t)
+#define CA_GET_SLOT_INFO  _IOR('o', 130, ca_slot_info_t)
+#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
+#define CA_GET_MSG        _IOR('o', 132, ca_msg_t)
+#define CA_SEND_MSG       _IOW('o', 133, ca_msg_t)
+#define CA_SET_DESCR      _IOW('o', 134, ca_descr_t)
+#define CA_SET_PID        _IOW('o', 135, ca_pid_t)
+
+
+On querying the device, the device yields information thus
+
+CA_GET_SLOT_INFO
+----------------------------
+Command = [info]
+APP: Number=[1]
+APP: Type=[1]
+APP: flags=[1]
+APP: CI High level interface
+APP: CA/CI Module Present
+
+CA_GET_CAP
+----------------------------
+Command = [caps]
+APP: Slots=[1]
+APP: Type=[1]
+APP: Descrambler keys=[16]
+APP: Type=[1]
+
+CA_SEND_MSG
+----------------------------
+Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1]
+Found CA descriptor @ program level
+
+(20) ES type=[2] ES pid=[201]  ES length =[0 (0x0)]
+(25) ES type=[4] ES pid=[301]  ES length =[0 (0x0)]
+ca_message length is 25 (0x19) bytes
+EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00]
+
+
+Not all ioctl's are implemented in the driver from the API, the other
+features of the hardware that cannot be implemented by the API are achieved
+using the CA_GET_MSG and CA_SEND_MSG ioctls. An EN50221 style wrapper is
+used to exchange the data to maintain compatibility with other hardware.
+
+
+/* a message to/from a CI-CAM */
+typedef struct ca_msg {
+       unsigned int index;
+       unsigned int type;
+       unsigned int length;
+       unsigned char msg[256];
+} ca_msg_t;
+
+
+The flow of data can be described thus,
+
+
+
+
+
+       App (User)
+       -----
+       parse
+         |
+         |
+         v
+       en50221 APDU (package)
+   --------------------------------------
+   |     |                             | High Level CI driver
+   |     |                             |
+   |     v                             |
+   |   en50221 APDU (unpackage)        |
+   |     |                             |
+   |     |                             |
+   |     v                             |
+   |   sanity checks                   |
+   |     |                             |
+   |     |                             |
+   |     v                             |
+   |   do (H/W dep)                    |
+   --------------------------------------
+         |    Hardware
+         |
+         v
+
+
+
+
+The High Level CI interface uses the EN50221 DVB standard, following a
+standard ensures futureproofness.
index 3ffdcb394299f43b65f50c7df3898281504fd32c..a750f0101d9de7d15f47a13e0cc7240b3299ba1f 100644 (file)
@@ -107,7 +107,7 @@ sub tda10045 {
 sub tda10046 {
     my $sourcefile = "tt_budget_217g.zip";
     my $url = "http://www.technotrend.de/new/217g/$sourcefile";
-    my $hash = "a25b579e37109af60f4a36c37893957c";
+    my $hash = "6a7e1e2f2644b162ff0502367553c72d";
     my $outfile = "dvb-fe-tda10046.fw";
     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
 
@@ -115,7 +115,7 @@ sub tda10046 {
 
     wgetfile($sourcefile, $url);
     unzip($sourcefile, $tmpdir);
-    extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24479, "$tmpdir/fwtmp");
+    extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp");
     verify("$tmpdir/fwtmp", $hash);
     copy("$tmpdir/fwtmp", $outfile);
 
index d3c52dd24a2ae6f5a39d35d788c8831aa52f4b9c..b9eb209318ab7d737ba7e6be2a0587ce9e8a9d25 100644 (file)
@@ -63,3 +63,23 @@ Why: Outside of Linux, the only implementations of anything even
        people, who might be using implementations that I am not aware
        of, to adjust to this upcoming change.
 Who:   Paul E. McKenney <paulmck@us.ibm.com>
+
+---------------------------
+
+What:  IEEE1394 Audio and Music Data Transmission Protocol driver,
+       Connection Management Procedures driver
+When:  November 2005
+Files: drivers/ieee1394/{amdtp,cmp}*
+Why:   These are incomplete, have never worked, and are better implemented
+       in userland via raw1394 (see http://freebob.sourceforge.net/ for
+       example.)
+Who:   Jody McIntyre <scjody@steamballoon.com>
+
+---------------------------
+
+What:  raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
+When:  November 2005
+Why:   Deprecated in favour of the new ioctl-based rawiso interface, which is
+       more efficient.  You should really be using libraw1394 for raw1394
+       access anyway.
+Who:   Jody McIntyre <scjody@steamballoon.com>
index e97d024eae77e5fa9f1ac338074a24baf42680e5..988a62fae11f883b8b2ba14ba95d83490a3fc5a1 100644 (file)
@@ -7,7 +7,6 @@ that support it.  For example, a given bus might look like this:
      |-- 0000:17:00.0
      |   |-- class
      |   |-- config
-     |   |-- detach_state
      |   |-- device
      |   |-- irq
      |   |-- local_cpus
@@ -19,7 +18,7 @@ that support it.  For example, a given bus might look like this:
      |   |-- subsystem_device
      |   |-- subsystem_vendor
      |   `-- vendor
-     `-- detach_state
+     `-- ...
 
 The topmost element describes the PCI domain and bus number.  In this case,
 the domain number is 0000 and the bus number is 17 (both values are in hex).
@@ -31,7 +30,6 @@ files, each with their own function.
        ----               --------
        class              PCI class (ascii, ro)
        config             PCI config space (binary, rw)
-       detach_state       connection status (bool, rw)
        device             PCI device (ascii, ro)
        irq                IRQ number (ascii, ro)
        local_cpus         nearby CPU mask (cpumask, ro)
@@ -85,4 +83,4 @@ useful return codes should be provided.
 
 Legacy resources are protected by the HAVE_PCI_LEGACY define.  Platforms
 wishing to support legacy functionality should define it and provide
-pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
\ No newline at end of file
+pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
index 083d24752b8351220928a5d375cd9ea7a294a63f..55d24433d151e94162c732f5c36d943501c7fae8 100644 (file)
@@ -178,10 +178,9 @@ Released 1994-06-13
        7. ACKNOWLEDGMENTS.
 
        These drivers wouldn't have been done without the base
-       (and support) from Ross Biro <bir7@leland.stanford.edu>,
-       and D-Link Systems Inc.  The driver relies upon GPL-ed
-       source from D-Link Systems Inc. and from Russel Nelson at
-       Crynwr Software <nelson@crynwr.com>.
+       (and support) from Ross Biro, and D-Link Systems Inc.
+       The driver relies upon GPL-ed source from D-Link Systems Inc.
+       and from Russel Nelson at Crynwr Software <nelson@crynwr.com>.
 
        Additional input also from:
        Donald Becker <becker@super.org>, Alan Cox <A.Cox@swansea.ac.uk>
index fa12a9e4abdd2a4f23075c48ba8652c21cea27d1..80e1cb19609f552e958f7bd2259279e1a678e1cd 100644 (file)
@@ -12,7 +12,7 @@ Don is no longer the prime maintainer of this version of the driver.
 Please report problems to one or more of:
 
   Andrew Morton <andrewm@uow.edu.au>
-  Netdev mailing list <netdev@oss.sgi.com>
+  Netdev mailing list <netdev@vger.kernel.org>
   Linux kernel mailing list <linux-kernel@vger.kernel.org>
 
 Please note the 'Reporting and Diagnosing Problems' section at the end
index 67514bf87ccde2db27f138fc52348899bf8ec351..62b1dc5d97e2e90523e8010b93054f81ef3ffe58 100644 (file)
@@ -279,6 +279,7 @@ pci_for_each_dev_reverse()  Superseded by pci_find_device_reverse()
 pci_for_each_bus()             Superseded by pci_find_next_bus()
 pci_find_device()              Superseded by pci_get_device()
 pci_find_subsys()              Superseded by pci_get_subsys()
+pci_find_slot()                        Superseded by pci_get_slot()
 pcibios_find_class()           Superseded by pci_get_class()
 pci_find_class()               Superseded by pci_get_class()
 pci_(read|write)_*_nodev()     Superseded by pci_bus_(read|write)_*()
index 5d4ae9a39f1d5df7ffa644d39d0235a71b22c125..f987afe43e28e1327ee76ab4f3fdb617abfe0829 100644 (file)
@@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
 #READY_AFTER_RESUME
 #
 
-Driver Detach Power Management
-
-The kernel now supports the ability to place a device in a low-power
-state when it is detached from its driver, which happens when its
-module is removed. 
-
-Each device contains a 'detach_state' file in its sysfs directory
-which can be used to control this state. Reading from this file
-displays what the current detach state is set to. This is 0 (On) by
-default. A user may write a positive integer value to this file in the
-range of 1-4 inclusive. 
-
-A value of 1-3 will indicate the device should be placed in that
-low-power state, which will cause ->suspend() to be called for that
-device. A value of 4 indicates that the device should be shutdown, so
-->shutdown() will be called for that device. 
-
-The driver is responsible for reinitializing the device when the
-module is re-inserted during it's ->probe() (or equivalent) method. 
-The driver core will not call any extra functions when binding the
-device to the driver. 
 
 pm_message_t meaning
 
index c85428e7ad9263487bf2ef6816e2bdd1379e2097..35b1a7dae34253751ade84ca7f0eda948fac11dd 100644 (file)
@@ -165,40 +165,9 @@ Description:
 These functions are intended for use by individual drivers, and are defined in 
 struct pci_driver:
 
-        int  (*save_state) (struct pci_dev *dev, u32 state);
-        int  (*suspend) (struct pci_dev *dev, u32 state);
+        int  (*suspend) (struct pci_dev *dev, pm_message_t state);
         int  (*resume) (struct pci_dev *dev);
-        int  (*enable_wake) (struct pci_dev *dev, u32 state, int enable);
-
-
-save_state
-----------
-
-Usage:
-
-if (dev->driver && dev->driver->save_state)
-       dev->driver->save_state(dev,state);
-
-The driver should use this callback to save device state. It should take into
-account the current state of the device and the requested state in order to
-avoid any unnecessary operations.
-
-For example, a video card that supports all 4 states (D0-D3), all controller
-context is preserved when entering D1, but the screen is placed into a low power
-state (blanked). 
-
-The driver can also interpret this function as a notification that it may be
-entering a sleep state in the near future. If it knows that the device cannot
-enter the requested state, either because of lack of support for it, or because
-the device is middle of some critical operation, then it should fail.
-
-This function should not be used to set any state in the device or the driver
-because the device may not actually enter the sleep state (e.g. another driver
-later causes causes a global state transition to fail).
-
-Note that in intermediate low power states, a device's I/O and memory spaces may
-be disabled and may not be available in subsequent transitions to lower power
-states.
+        int  (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable);
 
 
 suspend
index c0a62e116e6e969e2e6e6cbe7b354a1e16a42fdc..dca75cbda6f8abc144afb9efcdea77b7b5f21eac 100644 (file)
@@ -347,8 +347,8 @@ address that is created by firmware.  An example vty-server sysfs entry
 looks like the following:
 
        Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
-       .   current_vty   devspec  name          partner_vtys
-       ..  detach_state  index    partner_clcs  vterm_state
+       .   current_vty   devspec       name          partner_vtys
+       ..  index         partner_clcs  vterm_state
 
 Each entry is provided, by default with a "name" attribute.  Reading the
 "name" attribute will reveal the device type as shown in the following
index 44b6eea60ecec18a090a426a3c5cbef7920b5e82..b9e6be00cadfbc1f2e767076c467ccb6f6ad28e6 100644 (file)
@@ -25,6 +25,9 @@ APICs
 
    noapictimer  Don't set up the APIC timer
 
+   no_timer_check Don't check the IO-APIC timer. This can work around
+                problems with incorrect timer initialization on some boards.
+
 Early Console
 
    syntax: earlyprintk=vga
index f384a9758fc05fa1860876120ca336c05b797c6b..86ba94f16e83082be25974bdfb859660e5686a6c 100644 (file)
@@ -73,7 +73,7 @@ S: Status, one of the following:
 3C359 NETWORK DRIVER
 P:     Mike Phillips
 M:     mikep@linuxtr.net
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 L:     linux-tr@linuxtr.net
 W:     http://www.linuxtr.net
 S:     Maintained
@@ -81,13 +81,13 @@ S:  Maintained
 3C505 NETWORK DRIVER
 P:     Philip Blundell
 M:     philb@gnu.org
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 3CR990 NETWORK DRIVER
 P:     David Dillow
 M:     dave@thedillows.org
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 3W-XXXX ATA-RAID CONTROLLER DRIVER
@@ -130,7 +130,7 @@ S:  Maintained
 8169 10/100/1000 GIGABIT ETHERNET DRIVER
 P:     Francois Romieu
 M:     romieu@fr.zoreil.com
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
@@ -143,7 +143,7 @@ S:  Maintained
 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
 P:     Paul Gortmaker
 M:     p_gortmaker@yahoo.com
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 A2232 SERIAL BOARD DRIVER
@@ -239,6 +239,12 @@ L: linux-usb-devel@lists.sourceforge.net
 W:     http://www.linux-usb.org/SpeedTouch/
 S:     Maintained
 
+ALI1563 I2C DRIVER
+P:     Rudolf Marek
+M:     r.marek@sh.cvut.cz
+L:     sensors@stimpy.netroedge.com
+S:     Maintained
+
 ALPHA PORT
 P:     Richard Henderson
 M:     rth@twiddle.net
@@ -326,7 +332,7 @@ S:  Maintained
 
 ARPD SUPPORT
 P:     Jonathan Layes
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 ASUS ACPI EXTRAS DRIVER
@@ -700,7 +706,7 @@ S:  Orphaned
 
 DIGI RIGHTSWITCH NETWORK DRIVER
 P:     Rick Richardson
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 W:     http://www.digi.com
 S:     Orphaned
 
@@ -806,7 +812,7 @@ S:  Maintained
 ETHEREXPRESS-16 NETWORK DRIVER
 P:     Philip Blundell
 M:     philb@gnu.org
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 ETHERNET BRIDGE
@@ -869,7 +875,7 @@ S:  Maintained
 FRAME RELAY DLCI/FRAD (Sangoma drivers too)
 P:     Mike McLagan
 M:     mike.mclagan@linux.org
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 FREEVXFS FILESYSTEM
@@ -1023,8 +1029,8 @@ W:        http://www.ia64-linux.org/
 S:     Maintained
 
 SN-IA64 (Itanium) SUB-PLATFORM
-P:     Jesse Barnes
-M:     jbarnes@sgi.com
+P:     Greg Edwards
+M:     edwardsg@sgi.com
 L:     linux-altix@sgi.com
 L:     linux-ia64@vger.kernel.org
 W:     http://www.sgi.com/altix
@@ -1209,7 +1215,7 @@ S:        Maintained
 IPX NETWORK LAYER
 P:     Arnaldo Carvalho de Melo
 M:     acme@conectiva.com.br
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 IRDA SUBSYSTEM
@@ -1476,7 +1482,7 @@ MARVELL MV64340 ETHERNET DRIVER
 P:     Manish Lachwani
 M:     Manish_Lachwani@pmc-sierra.com
 L:     linux-mips@linux-mips.org
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Supported
 
 MATROX FRAMEBUFFER DRIVER
@@ -1586,13 +1592,13 @@ P:      Andrew Morton
 M:     akpm@osdl.org
 P:     Jeff Garzik
 M:     jgarzik@pobox.com
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 NETWORKING [GENERAL]
 P:     Networking Team
-M:     netdev@oss.sgi.com
-L:     netdev@oss.sgi.com
+M:     netdev@vger.kernel.org
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 NETWORKING [IPv4/IPv6]
@@ -1608,7 +1614,7 @@ P:        Hideaki YOSHIFUJI
 M:     yoshfuji@linux-ipv6.org
 P:     Patrick McHardy
 M:     kaber@coreworks.de
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 IPVS
@@ -1628,7 +1634,7 @@ NI5010 NETWORK DRIVER
 P:     Jan-Pascal van Best and Andreas Mohr
 M:     Jan-Pascal van Best <jvbest@qv3pluto.leidenuniv.nl>
 M:     Andreas Mohr <100.30936@germany.net>
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER
@@ -1670,7 +1676,7 @@ P:        Peter De Shrijver
 M:     p2@ace.ulyssis.student.kuleuven.ac.be
 P:     Mike Phillips
 M:     mikep@linuxtr.net 
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 L:     linux-tr@linuxtr.net
 W:     http://www.linuxtr.net
 S:     Maintained
@@ -1699,7 +1705,9 @@ P:        Pavel Roskin
 M:     proski@gnu.org
 P:     David Gibson
 M:     hermes@gibson.dropbear.id.au
-W:     http://www.ozlabs.org/people/dgibson/dldwd
+L:     orinoco-users@lists.sourceforge.net
+L:     orinoco-devel@lists.sourceforge.net
+W:     http://www.nongnu.org/orinoco/
 S:     Maintained
 
 PARALLEL PORT SUPPORT
@@ -1775,7 +1783,7 @@ S:        Unmaintained
 PCNET32 NETWORK DRIVER
 P:     Thomas Bogendörfer
 M:     tsbogend@alpha.franken.de
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 PHRAM MTD DRIVER
@@ -1787,7 +1795,7 @@ S:        Maintained
 POSIX CLOCKS and TIMERS
 P:     George Anzinger
 M:     george@mvista.com
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Supported
 
 PNP SUPPORT
@@ -1822,7 +1830,7 @@ S:        Supported
 PRISM54 WIRELESS DRIVER
 P:     Prism54 Development Team
 M:     prism54-private@prism54.org
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 W:     http://prism54.org
 S:     Maintained
 
@@ -2039,7 +2047,7 @@ SIS 900/7016 FAST ETHERNET DRIVER
 P:     Daniele Venzano
 M:     venza@brownhat.org
 W:     http://www.brownhat.org/sis900.html
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 SIS FRAMEBUFFER DRIVER
@@ -2098,7 +2106,7 @@ S:        Maintained
 SONIC NETWORK DRIVER
 P:     Thomas Bogendoerfer
 M:     tsbogend@alpha.franken.de
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Maintained
 
 SONY VAIO CONTROL DEVICE DRIVER
@@ -2155,7 +2163,7 @@ S:        Supported
 SPX NETWORK LAYER
 P:     Jay Schulist
 M:     jschlst@samba.org
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 S:     Supported
 
 SRM (Alpha) environment access
@@ -2234,7 +2242,7 @@ S:        Maintained
 TOKEN-RING NETWORK DRIVER
 P:     Mike Phillips
 M:     mikep@linuxtr.net
-L:     netdev@oss.sgi.com
+L:     netdev@vger.kernel.org
 L:     linux-tr@linuxtr.net
 W:     http://www.linuxtr.net
 S:     Maintained
index f7eb55878f11575281add2a5726e483aed5e45bb..9e005e18c71c4b7adc83a200e1ae10782c751920 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 12
-EXTRAVERSION =-rc3
+EXTRAVERSION =-rc6
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
@@ -530,7 +530,7 @@ endif
 include $(srctree)/arch/$(ARCH)/Makefile
 
 # arch Makefile may override CC so keep this after arch Makefile is included
-NOSTDINC_FLAGS := -nostdinc -isystem $(shell $(CC) -print-file-name=include)
+NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
 CHECKFLAGS     += $(NOSTDINC_FLAGS)
 
 # warn about C99 declaration after statement
index 0c79b9d95f74ee4383ed16dd11048ecdf37b3920..f7c96635d3b4fe7cf6d482b8d351e1c4f42095b4 100644 (file)
@@ -280,6 +280,10 @@ config ISA
          (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
          newer boards don't support it.  If you have ISA, say Y, otherwise N.
 
+config ISA_DMA_API
+       bool
+       default y
+
 config PCI
        bool
        depends on !ALPHA_JENSEN
index 64e450dddb49d55c3ddea43bb35371958f52369a..167fd89f8707aeb1b0ad59190e9fa352718d5900 100644 (file)
@@ -1150,16 +1150,13 @@ osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remai
        if (get_tv32(&tmp, sleep))
                goto fault;
 
-       ticks = tmp.tv_usec;
-       ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
-       ticks += tmp.tv_sec * HZ;
+       ticks = timeval_to_jiffies(&tmp);
 
        current->state = TASK_INTERRUPTIBLE;
        ticks = schedule_timeout(ticks);
 
        if (remain) {
-               tmp.tv_sec = ticks / HZ;
-               tmp.tv_usec = ticks % HZ;
+               jiffies_to_timeval(ticks, &tmp);
                if (put_tv32(remain, &tmp))
                        goto fault;
        }
index 4055115ae0e285f88d319be0369765a7d54b8409..475950c8a8317ec435f441137e4357d35efc93c1 100644 (file)
@@ -85,6 +85,7 @@ choice
 config ARCH_CLPS7500
        bool "Cirrus-CL-PS7500FE"
        select TIMER_ACORN
+       select ISA
 
 config ARCH_CLPS711X
        bool "CLPS711x/EP721x-based"
@@ -96,6 +97,7 @@ config ARCH_CO285
 
 config ARCH_EBSA110
        bool "EBSA-110"
+       select ISA
        help
          This is an evaluation board for the StrongARM processor available
          from Digital. It has limited hardware on-board, including an onboard
@@ -120,13 +122,16 @@ config ARCH_INTEGRATOR
 
 config ARCH_IOP3XX
        bool "IOP3xx-based"
+       select PCI
 
 config ARCH_IXP4XX
        bool "IXP4xx-based"
        select DMABOUNCE
+       select PCI
 
 config ARCH_IXP2000
        bool "IXP2400/2800-based"
+       select PCI
 
 config ARCH_L7200
        bool "LinkUp-L7200"
@@ -155,6 +160,8 @@ config ARCH_RPC
 
 config ARCH_SA1100
        bool "SA1100-based"
+       select ISA
+       select DISCONTIGMEM
 
 config ARCH_S3C2410
        bool "Samsung S3C2410"
@@ -165,6 +172,9 @@ config ARCH_S3C2410
 
 config ARCH_SHARK
        bool "Shark"
+       select ISA
+       select ISA_DMA
+       select PCI
 
 config ARCH_LH7A40X
        bool "Sharp LH7A40X"
@@ -252,8 +262,6 @@ config ARM_AMBA
 
 config ISA
        bool
-       depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100 || ARCH_MX1ADS
-       default y
        help
          Find out whether you have ISA slots on your motherboard.  ISA is the
          name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -263,12 +271,13 @@ config ISA
 
 config ISA_DMA
        bool
-       depends on FOOTBRIDGE_HOST || ARCH_SHARK
+
+config ISA_DMA_API
+       bool
        default y
 
 config PCI
        bool "PCI support" if ARCH_INTEGRATOR_AP
-       default y if ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_IXP2000
        help
          Find out whether you have a PCI motherboard. PCI is the name of a
          bus system, i.e. the way the CPU talks to the other stuff inside
@@ -296,7 +305,7 @@ menu "Kernel Features"
 
 config SMP
        bool "Symmetric Multi-Processing (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && n
+       depends on EXPERIMENTAL #&& n
        help
          This enables support for systems with more than one CPU. If you have
          a system with only one CPU, like most personal computers, say N. If
@@ -336,8 +345,7 @@ config PREEMPT
 
 config DISCONTIGMEM
        bool
-       depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
-       default y
+       default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
        help
          Say Y to support efficient handling of discontiguous physical memory,
          for architectures which are either NUMA (Non-Uniform Memory Access)
@@ -489,7 +497,7 @@ source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_SA1100
        bool
-       depends on CPU_FREQ && (SA1100_LART || SA1100_PLEB)
+       depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
        default y
 
 config CPU_FREQ_SA1110
@@ -681,7 +689,9 @@ source "drivers/block/Kconfig"
 
 source "drivers/acorn/block/Kconfig"
 
-if ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
+if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
+       || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
+       || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
 source "drivers/ide/Kconfig"
 endif
 
index 665bd2c2074303d44b7c3593125c7659cc5258f8..d3fe2533907ec1af9c812362eb91802a8af713f4 100644 (file)
@@ -47,3 +47,10 @@ __XScale_start:
                orr     r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
 #endif
 
+#ifdef CONFIG_ARCH_IXP2000
+               mov     r1, #-1
+               mov     r0, #0xd6000000
+               str     r1, [r0, #0x14]
+               str     r1, [r0, #0x18]
+#endif
+
index 2b4059d2f8e457c05af2cba17f060b7dcf252388..5d92af975d870ae59b162d33e7ca49e56cca924d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sat Mar 26 21:32:26 2005
+# Linux kernel version: 2.6.12-rc6-git3
+# Thu Jun  9 19:00:50 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -34,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y
 CONFIG_CPU_CACHE_V4WB=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -122,6 +124,7 @@ CONFIG_FORCE_MAX_ZONEORDER=9
 # Bus support
 #
 CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -131,6 +134,7 @@ CONFIG_ISA=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_DISCONTIGMEM=y
 # CONFIG_LEDS is not set
@@ -152,12 +156,14 @@ CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_SA1100=y
 
 #
 # Floating point emulation
@@ -294,7 +300,6 @@ CONFIG_PARPORT_NOT_PC=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -428,7 +433,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -526,6 +530,7 @@ CONFIG_IRDA_ULTRA=y
 # CONFIG_SMC_IRCC_FIR is not set
 # CONFIG_ALI_FIR is not set
 CONFIG_SA1100_FIR=y
+# CONFIG_VIA_FIR is not set
 CONFIG_BT=m
 CONFIG_BT_L2CAP=m
 # CONFIG_BT_SCO is not set
@@ -618,7 +623,6 @@ CONFIG_NET_WIRELESS=y
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -687,7 +691,6 @@ CONFIG_RTC=m
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -736,6 +739,7 @@ CONFIG_I2C_ELEKTOR=m
 # 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_SMSC47B397 is not set
@@ -747,6 +751,7 @@ CONFIG_I2C_ELEKTOR=m
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -871,7 +876,6 @@ CONFIG_USB_PRINTER=m
 #
 CONFIG_USB_STORAGE=y
 CONFIG_USB_STORAGE_DEBUG=y
-# CONFIG_USB_STORAGE_RW_DETECT is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
@@ -954,9 +958,11 @@ CONFIG_USB_USS720=m
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
 CONFIG_USB_SERIAL_BELKIN=m
 CONFIG_USB_SERIAL_WHITEHEAT=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -985,6 +991,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
 # CONFIG_USB_SERIAL_TI is not set
 CONFIG_USB_SERIAL_CYBERJACK=m
index b4e297dd54b2286374dfa6814018fb65f03bf2cd..b9de07de80feac1f708039d39940864c5192c94b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Mon Mar 28 00:02:26 2005
+# Linux kernel version: 2.6.12-rc4
+# Thu Jun  9 01:59:03 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -33,6 +34,8 @@ CONFIG_KOBJECT_UEVENT=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -120,6 +123,7 @@ CONFIG_CPU_MINICACHE=y
 # Bus support
 #
 CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -138,6 +142,7 @@ CONFIG_PCMCIA_SA1100=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_DISCONTIGMEM=y
 # CONFIG_LEDS is not set
@@ -159,12 +164,13 @@ CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+CONFIG_CPU_FREQ_SA1100=y
 
 #
 # Floating point emulation
@@ -298,7 +304,6 @@ CONFIG_MTD_SA1100=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
@@ -379,7 +384,6 @@ CONFIG_NET=y
 # Networking options
 #
 # CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -476,6 +480,7 @@ CONFIG_IRCOMM=m
 # CONFIG_SMC_IRCC_FIR is not set
 # CONFIG_ALI_FIR is not set
 CONFIG_SA1100_FIR=m
+# CONFIG_VIA_FIR is not set
 # CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
@@ -647,7 +652,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -676,9 +680,11 @@ CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 CONFIG_FB_SA1100=y
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
index 6987c8c5ddb4ac3fe28f2285f3d7b4e7f235d03f..fb41a36a5a68fe42ce39f08a3367b9abf984ac6b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Mon Mar 28 00:22:34 2005
+# Linux kernel version: 2.6.12-rc6-git3
+# Thu Jun  9 20:58:58 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -34,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y
 CONFIG_CPU_CACHE_V4WB=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -119,6 +121,7 @@ CONFIG_CPU_MINICACHE=y
 # Bus support
 #
 CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -128,6 +131,7 @@ CONFIG_ISA=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_DISCONTIGMEM=y
 CONFIG_LEDS=y
@@ -151,12 +155,14 @@ CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_SA1100=y
 
 #
 # Floating point emulation
@@ -280,7 +286,6 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
@@ -338,7 +343,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -484,7 +488,6 @@ CONFIG_SERIO=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -533,7 +536,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
index 080df907f24286c31416a70072f6933a5fd6a699..e14278d59882367dc579f1dabeb5f2d191772ee2 100644 (file)
@@ -17,8 +17,8 @@
 
 #include <asm/glue.h>
 #include <asm/vfpmacros.h>
-#include <asm/hardware.h>              @ should be moved into entry-macro.S
-#include <asm/arch/irqs.h>             @ should be moved into entry-macro.S
+#include <asm/hardware.h>              /* should be moved into entry-macro.S */
+#include <asm/arch/irqs.h>             /* should be moved into entry-macro.S */
 #include <asm/arch/entry-macro.S>
 
 #include "entry-header.S"
@@ -269,7 +269,7 @@ __pabt_svc:
        add     r5, sp, #S_PC
        ldmia   r7, {r2 - r4}                   @ Get USR pc, cpsr
 
-#if __LINUX_ARM_ARCH__ < 6
+#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
        @ make sure our user space atomic helper is aborted
        cmp     r2, #VIRT_OFFSET
        bichs   r3, r3, #PSR_Z_BIT
@@ -505,9 +505,9 @@ ENTRY(__switch_to)
        mra     r4, r5, acc0
        stmia   ip, {r4, r5}
 #endif
-#ifdef CONFIG_HAS_TLS_REG
+#if defined(CONFIG_HAS_TLS_REG)
        mcr     p15, 0, r3, c13, c0, 3          @ set TLS register
-#else
+#elif !defined(CONFIG_TLS_REG_EMUL)
        mov     r4, #0xffff0fff
        str     r3, [r4, #-15]                  @ TLS val at 0xffff0ff0
 #endif
@@ -616,11 +616,17 @@ __kuser_helper_start:
 
 __kuser_cmpxchg:                               @ 0xffff0fc0
 
-#if __LINUX_ARM_ARCH__ < 6
+#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
 
-#ifdef CONFIG_SMP  /* sanity check */
-#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?"
-#endif
+       /*
+        * Poor you.  No fast solution possible...
+        * The kernel itself must perform the operation.
+        * A special ghost syscall is used for that (see traps.c).
+        */
+       swi     #0x9ffff0
+       mov     pc, lr
+
+#elif __LINUX_ARM_ARCH__ < 6
 
        /*
         * Theory of operation:
@@ -690,11 +696,7 @@ __kuser_cmpxchg:                           @ 0xffff0fc0
 
 __kuser_get_tls:                               @ 0xffff0fe0
 
-#ifndef CONFIG_HAS_TLS_REG
-
-#ifdef CONFIG_SMP  /* sanity check */
-#error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong"
-#endif
+#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
 
        ldr     r0, [pc, #(16 - 8)]             @ TLS stored at 0xffff0ff0
        mov     pc, lr
index 171b3e811c7166f20cf218266982fb895575d704..4733877296d41209f6e0b0dd6c5c66cf6a0f3762 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/procinfo.h>
 #include <asm/ptrace.h>
 #include <asm/constants.h>
+#include <asm/thread_info.h>
 #include <asm/system.h>
 
 #define PROCINFO_MMUFLAGS      8
@@ -131,7 +132,7 @@ __switch_data:
        .long   processor_id                    @ r4
        .long   __machine_arch_type             @ r5
        .long   cr_alignment                    @ r6
-       .long   init_thread_union+8192          @ sp
+       .long   init_thread_union + THREAD_START_SP @ sp
 
 /*
  * The following fragment of code is executed with the MMU on, and uses
index 26eacd3e5def130504adf2ddd88f9cc977c98abf..8f146a4b4752665013bc33c510f1df5adb53a739 100644 (file)
@@ -256,8 +256,6 @@ static unsigned long *thread_info_head;
 static unsigned int nr_thread_info;
 
 #define EXTRA_TASK_STRUCT      4
-#define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
-#define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
 
 struct thread_info *alloc_thread_info(struct task_struct *task)
 {
@@ -274,17 +272,16 @@ struct thread_info *alloc_thread_info(struct task_struct *task)
        }
 
        if (!thread)
-               thread = ll_alloc_task_struct();
+               thread = (struct thread_info *)
+                          __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
 
-#ifdef CONFIG_MAGIC_SYSRQ
+#ifdef CONFIG_DEBUG_STACK_USAGE
        /*
         * The stack must be cleared if you want SYSRQ-T to
         * give sensible stack usage information
         */
-       if (thread) {
-               char *p = (char *)thread;
-               memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
-       }
+       if (thread)
+               memzero(thread, THREAD_SIZE);
 #endif
        return thread;
 }
@@ -297,7 +294,7 @@ void free_thread_info(struct thread_info *thread)
                thread_info_head = p;
                nr_thread_info += 1;
        } else
-               ll_free_task_struct(thread);
+               free_pages((unsigned long)thread, THREAD_SIZE_ORDER);
 }
 
 /*
@@ -350,7 +347,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
        struct thread_info *thread = p->thread_info;
        struct pt_regs *childregs;
 
-       childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1;
+       childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1;
        *childregs = *regs;
        childregs->ARM_r0 = 0;
        childregs->ARM_sp = stack_start;
@@ -447,15 +444,17 @@ EXPORT_SYMBOL(kernel_thread);
 unsigned long get_wchan(struct task_struct *p)
 {
        unsigned long fp, lr;
-       unsigned long stack_page;
+       unsigned long stack_start, stack_end;
        int count = 0;
        if (!p || p == current || p->state == TASK_RUNNING)
                return 0;
 
-       stack_page = 4096 + (unsigned long)p->thread_info;
+       stack_start = (unsigned long)(p->thread_info + 1);
+       stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE;
+
        fp = thread_saved_fp(p);
        do {
-               if (fp < stack_page || fp > 4092+stack_page)
+               if (fp < stack_start || fp > stack_end)
                        return 0;
                lr = pc_pointer (((unsigned long *)fp)[-1]);
                if (!in_sched_functions(lr))
index ef32577da304ba7f4c13a9c92d0f6a36631d3376..f897ce2ccf0d358cc79a6493b23d1cf33d91a05a 100644 (file)
@@ -302,7 +302,7 @@ long execve(const char *filename, char **argv, char **envp)
                "b      ret_to_user"
                :
                : "r" (current_thread_info()),
-                 "Ir" (THREAD_SIZE - 8 - sizeof(regs)),
+                 "Ir" (THREAD_START_SP - sizeof(regs)),
                  "r" (&regs),
                  "Ir" (sizeof(regs))
                : "r0", "r1", "r2", "r3", "ip", "memory");
index 3a001fe5540badeb1b5452f9d665e747e28687a2..45d2a032d8900f4f4f4d12c97ed0da021a4aa233 100644 (file)
@@ -218,7 +218,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
                tsk->comm, tsk->pid, tsk->thread_info + 1);
 
        if (!user_mode(regs) || in_interrupt()) {
-               dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info);
+               dump_mem("Stack: ", regs->ARM_sp,
+                        THREAD_SIZE + (unsigned long)tsk->thread_info);
                dump_backtrace(regs, tsk);
                dump_instr(regs);
        }
@@ -450,9 +451,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
 
        case NR(set_tls):
                thread->tp_value = regs->ARM_r0;
-#ifdef CONFIG_HAS_TLS_REG
+#if defined(CONFIG_HAS_TLS_REG)
                asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
-#else
+#elif !defined(CONFIG_TLS_REG_EMUL)
                /*
                 * User space must never try to access this directly.
                 * Expect your app to break eventually if you do so.
@@ -463,6 +464,55 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
 #endif
                return 0;
 
+#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
+       /*
+        * Atomically store r1 in *r2 if *r2 is equal to r0 for user space.
+        * Return zero in r0 if *MEM was changed or non-zero if no exchange
+        * happened.  Also set the user C flag accordingly.
+        * If access permissions have to be fixed up then non-zero is
+        * returned and the operation has to be re-attempted.
+        *
+        * *NOTE*: This is a ghost syscall private to the kernel.  Only the
+        * __kuser_cmpxchg code in entry-armv.S should be aware of its
+        * existence.  Don't ever use this from user code.
+        */
+       case 0xfff0:
+       {
+               extern void do_DataAbort(unsigned long addr, unsigned int fsr,
+                                        struct pt_regs *regs);
+               unsigned long val;
+               unsigned long addr = regs->ARM_r2;
+               struct mm_struct *mm = current->mm;
+               pgd_t *pgd; pmd_t *pmd; pte_t *pte;
+
+               regs->ARM_cpsr &= ~PSR_C_BIT;
+               spin_lock(&mm->page_table_lock);
+               pgd = pgd_offset(mm, addr);
+               if (!pgd_present(*pgd))
+                       goto bad_access;
+               pmd = pmd_offset(pgd, addr);
+               if (!pmd_present(*pmd))
+                       goto bad_access;
+               pte = pte_offset_map(pmd, addr);
+               if (!pte_present(*pte) || !pte_write(*pte))
+                       goto bad_access;
+               val = *(unsigned long *)addr;
+               val -= regs->ARM_r0;
+               if (val == 0) {
+                       *(unsigned long *)addr = regs->ARM_r1;
+                       regs->ARM_cpsr |= PSR_C_BIT;
+               }
+               spin_unlock(&mm->page_table_lock);
+               return val;
+
+               bad_access:
+               spin_unlock(&mm->page_table_lock);
+               /* simulate a read access fault */
+               do_DataAbort(addr, 15 + (1 << 11), regs);
+               return -1;
+       }
+#endif
+
        default:
                /* Calls 9f00xx..9f07ff are defined to return -ENOSYS
                   if not implemented, rather than raising SIGILL.  This
@@ -497,11 +547,14 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
        return 0;
 }
 
-#if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG)
+#ifdef CONFIG_TLS_REG_EMUL
 
 /*
  * We might be running on an ARMv6+ processor which should have the TLS
- * register, but for some reason we can't use it and have to emulate it.
+ * register but for some reason we can't use it, or maybe an SMP system
+ * using a pre-ARMv6 processor (there are apparently a few prototypes like
+ * that in existence) and therefore access to that register must be
+ * emulated.
  */
 
 static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
index a39c6a42d68ad4b6a9a8f1f3a1b3b28e54591c38..ad2d66c93a5c3edf15f7a854683c9d67bfd76241 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <asm-generic/vmlinux.lds.h>
 #include <linux/config.h>
+#include <asm/thread_info.h>
        
 OUTPUT_ARCH(arm)
 ENTRY(stext)
@@ -103,7 +104,7 @@ SECTIONS
        __data_loc = ALIGN(4);          /* location in binary */
        . = DATAADDR;
 #else
-       . = ALIGN(8192);
+       . = ALIGN(THREAD_SIZE);
        __data_loc = .;
 #endif
 
index 6d1d7c27806e407f6c2efaf0c1f7fcbc16927614..5e240e452af6af66b2d9d18321009fddea82c73e 100644 (file)
@@ -87,9 +87,9 @@ ENTRY(__raw_writesw)
                subs    r2, r2, #2
                orr     ip, ip, r3, push_hbyte1
                strh    ip, [r0]
-               bpl     2b
+               bpl     1b
 
-3:             tst     r2, #1
-2:             movne   ip, r3, lsr #8
+               tst     r2, #1
+3:             movne   ip, r3, lsr #8
                strneh  ip, [r0]
                mov     pc, lr
index f6e676322ca948209afc244201939cdedf10bf58..45c930ccd064802ec3195e342ed57476db6ca43d 100644 (file)
@@ -10,6 +10,7 @@ config ARCH_AUTCPU12
 
 config ARCH_CDB89712
        bool "CDB89712"
+       select ISA
        help
          This is an evaluation board from Cirrus for the CS89712 processor.
          The board includes 2 serial ports, Ethernet, IRDA, and expansion
@@ -26,6 +27,8 @@ config ARCH_CLEP7312
 
 config ARCH_EDB7211
        bool "EDB7211"
+       select ISA
+       select DISCONTIGMEM
        help
          Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
          evaluation board.
index 1090c680b6dd3653afd524c11c02a8ade7a60c81..324d9edeec38f3e1dc70cff7248705e0837429ea 100644 (file)
@@ -5,6 +5,9 @@ menu "Footbridge Implementations"
 config ARCH_CATS
        bool "CATS"
        select FOOTBRIDGE_HOST
+       select ISA
+       select ISA_DMA
+       select PCI
        help
          Say Y here if you intend to run this kernel on the CATS.
 
@@ -13,6 +16,9 @@ config ARCH_CATS
 config ARCH_PERSONAL_SERVER
        bool "Compaq Personal Server"
        select FOOTBRIDGE_HOST
+       select ISA
+       select ISA_DMA
+       select PCI
        ---help---
          Say Y here if you intend to run this kernel on the Compaq
          Personal Server.
@@ -42,6 +48,9 @@ config ARCH_EBSA285_HOST
        bool "EBSA285 (host mode)"
        select ARCH_EBSA285
        select FOOTBRIDGE_HOST
+       select ISA
+       select ISA_DMA
+       select PCI
        help
          Say Y here if you intend to run this kernel on the EBSA285 card
          in host ("central function") mode.
@@ -51,6 +60,9 @@ config ARCH_EBSA285_HOST
 config ARCH_NETWINDER
        bool "NetWinder"
        select FOOTBRIDGE_HOST
+       select ISA
+       select ISA_DMA
+       select PCI
        help
          Say Y here if you intend to run this kernel on the Rebel.COM
          NetWinder.  Information about this machine can be found at:
index ec85813ee5dc7c139171d8b80a4d259f82b0b6a8..cddd194ac6eb7f36b487f215896bcd8773130c21 100644 (file)
@@ -4,6 +4,7 @@ menu "IMX Implementations"
 config ARCH_MX1ADS
        bool "mx1ads"
        depends on ARCH_IMX
+       select ISA
        help
          Say Y here if you are using the Motorola MX1ADS board
 
index 94bcdb933e41f1f0065b12154f9d1a5f3f7c7e36..aa92e3708838ed31fadbead7b073cfc7a3894578 100644 (file)
@@ -501,15 +501,6 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask)
        return -EIO;
 }
     
-int
-pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
-       if (mask >= SZ_64M - 1 )
-               return 0;
-
-       return -EIO;
-}
-
 int
 pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
 {
@@ -520,7 +511,6 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
 }
 
 EXPORT_SYMBOL(pci_set_dma_mask);
-EXPORT_SYMBOL(pci_dac_set_dma_mask);
 EXPORT_SYMBOL(pci_set_consistent_dma_mask);
 EXPORT_SYMBOL(ixp4xx_pci_read);
 EXPORT_SYMBOL(ixp4xx_pci_write);
index 3f952237ae3ddd185410bb2af9b1a9bf9bb981ad..6823ae28ae6a2c9de157c15637198ae0b5eb77be 100644 (file)
@@ -304,6 +304,15 @@ static void __init mainstone_map_io(void)
        PWER  = 0xC0000002;
        PRER  = 0x00000002;
        PFER  = 0x00000002;
+       /*      for use I SRAM as framebuffer.  */
+       PSLR |= 0xF04;
+       PCFR = 0x66;
+       /*      For Keypad wakeup.      */
+       KPC &=~KPC_ASACT;
+       KPC |=KPC_AS;
+       PKWR  = 0x000FD000;
+       /*      Need read PKWR back after set it.       */
+       PKWR;
 }
 
 MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
index 82a4bf34c251c338cc735679a559eef2ecf4e46e..9799fe80df23255d6d77bca271100b7b683a9345 100644 (file)
@@ -29,9 +29,6 @@
  */
 #undef DEBUG
 
-extern void pxa_cpu_suspend(void);
-extern void pxa_cpu_resume(void);
-
 #define SAVE(x)                sleep_save[SLEEP_SAVE_##x] = x
 #define RESTORE(x)     x = sleep_save[SLEEP_SAVE_##x]
 
@@ -63,6 +60,12 @@ enum {       SLEEP_SAVE_START = 0,
        SLEEP_SAVE_ICMR,
        SLEEP_SAVE_CKEN,
 
+#ifdef CONFIG_PXA27x
+       SLEEP_SAVE_MDREFR,
+       SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
+       SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
+#endif
+
        SLEEP_SAVE_CKSUM,
 
        SLEEP_SAVE_SIZE
@@ -75,9 +78,7 @@ static int pxa_pm_enter(suspend_state_t state)
        unsigned long checksum = 0;
        struct timespec delta, rtc;
        int i;
-
-       if (state != PM_SUSPEND_MEM)
-               return -EINVAL;
+       extern void pxa_cpu_pm_enter(suspend_state_t state);
 
 #ifdef CONFIG_IWMMXT
        /* force any iWMMXt context to ram **/
@@ -100,16 +101,17 @@ static int pxa_pm_enter(suspend_state_t state)
        SAVE(GAFR2_L); SAVE(GAFR2_U);
 
 #ifdef CONFIG_PXA27x
+       SAVE(MDREFR);
        SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
        SAVE(GAFR3_L); SAVE(GAFR3_U);
+       SAVE(PWER); SAVE(PCFR); SAVE(PRER);
+       SAVE(PFER); SAVE(PKWR);
 #endif
 
        SAVE(ICMR);
        ICMR = 0;
 
        SAVE(CKEN);
-       CKEN = 0;
-
        SAVE(PSTR);
 
        /* Note: wake up source are set up in each machine specific files */
@@ -123,16 +125,13 @@ static int pxa_pm_enter(suspend_state_t state)
        /* Clear sleep reset status */
        RCSR = RCSR_SMR;
 
-       /* set resume return address */
-       PSPR = virt_to_phys(pxa_cpu_resume);
-
        /* before sleeping, calculate and save a checksum */
        for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
                checksum += sleep_save[i];
        sleep_save[SLEEP_SAVE_CKSUM] = checksum;
 
        /* *** go zzz *** */
-       pxa_cpu_suspend();
+       pxa_cpu_pm_enter(state);
 
        /* after sleeping, validate the checksum */
        checksum = 0;
@@ -145,7 +144,7 @@ static int pxa_pm_enter(suspend_state_t state)
                LUB_HEXLED = 0xbadbadc5;
 #endif
                while (1)
-                       pxa_cpu_suspend();
+                       pxa_cpu_pm_enter(state);
        }
 
        /* ensure not to come back here if it wasn't intended */
@@ -162,8 +161,11 @@ static int pxa_pm_enter(suspend_state_t state)
        RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
 
 #ifdef CONFIG_PXA27x
+       RESTORE(MDREFR);
        RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
        RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
+       RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
+       RESTORE(PFER); RESTORE(PKWR);
 #endif
 
        PSSR = PSSR_RDH | PSSR_PH;
@@ -197,7 +199,9 @@ unsigned long sleep_phys_sp(void *sp)
  */
 static int pxa_pm_prepare(suspend_state_t state)
 {
-       return 0;
+       extern int pxa_cpu_pm_prepare(suspend_state_t state);
+
+       return pxa_cpu_pm_prepare(state);
 }
 
 /*
index e887b7175ef33b8c547c04a14d6117deaf19ec49..7869c3b4e62f0447eee5737dc855b0b99afe5d10 100644 (file)
@@ -16,6 +16,7 @@
  * initialization stuff for PXA machines which can be overridden later if
  * need be.
  */
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -102,3 +103,35 @@ unsigned int get_lcdclk_frequency_10khz(void)
 }
 
 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);
+       extern void pxa_cpu_resume(void);
+
+       CKEN = 0;
+
+       switch (state) {
+       case PM_SUSPEND_MEM:
+               /* set resume return address */
+               PSPR = virt_to_phys(pxa_cpu_resume);
+               pxa_cpu_suspend(3);
+               break;
+       }
+}
+
+#endif
index 7e863afefb531e5a9fe6c20d22e6e1355fb3b41d..893964fb9659bbabed5ed818377f430315915ef2 100644 (file)
@@ -120,6 +120,42 @@ EXPORT_SYMBOL(get_clk_frequency_khz);
 EXPORT_SYMBOL(get_memclk_frequency_10khz);
 EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
 
+#ifdef CONFIG_PM
+
+int pxa_cpu_pm_prepare(suspend_state_t state)
+{
+       switch (state) {
+       case PM_SUSPEND_MEM:
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+void pxa_cpu_pm_enter(suspend_state_t state)
+{
+       extern void pxa_cpu_standby(void);
+       extern void pxa_cpu_suspend(unsigned int);
+       extern void pxa_cpu_resume(void);
+
+       CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
+
+       /* ensure voltage-change sequencer not initiated, which hangs */
+       PCFR &= ~PCFR_FVC;
+
+       /* Clear edge-detect status register. */
+       PEDR = 0xDF12FE1B;
+
+       switch (state) {
+       case PM_SUSPEND_MEM:
+               /* set resume return address */
+               PSPR = virt_to_phys(pxa_cpu_resume);
+               pxa_cpu_suspend(3);
+               break;
+       }
+}
+
+#endif
 
 /*
  * device registration specific to PXA27x.
index e23f534d4e1d1696ff7343ad29f1ecad893f9cc1..8d986b8401c2474f3948bb3a4301c26a9784b7f1 100644 (file)
@@ -478,7 +478,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
 {
        unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
 
-       s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2;
+       s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate);
 
        printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
               print_mhz(s3c2440_clk_upll.rate));
index bc229fab86d44644fc4d3d5bc1793035f58ec4f9..c7c28890d406c25356b2643400360cb661ee1586 100644 (file)
@@ -785,6 +785,10 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client)
        chan->client = NULL;
        chan->in_use = 0;
 
+       if (chan->irq_claimed)
+               free_irq(chan->irq, (void *)chan);
+       chan->irq_claimed = 0;
+
        local_irq_restore(flags);
 
        return 0;
index 9a8cc5ae225566e5d6d17de94df3fe79dbfe9a2c..d4c8281b55f64a5c3a7a4f2d4fef2c6433215d25 100644 (file)
@@ -192,9 +192,11 @@ void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
 
        iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
        iotable_init(mach_desc, size);
+
        /* rename any peripherals used differing from the s3c2410 */
 
-       s3c_device_i2c.name = "s3c2440-i2c";
+       s3c_device_i2c.name  = "s3c2440-i2c";
+       s3c_device_nand.name = "s3c2440-nand";
 
        /* change irq for watchdog */
 
@@ -225,7 +227,7 @@ void __init s3c2440_init_clocks(int xtal)
                break;
 
        case S3C2440_CLKDIVN_HDIVN_2:
-               hdiv = 1;
+               hdiv = 2;
                break;
 
        case S3C2440_CLKDIVN_HDIVN_4_8:
index 50cde576dadfc9cf9ebe06917c43e2e054976ed9..6923316b3d0df043f4140648bdbfd58aa0691c7e 100644 (file)
@@ -150,7 +150,7 @@ config SA1100_SSP
 
 config H3600_SLEEVE
        tristate "Compaq iPAQ Handheld sleeve support"
-       depends on SA1100_H3600
+       depends on SA1100_H3100 || SA1100_H3600
        help
          Choose this option to enable support for extension packs (sleeves)
          for the Compaq iPAQ H3XXX series of handheld computers.  This option
index 27892e34b060345dde82c4c5d8e0484b63eaee10..3fefb43c67f7c8cc851285e83e21d3648902027a 100644 (file)
@@ -228,7 +228,6 @@ config CPU_SA1100
        select CPU_CACHE_V4WB
        select CPU_CACHE_VIVT
        select CPU_TLB_V4WB
-       select CPU_MINICACHE
 
 # XScale
 config CPU_XSCALE
@@ -239,7 +238,6 @@ config CPU_XSCALE
        select CPU_ABRT_EV5T
        select CPU_CACHE_VIVT
        select CPU_TLB_V4WBI
-       select CPU_MINICACHE
 
 # ARMv6
 config CPU_V6
@@ -345,11 +343,6 @@ config CPU_TLB_V4WBI
 config CPU_TLB_V6
        bool
 
-config CPU_MINICACHE
-       bool
-       help
-         Processor has a minicache.
-
 comment "Processor Features"
 
 config ARM_THUMB
@@ -410,17 +403,30 @@ config CPU_BPREDICT_DISABLE
        help
          Say Y here to disable branch prediction.  If unsure, say N.
 
+config TLS_REG_EMUL
+       bool
+       default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
+       help
+         An SMP system using a pre-ARMv6 processor (there are apparently
+         a few prototypes like that in existence) and therefore access to
+         that required register must be emulated.
+
 config HAS_TLS_REG
        bool
-       depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3
-       default y
+       depends on !TLS_REG_EMUL
+       default y if SMP || CPU_32v7
        help
          This selects support for the CP15 thread register.
-         It is defined to be available on ARMv6 or later.  However
-         if the kernel is configured to support multiple CPUs including
-         a pre-ARMv6 processors, or if a given ARMv6 processor doesn't
-         implement the thread register for some reason, then access to
-         this register from user space must be trapped and emulated.
-         If user space is relying on the __kuser_get_tls code then
-         there should not be any impact.
+         It is defined to be available on some ARMv6 processors (including
+         all SMP capable ARMv6's) or later processors.  User space may
+         assume directly accessing that register and always obtain the
+         expected value only on ARMv7 and above.
+
+config NEEDS_SYSCALL_FOR_CMPXCHG
+       bool
+       default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
+       help
+         SMP on a pre-ARMv6 processor?  Well OK then.
+         Forget about fast user space cmpxchg support.
+         It is just not possible.
 
index ccf316c11e02523f65b3cd21e3c13fe2afd71e59..59f47d4c2dfe6edf22560b861d6a3d554104dbf1 100644 (file)
@@ -31,8 +31,6 @@ obj-$(CONFIG_CPU_COPY_V6)     += copypage-v6.o mmu.o
 obj-$(CONFIG_CPU_SA1100)       += copypage-v4mc.o
 obj-$(CONFIG_CPU_XSCALE)       += copypage-xscale.o
 
-obj-$(CONFIG_CPU_MINICACHE)    += minicache.o
-
 obj-$(CONFIG_CPU_TLB_V3)       += tlb-v3.o
 obj-$(CONFIG_CPU_TLB_V4WT)     += tlb-v4.o
 obj-$(CONFIG_CPU_TLB_V4WB)     += tlb-v4wb.o
diff --git a/arch/arm/mm/copypage-v4mc.S b/arch/arm/mm/copypage-v4mc.S
deleted file mode 100644 (file)
index 305af3d..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *  linux/arch/arm/lib/copy_page-armv4mc.S
- *
- *  Copyright (C) 1995-2001 Russell King
- *
- * 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.
- *
- *  ASM optimised string functions
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/constants.h>
-
-       .text
-       .align  5
-/*
- * ARMv4 mini-dcache optimised copy_user_page
- *
- * We flush the destination cache lines just before we write the data into the
- * corresponding address.  Since the Dcache is read-allocate, this removes the
- * Dcache aliasing issue.  The writes will be forwarded to the write buffer,
- * and merged as appropriate.
- *
- * Note: We rely on all ARMv4 processors implementing the "invalidate D line"
- * instruction.  If your processor does not supply this, you have to write your
- * own copy_user_page that does the right thing.
- */
-ENTRY(v4_mc_copy_user_page)
-       stmfd   sp!, {r4, lr}                   @ 2
-       mov     r4, r0
-       mov     r0, r1
-       bl      map_page_minicache
-       mov     r1, #PAGE_SZ/64                 @ 1
-       ldmia   r0!, {r2, r3, ip, lr}           @ 4
-1:     mcr     p15, 0, r4, c7, c6, 1           @ 1   invalidate D line
-       stmia   r4!, {r2, r3, ip, lr}           @ 4
-       ldmia   r0!, {r2, r3, ip, lr}           @ 4+1
-       stmia   r4!, {r2, r3, ip, lr}           @ 4
-       ldmia   r0!, {r2, r3, ip, lr}           @ 4
-       mcr     p15, 0, r4, c7, c6, 1           @ 1   invalidate D line
-       stmia   r4!, {r2, r3, ip, lr}           @ 4
-       ldmia   r0!, {r2, r3, ip, lr}           @ 4
-       subs    r1, r1, #1                      @ 1
-       stmia   r4!, {r2, r3, ip, lr}           @ 4
-       ldmneia r0!, {r2, r3, ip, lr}           @ 4
-       bne     1b                              @ 1
-       ldmfd   sp!, {r4, pc}                   @ 3
-
-       .align  5
-/*
- * ARMv4 optimised clear_user_page
- *
- * Same story as above.
- */
-ENTRY(v4_mc_clear_user_page)
-       str     lr, [sp, #-4]!
-       mov     r1, #PAGE_SZ/64                 @ 1
-       mov     r2, #0                          @ 1
-       mov     r3, #0                          @ 1
-       mov     ip, #0                          @ 1
-       mov     lr, #0                          @ 1
-1:     mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line
-       stmia   r0!, {r2, r3, ip, lr}           @ 4
-       stmia   r0!, {r2, r3, ip, lr}           @ 4
-       mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line
-       stmia   r0!, {r2, r3, ip, lr}           @ 4
-       stmia   r0!, {r2, r3, ip, lr}           @ 4
-       subs    r1, r1, #1                      @ 1
-       bne     1b                              @ 1
-       ldr     pc, [sp], #4
-
-       __INITDATA
-
-       .type   v4_mc_user_fns, #object
-ENTRY(v4_mc_user_fns)
-       .long   v4_mc_clear_user_page
-       .long   v4_mc_copy_user_page
-       .size   v4_mc_user_fns, . - v4_mc_user_fns
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
new file mode 100644 (file)
index 0000000..fc69dcc
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *  linux/arch/arm/lib/copypage-armv4mc.S
+ *
+ *  Copyright (C) 1995-2005 Russell King
+ *
+ * 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 handles the mini data cache, as found on SA11x0 and XScale
+ * processors.  When we copy a user page page, we map it in such a way
+ * that accesses to this page will not touch the main data cache, but
+ * will be cached in the mini data cache.  This prevents us thrashing
+ * the main data cache on page faults.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+/*
+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
+ * specific hacks for copying pages efficiently.
+ */
+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
+                                 L_PTE_CACHEABLE)
+
+#define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
+
+static DEFINE_SPINLOCK(minicache_lock);
+
+/*
+ * ARMv4 mini-dcache optimised copy_user_page
+ *
+ * We flush the destination cache lines just before we write the data into the
+ * corresponding address.  Since the Dcache is read-allocate, this removes the
+ * Dcache aliasing issue.  The writes will be forwarded to the write buffer,
+ * and merged as appropriate.
+ *
+ * Note: We rely on all ARMv4 processors implementing the "invalidate D line"
+ * instruction.  If your processor does not supply this, you have to write your
+ * own copy_user_page that does the right thing.
+ */
+static void __attribute__((naked))
+mc_copy_user_page(void *from, void *to)
+{
+       asm volatile(
+       "stmfd  sp!, {r4, lr}                   @ 2\n\
+       mov     r4, %2                          @ 1\n\
+       ldmia   %0!, {r2, r3, ip, lr}           @ 4\n\
+1:     mcr     p15, 0, %1, c7, c6, 1           @ 1   invalidate D line\n\
+       stmia   %1!, {r2, r3, ip, lr}           @ 4\n\
+       ldmia   %0!, {r2, r3, ip, lr}           @ 4+1\n\
+       stmia   %1!, {r2, r3, ip, lr}           @ 4\n\
+       ldmia   %0!, {r2, r3, ip, lr}           @ 4\n\
+       mcr     p15, 0, %1, c7, c6, 1           @ 1   invalidate D line\n\
+       stmia   %1!, {r2, r3, ip, lr}           @ 4\n\
+       ldmia   %0!, {r2, r3, ip, lr}           @ 4\n\
+       subs    r4, r4, #1                      @ 1\n\
+       stmia   %1!, {r2, r3, ip, lr}           @ 4\n\
+       ldmneia %0!, {r2, r3, ip, lr}           @ 4\n\
+       bne     1b                              @ 1\n\
+       ldmfd   sp!, {r4, pc}                   @ 3"
+       :
+       : "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
+}
+
+void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
+{
+       spin_lock(&minicache_lock);
+
+       set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
+       flush_tlb_kernel_page(0xffff8000);
+
+       mc_copy_user_page((void *)0xffff8000, kto);
+
+       spin_unlock(&minicache_lock);
+}
+
+/*
+ * ARMv4 optimised clear_user_page
+ */
+void __attribute__((naked))
+v4_mc_clear_user_page(void *kaddr, unsigned long vaddr)
+{
+       asm volatile(
+       "str    lr, [sp, #-4]!\n\
+       mov     r1, %0                          @ 1\n\
+       mov     r2, #0                          @ 1\n\
+       mov     r3, #0                          @ 1\n\
+       mov     ip, #0                          @ 1\n\
+       mov     lr, #0                          @ 1\n\
+1:     mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line\n\
+       stmia   r0!, {r2, r3, ip, lr}           @ 4\n\
+       stmia   r0!, {r2, r3, ip, lr}           @ 4\n\
+       mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line\n\
+       stmia   r0!, {r2, r3, ip, lr}           @ 4\n\
+       stmia   r0!, {r2, r3, ip, lr}           @ 4\n\
+       subs    r1, r1, #1                      @ 1\n\
+       bne     1b                              @ 1\n\
+       ldr     pc, [sp], #4"
+       :
+       : "I" (PAGE_SIZE / 64));
+}
+
+struct cpu_user_fns v4_mc_user_fns __initdata = {
+       .cpu_clear_user_page    = v4_mc_clear_user_page, 
+       .cpu_copy_user_page     = v4_mc_copy_user_page,
+};
index 694ac8208858a9c54475f8f3173b71cca7787d4e..a8c00236bd3d54283da26f1fe36d3a0cc3d6c636 100644 (file)
@@ -26,8 +26,8 @@
 #define to_address     (0xffffc000)
 #define to_pgprot      PAGE_KERNEL
 
-static pte_t *from_pte;
-static pte_t *to_pte;
+#define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
+
 static DEFINE_SPINLOCK(v6_lock);
 
 #define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
@@ -74,8 +74,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
         */
        spin_lock(&v6_lock);
 
-       set_pte(from_pte + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
-       set_pte(to_pte + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
+       set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
+       set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
 
        from = from_address + (offset << PAGE_SHIFT);
        to   = to_address + (offset << PAGE_SHIFT);
@@ -114,7 +114,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
         */
        spin_lock(&v6_lock);
 
-       set_pte(to_pte + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
+       set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
        flush_tlb_kernel_page(to);
        clear_page((void *)to);
 
@@ -129,21 +129,6 @@ struct cpu_user_fns v6_user_fns __initdata = {
 static int __init v6_userpage_init(void)
 {
        if (cache_is_vipt_aliasing()) {
-               pgd_t *pgd;
-               pmd_t *pmd;
-
-               pgd = pgd_offset_k(from_address);
-               pmd = pmd_alloc(&init_mm, pgd, from_address);
-               if (!pmd)
-                       BUG();
-               from_pte = pte_alloc_kernel(&init_mm, pmd, from_address);
-               if (!from_pte)
-                       BUG();
-
-               to_pte = pte_alloc_kernel(&init_mm, pmd, to_address);
-               if (!to_pte)
-                       BUG();
-
                cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing;
                cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing;
        }
@@ -151,5 +136,4 @@ static int __init v6_userpage_init(void)
        return 0;
 }
 
-__initcall(v6_userpage_init);
-
+core_initcall(v6_userpage_init);
diff --git a/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S
deleted file mode 100644 (file)
index bb27731..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *  linux/arch/arm/lib/copypage-xscale.S
- *
- *  Copyright (C) 2001 Russell King
- *
- * 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/linkage.h>
-#include <linux/init.h>
-#include <asm/constants.h>
-
-/*
- * General note:
- *  We don't really want write-allocate cache behaviour for these functions
- *  since that will just eat through 8K of the cache.
- */
-
-       .text
-       .align  5
-/*
- * XScale optimised copy_user_page
- *  r0 = destination
- *  r1 = source
- *  r2 = virtual user address of ultimate destination page
- *
- * The source page may have some clean entries in the cache already, but we
- * can safely ignore them - break_cow() will flush them out of the cache
- * if we eventually end up using our copied page.
- *
- * What we could do is use the mini-cache to buffer reads from the source
- * page.  We rely on the mini-cache being smaller than one page, so we'll
- * cycle through the complete cache anyway.
- */
-ENTRY(xscale_mc_copy_user_page)
-       stmfd   sp!, {r4, r5, lr}
-       mov     r5, r0
-       mov     r0, r1
-       bl      map_page_minicache
-       mov     r1, r5
-       mov     lr, #PAGE_SZ/64-1
-
-       /*
-        * Strangely enough, best performance is achieved
-        * when prefetching destination as well.  (NP)
-        */
-       pld     [r0, #0]
-       pld     [r0, #32]
-       pld     [r1, #0]
-       pld     [r1, #32]
-
-1:     pld     [r0, #64]
-       pld     [r0, #96]
-       pld     [r1, #64]
-       pld     [r1, #96]
-
-2:     ldrd    r2, [r0], #8
-       ldrd    r4, [r0], #8
-       mov     ip, r1
-       strd    r2, [r1], #8
-       ldrd    r2, [r0], #8
-       strd    r4, [r1], #8
-       ldrd    r4, [r0], #8
-       strd    r2, [r1], #8
-       strd    r4, [r1], #8
-       mcr     p15, 0, ip, c7, c10, 1          @ clean D line
-       ldrd    r2, [r0], #8
-       mcr     p15, 0, ip, c7, c6, 1           @ invalidate D line
-       ldrd    r4, [r0], #8
-       mov     ip, r1
-       strd    r2, [r1], #8
-       ldrd    r2, [r0], #8
-       strd    r4, [r1], #8
-       ldrd    r4, [r0], #8
-       strd    r2, [r1], #8
-       strd    r4, [r1], #8
-       mcr     p15, 0, ip, c7, c10, 1          @ clean D line
-       subs    lr, lr, #1
-       mcr     p15, 0, ip, c7, c6, 1           @ invalidate D line
-       bgt     1b
-       beq     2b
-
-       ldmfd   sp!, {r4, r5, pc}
-
-       .align  5
-/*
- * XScale optimised clear_user_page
- *  r0 = destination
- *  r1 = virtual user address of ultimate destination page
- */
-ENTRY(xscale_mc_clear_user_page)
-       mov     r1, #PAGE_SZ/32
-       mov     r2, #0
-       mov     r3, #0
-1:     mov     ip, r0
-       strd    r2, [r0], #8
-       strd    r2, [r0], #8
-       strd    r2, [r0], #8
-       strd    r2, [r0], #8
-       mcr     p15, 0, ip, c7, c10, 1          @ clean D line
-       subs    r1, r1, #1
-       mcr     p15, 0, ip, c7, c6, 1           @ invalidate D line
-       bne     1b
-       mov     pc, lr
-
-       __INITDATA
-
-       .type   xscale_mc_user_fns, #object
-ENTRY(xscale_mc_user_fns)
-       .long   xscale_mc_clear_user_page
-       .long   xscale_mc_copy_user_page
-       .size   xscale_mc_user_fns, . - xscale_mc_user_fns
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
new file mode 100644 (file)
index 0000000..42a6ee2
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ *  linux/arch/arm/lib/copypage-xscale.S
+ *
+ *  Copyright (C) 1995-2005 Russell King
+ *
+ * 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 handles the mini data cache, as found on SA11x0 and XScale
+ * processors.  When we copy a user page page, we map it in such a way
+ * that accesses to this page will not touch the main data cache, but
+ * will be cached in the mini data cache.  This prevents us thrashing
+ * the main data cache on page faults.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+/*
+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
+ * specific hacks for copying pages efficiently.
+ */
+#define COPYPAGE_MINICACHE     0xffff8000
+
+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
+                                 L_PTE_CACHEABLE)
+
+#define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
+
+static DEFINE_SPINLOCK(minicache_lock);
+
+/*
+ * XScale mini-dcache optimised copy_user_page
+ *
+ * We flush the destination cache lines just before we write the data into the
+ * corresponding address.  Since the Dcache is read-allocate, this removes the
+ * Dcache aliasing issue.  The writes will be forwarded to the write buffer,
+ * and merged as appropriate.
+ */
+static void __attribute__((naked))
+mc_copy_user_page(void *from, void *to)
+{
+       /*
+        * Strangely enough, best performance is achieved
+        * when prefetching destination as well.  (NP)
+        */
+       asm volatile(
+       "stmfd  sp!, {r4, r5, lr}               \n\
+       mov     lr, %2                          \n\
+       pld     [r0, #0]                        \n\
+       pld     [r0, #32]                       \n\
+       pld     [r1, #0]                        \n\
+       pld     [r1, #32]                       \n\
+1:     pld     [r0, #64]                       \n\
+       pld     [r0, #96]                       \n\
+       pld     [r1, #64]                       \n\
+       pld     [r1, #96]                       \n\
+2:     ldrd    r2, [r0], #8                    \n\
+       ldrd    r4, [r0], #8                    \n\
+       mov     ip, r1                          \n\
+       strd    r2, [r1], #8                    \n\
+       ldrd    r2, [r0], #8                    \n\
+       strd    r4, [r1], #8                    \n\
+       ldrd    r4, [r0], #8                    \n\
+       strd    r2, [r1], #8                    \n\
+       strd    r4, [r1], #8                    \n\
+       mcr     p15, 0, ip, c7, c10, 1          @ clean D line\n\
+       ldrd    r2, [r0], #8                    \n\
+       mcr     p15, 0, ip, c7, c6, 1           @ invalidate D line\n\
+       ldrd    r4, [r0], #8                    \n\
+       mov     ip, r1                          \n\
+       strd    r2, [r1], #8                    \n\
+       ldrd    r2, [r0], #8                    \n\
+       strd    r4, [r1], #8                    \n\
+       ldrd    r4, [r0], #8                    \n\
+       strd    r2, [r1], #8                    \n\
+       strd    r4, [r1], #8                    \n\
+       mcr     p15, 0, ip, c7, c10, 1          @ clean D line\n\
+       subs    lr, lr, #1                      \n\
+       mcr     p15, 0, ip, c7, c6, 1           @ invalidate D line\n\
+       bgt     1b                              \n\
+       beq     2b                              \n\
+       ldmfd   sp!, {r4, r5, pc}               "
+       :
+       : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
+}
+
+void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
+{
+       spin_lock(&minicache_lock);
+
+       set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
+       flush_tlb_kernel_page(COPYPAGE_MINICACHE);
+
+       mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
+
+       spin_unlock(&minicache_lock);
+}
+
+/*
+ * XScale optimised clear_user_page
+ */
+void __attribute__((naked))
+xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr)
+{
+       asm volatile(
+       "mov    r1, %0                          \n\
+       mov     r2, #0                          \n\
+       mov     r3, #0                          \n\
+1:     mov     ip, r0                          \n\
+       strd    r2, [r0], #8                    \n\
+       strd    r2, [r0], #8                    \n\
+       strd    r2, [r0], #8                    \n\
+       strd    r2, [r0], #8                    \n\
+       mcr     p15, 0, ip, c7, c10, 1          @ clean D line\n\
+       subs    r1, r1, #1                      \n\
+       mcr     p15, 0, ip, c7, c6, 1           @ invalidate D line\n\
+       bne     1b                              \n\
+       mov     pc, lr"
+       :
+       : "I" (PAGE_SIZE / 32));
+}
+
+struct cpu_user_fns xscale_mc_user_fns __initdata = {
+       .cpu_clear_user_page    = xscale_mc_clear_user_page, 
+       .cpu_copy_user_page     = xscale_mc_copy_user_page,
+};
index c6de48d895032de8d615ee0f1ae8d8b31e13a716..4085ed983e46e07c3ac62ba31f8b0e605ee2594c 100644 (file)
 
 #include <asm/cacheflush.h>
 #include <asm/system.h>
+#include <asm/tlbflush.h>
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+#define ALIAS_FLUSH_START      0xffff4000
+
+#define TOP_PTE(x)     pte_offset_kernel(top_pmd, x)
+
+static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
+{
+       unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
+
+       set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));
+       flush_tlb_kernel_page(to);
+
+       asm(    "mcrr   p15, 0, %1, %0, c14\n"
+       "       mcrr    p15, 0, %1, %0, c5\n"
+           :
+           : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES)
+           : "cc");
+}
+#else
+#define flush_pfn_alias(pfn,vaddr)     do { } while (0)
+#endif
 
 static void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
@@ -36,6 +59,18 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
        if (!mapping)
                return;
 
+       /*
+        * This is a page cache page.  If we have a VIPT cache, we
+        * only need to do one flush - which would be at the relevant
+        * userspace colour, which is congruent with page->index.
+        */
+       if (cache_is_vipt()) {
+               if (cache_is_vipt_aliasing())
+                       flush_pfn_alias(page_to_pfn(page),
+                                       page->index << PAGE_CACHE_SHIFT);
+               return;
+       }
+
        /*
         * There are possible user space mappings of this page:
         * - VIVT cache: we need to also write back and invalidate all user
@@ -57,8 +92,6 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
                        continue;
                offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
                flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));
-               if (cache_is_vipt())
-                       break;
        }
        flush_dcache_mmap_unlock(mapping);
 }
diff --git a/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c
deleted file mode 100644 (file)
index dedf2ab..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *  linux/arch/arm/mm/minicache.c
- *
- *  Copyright (C) 2001 Russell King
- *
- * 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 handles the mini data cache, as found on SA11x0 and XScale
- * processors.  When we copy a user page page, we map it in such a way
- * that accesses to this page will not touch the main data cache, but
- * will be cached in the mini data cache.  This prevents us thrashing
- * the main data cache on page faults.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-
-/*
- * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
- * specific hacks for copying pages efficiently.
- */
-#define minicache_address (0xffff8000)
-#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
-                                 L_PTE_CACHEABLE)
-
-static pte_t *minicache_pte;
-
-/*
- * Note that this is intended to be called only from the copy_user_page
- * asm code; anything else will require special locking to prevent the
- * mini-cache space being re-used.  (Note: probably preempt unsafe).
- *
- * We rely on the fact that the minicache is 2K, and we'll be pushing
- * 4K of data through it, so we don't actually have to specifically
- * flush the minicache when we change the mapping.
- *
- * Note also: assert(PAGE_OFFSET <= virt < high_memory).
- * Unsafe: preempt, kmap.
- */
-unsigned long map_page_minicache(unsigned long virt)
-{
-       set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot));
-       flush_tlb_kernel_page(minicache_address);
-
-       return minicache_address;
-}
-
-static int __init minicache_init(void)
-{
-       pgd_t *pgd;
-       pmd_t *pmd;
-
-       spin_lock(&init_mm.page_table_lock);
-
-       pgd = pgd_offset_k(minicache_address);
-       pmd = pmd_alloc(&init_mm, pgd, minicache_address);
-       if (!pmd)
-               BUG();
-       minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address);
-       if (!minicache_pte)
-               BUG();
-
-       spin_unlock(&init_mm.page_table_lock);
-
-       return 0;
-}
-
-core_initcall(minicache_init);
index 585dfb8e20b96a7526b519d85afe8dc67226c562..2c2b93d77d433248dba64b6a1dd525eae51277fc 100644 (file)
@@ -37,6 +37,8 @@ pgprot_t pgprot_kernel;
 
 EXPORT_SYMBOL(pgprot_kernel);
 
+pmd_t *top_pmd;
+
 struct cachepolicy {
        const char      policy[16];
        unsigned int    cr_mask;
@@ -142,6 +144,16 @@ __setup("noalign", noalign_setup);
 
 #define FIRST_KERNEL_PGD_NR    (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
 
+static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
+{
+       return pmd_offset(pgd, virt);
+}
+
+static inline pmd_t *pmd_off_k(unsigned long virt)
+{
+       return pmd_off(pgd_offset_k(virt), virt);
+}
+
 /*
  * need to get a 16k page for level 1
  */
@@ -220,7 +232,7 @@ void free_pgd_slow(pgd_t *pgd)
                return;
 
        /* pgd is always present and good */
-       pmd = (pmd_t *)pgd;
+       pmd = pmd_off(pgd, 0);
        if (pmd_none(*pmd))
                goto free;
        if (pmd_bad(*pmd)) {
@@ -246,9 +258,8 @@ free:
 static inline void
 alloc_init_section(unsigned long virt, unsigned long phys, int prot)
 {
-       pmd_t *pmdp;
+       pmd_t *pmdp = pmd_off_k(virt);
 
-       pmdp = pmd_offset(pgd_offset_k(virt), virt);
        if (virt & (1 << 20))
                pmdp++;
 
@@ -283,11 +294,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
 static inline void
 alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
 {
-       pmd_t *pmdp;
+       pmd_t *pmdp = pmd_off_k(virt);
        pte_t *ptep;
 
-       pmdp = pmd_offset(pgd_offset_k(virt), virt);
-
        if (pmd_none(*pmdp)) {
                unsigned long pmdval;
                ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
@@ -310,7 +319,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
  */
 static inline void clear_mapping(unsigned long virt)
 {
-       pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
+       pmd_clear(pmd_off_k(virt));
 }
 
 struct mem_types {
@@ -578,7 +587,7 @@ void setup_mm_for_reboot(char mode)
                         PMD_TYPE_SECT;
                if (cpu_arch <= CPU_ARCH_ARMv5)
                        pmdval |= PMD_BIT4;
-               pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
+               pmd = pmd_off(pgd, i << PGDIR_SHIFT);
                pmd[0] = __pmd(pmdval);
                pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
                flush_pmd_entry(pmd);
@@ -675,6 +684,8 @@ void __init memtable_init(struct meminfo *mi)
 
        flush_cache_all();
        flush_tlb_all();
+
+       top_pmd = pmd_off_k(0xffff0000);
 }
 
 /*
index 3955de5af4c0a89accfa724fe288b81fd94bc64b..6caed90661fc8dcafbecdb6e15a92f95e142273d 100644 (file)
@@ -89,6 +89,10 @@ config PAGESIZE_16
           machine with 4MB of memory.
 endmenu
 
+config ISA_DMA_API
+       bool
+       default y
+
 menu "General setup"
 
 # Compressed boot loader in ROM.  Yes, we really want to ask about
index 134aec1c6d199d259a5207a2c0ea427bc487843a..b5f83e9f04db63eb1013267b65f94a891432e375 100644 (file)
@@ -54,7 +54,7 @@ asmlinkage void ret_from_fork(void);
 void default_idle(void)
 {
        while(1) {
-               if (need_resched()) {
+               if (!need_resched()) {
                        local_irq_enable();
                        __asm__("sleep");
                        local_irq_disable();
index 99b4f294a52d981fbc30aef0ec47348b0d5cd385..dfd904f6883b29820a19c5793240ac0e10103755 100644 (file)
@@ -183,7 +183,7 @@ config M386
          - "Winchip-C6" for original IDT Winchip.
          - "Winchip-2" for IDT Winchip 2.
          - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
-         - "MediaGX/Geode" for Cyrix MediaGX aka Geode.
+         - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
          - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
          - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
 
@@ -311,12 +311,10 @@ config MWINCHIP3D
          stores for this CPU, which can increase performance of some
          operations.
 
-config MGEODE
-       bool "MediaGX/Geode"
+config MGEODEGX1
+       bool "GeodeGX1"
        help
-         Select this for a Cyrix MediaGX aka Geode chip. Linux and GCC
-          treat this chip as a 586TSC with some extended instructions
-          and alignment reqirements.
+         Select this for a Geode GX1 (Cyrix MediaGX) chip.
 
 config MCYRIXIII
        bool "CyrixIII/VIA-C3"
@@ -368,7 +366,7 @@ config X86_L1_CACHE_SHIFT
        int
        default "7" if MPENTIUM4 || X86_GENERIC
        default "4" if X86_ELAN || M486 || M386
-       default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE
+       default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
        default "6" if MK7 || MK8 || MPENTIUMM
 
 config RWSEM_GENERIC_SPINLOCK
@@ -387,7 +385,7 @@ config GENERIC_CALIBRATE_DELAY
 
 config X86_PPRO_FENCE
        bool
-       depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODE
+       depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
        default y
 
 config X86_F00F_BUG
@@ -417,7 +415,7 @@ config X86_POPAD_OK
 
 config X86_ALIGNMENT_16
        bool
-       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODE
+       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
        default y
 
 config X86_GOOD_APIC
@@ -442,7 +440,7 @@ config X86_USE_3DNOW
 
 config X86_OOSTORE
        bool
-       depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MGEODE) && MTRR
+       depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
        default y
 
 config HPET_TIMER
@@ -578,7 +576,7 @@ config X86_VISWS_APIC
 
 config X86_TSC
        bool
-       depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODE) && !X86_NUMAQ
+       depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
        default y
 
 config X86_MCE
@@ -1165,7 +1163,7 @@ config PCI_DIRECT
 
 config PCI_MMCONFIG
        bool
-       depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI))
+       depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
        select ACPI_BOOT
        default y
 
@@ -1173,6 +1171,10 @@ source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
 
+config ISA_DMA_API
+       bool
+       default y
+
 config ISA
        bool "ISA support"
        depends on !(X86_VOYAGER || X86_VISWS)
index 04783ceb050c13d7a475a60bdb916b6eb56ffddf..1c36ca332a96df3bc408aa2433f64cb5f051e8df 100644 (file)
@@ -14,7 +14,7 @@
 # 19990713  Artur Skawina <skawina@geocities.com>
 #           Added '-march' and '-mpreferred-stack-boundary' support
 #
-#           Kianusch Sayah Karadji <kianusch@sk-tech.net>
+# 20050320  Kianusch Sayah Karadji <kianusch@sk-tech.net>
 #           Added support for GEODE CPU
 
 LDFLAGS                := -m elf_i386
@@ -54,8 +54,8 @@ cflags-$(CONFIG_MVIAC3_2)     += $(call cc-option,-march=c3-2,-march=i686)
 # AMD Elan support
 cflags-$(CONFIG_X86_ELAN)      += -march=i486
 
-# MediaGX aka Geode support
-cflags-$(CONFIG_MGEODE)                += $(call cc-option,-march=pentium-mmx,-march=i586)
+# Geode GX1 support
+cflags-$(CONFIG_MGEODEGX1)             += $(call cc-option,-march=pentium-mmx,-march=i486)
 
 # -mregparm=3 works ok on gcc-3.0 and later
 #
index ba9fe14db6a958a2b55d84416201c2388ac3a950..011b7a4993d40eb27ad99d811abf5e26a482a6ea 100644 (file)
@@ -83,7 +83,7 @@ bugger_off_msg:
        .ascii  "\n"
        .ascii  "Remove disk and press any key to reboot . . .\r\n"
        .byte   0
-       
+
 
        # Kernel attributes; used by setup
 
index 925d3f5a382422878ef08d0177e0dad5abd2e32c..0587477c99f2f32afa73a4dc10cf48e4ecb757d7 100644 (file)
@@ -1924,36 +1924,36 @@ skip10: movb    %ah, %al
        ret
 
 store_edid:
-       pushw   %es                             # just save all registers 
-       pushw   %ax                             
+       pushw   %es                             # just save all registers
+       pushw   %ax
        pushw   %bx
        pushw   %cx
        pushw   %dx
        pushw   %di
 
-       pushw   %fs                             
+       pushw   %fs
        popw    %es
 
        movl    $0x13131313, %eax               # memset block with 0x13
        movw    $32, %cx
        movw    $0x140, %di
        cld
-       rep 
-       stosl  
+       rep
+       stosl
 
-       movw    $0x4f15, %ax                    # do VBE/DDC 
+       movw    $0x4f15, %ax                    # do VBE/DDC
        movw    $0x01, %bx
        movw    $0x00, %cx
        movw    $0x01, %dx
        movw    $0x140, %di
-       int     $0x10   
+       int     $0x10
 
-       popw    %di                             # restore all registers        
+       popw    %di                             # restore all registers
        popw    %dx
        popw    %cx
        popw    %bx
        popw    %ax
-       popw    %es     
+       popw    %es
        ret
 
 # VIDEO_SELECT-only variables
index 0fbcfe00dd8d1514b33bd6aeff1b6cc01eebb4ac..51ecd512603da25153cbf194dcda57d724a8edd8 100644 (file)
@@ -43,7 +43,7 @@ obj-$(CONFIG_SCx200)          += scx200.o
 # Note: kbuild does not track this dependency due to usage of .incbin
 $(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
 targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
-targets += vsyscall.lds
+targets += vsyscall-note.o vsyscall.lds
 
 # The DSO images are built using a special linker script.
 quiet_cmd_syscall = SYSCALL $@
index 53eb5cfd5b630b614952ba31a08e384abb8a2f1a..848bb97af7ca316755f6e47e612ecc75717fb197 100644 (file)
@@ -650,7 +650,7 @@ acpi_find_rsdp (void)
         */
        rsdp_phys = acpi_scan_rsdp (0, 0x400);
        if (!rsdp_phys)
-               rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF);
+               rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000);
 
        return rsdp_phys;
 }
index 45641a87255009968c6882b4d04fcd4dbf52df90..0ff65abcd56c3c1139b4849a80228f555785c655 100644 (file)
@@ -1222,6 +1222,7 @@ static int suspend(int vetoable)
 
        save_processor_state();
        err = set_system_power_state(APM_STATE_SUSPEND);
+       ignore_normal_resume = 1;
        restore_processor_state();
 
        local_irq_disable();
@@ -1229,7 +1230,6 @@ static int suspend(int vetoable)
        spin_lock(&i8253_lock);
        reinit_timer();
        set_time();
-       ignore_normal_resume = 1;
 
        spin_unlock(&i8253_lock);
        write_sequnlock(&xtime_lock);
index 16dbc4151be43b8e671869b2a52220f47ec0b6ac..73aeaf5a9d4e493f7e2be65ac67a285d966e062c 100644 (file)
@@ -24,9 +24,6 @@ __asm__(".align 4\nvide: ret");
 
 static void __init init_amd(struct cpuinfo_x86 *c)
 {
-#ifdef CONFIG_X86_SMP
-       int cpu = c == &boot_cpu_data ? 0 : c - cpu_data;
-#endif
        u32 l, h;
        int mbytes = num_physpages >> (20-PAGE_SHIFT);
        int r;
@@ -198,14 +195,19 @@ static void __init init_amd(struct cpuinfo_x86 *c)
                        c->x86_num_cores = 1;
        }
 
-#ifdef CONFIG_X86_SMP
+#ifdef CONFIG_X86_HT
        /*
         * On a AMD dual core setup the lower bits of the APIC id
         * distingush the cores.  Assumes number of cores is a power
         * of two.
         */
        if (c->x86_num_cores > 1) {
-               cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
+               int cpu = smp_processor_id();
+               unsigned bits = 0;
+               while ((1 << bits) < c->x86_num_cores)
+                       bits++;
+               cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
+               phys_proc_id[cpu] >>= bits;
                printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
                       cpu, c->x86_num_cores, cpu_core_id[cpu]);
        }
index 6be0310e3cd3a15fc70bcf4782228cf73d7e161a..d199e525680aeabb7e6d5fc88ce895a217d92a1e 100644 (file)
@@ -243,6 +243,10 @@ static void __init early_cpu_detect(void)
        }
 
        early_intel_workaround(c);
+
+#ifdef CONFIG_X86_HT
+       phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
+#endif
 }
 
 void __init generic_identify(struct cpuinfo_x86 * c)
index f25ffd74235caa330985b4cbaa6d5ece01b78b67..0f1eb507233b701c6bb7b158104e0e5cfd9e4d85 100644 (file)
@@ -23,7 +23,7 @@ config X86_ACPI_CPUFREQ
          If in doubt, say N.
 
 config ELAN_CPUFREQ
-       tristate "AMD Elan"
+       tristate "AMD Elan SC400 and SC410"
        select CPU_FREQ_TABLE
        depends on X86_ELAN
        ---help---
@@ -38,6 +38,18 @@ config ELAN_CPUFREQ
 
          If in doubt, say N.
 
+config SC520_CPUFREQ
+       tristate "AMD Elan SC520"
+       select CPU_FREQ_TABLE
+       depends on X86_ELAN
+       ---help---
+         This adds the CPUFreq driver for AMD Elan SC520 processor.
+
+         For details, take a look at <file:Documentation/cpu-freq/>.
+
+         If in doubt, say N.
+
+
 config X86_POWERNOW_K6
        tristate "AMD Mobile K6-2/K6-3 PowerNow!"
        select CPU_FREQ_TABLE
index a922e97aeedd5ee7283441a72e613504ef566086..2e894f1c89103f69f51e9c7da8748060d3019790 100644 (file)
@@ -3,6 +3,7 @@ obj-$(CONFIG_X86_POWERNOW_K7)           += powernow-k7.o
 obj-$(CONFIG_X86_POWERNOW_K8)          += powernow-k8.o
 obj-$(CONFIG_X86_LONGHAUL)             += longhaul.o
 obj-$(CONFIG_ELAN_CPUFREQ)             += elanfreq.o
+obj-$(CONFIG_SC520_CPUFREQ)            += sc520_freq.o
 obj-$(CONFIG_X86_LONGRUN)              += longrun.o  
 obj-$(CONFIG_X86_GX_SUSPMOD)           += gx-suspmod.o
 obj-$(CONFIG_X86_SPEEDSTEP_ICH)                += speedstep-ich.o
index ab0f9f5aac1168075b02b36cf2fdeda1dc23cf2f..04e3563da4fea19e2a7f0c2c0e0053855cda67f1 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/pci.h>
 
 #include <asm/msr.h>
 #include <asm/timex.h>
@@ -119,7 +120,13 @@ static int longhaul_get_cpu_mult(void)
 static void do_powersaver(union msr_longhaul *longhaul,
                        unsigned int clock_ratio_index)
 {
+       struct pci_dev *dev;
+       unsigned long flags;
+       unsigned int tmp_mask;
        int version;
+       int i;
+       u16 pci_cmd;
+       u16 cmd_state[64];
 
        switch (cpu_model) {
        case CPU_EZRA_T:
@@ -137,17 +144,58 @@ static void do_powersaver(union msr_longhaul *longhaul,
        longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
        longhaul->bits.EnableSoftBusRatio = 1;
        longhaul->bits.RevisionKey = 0;
-       local_irq_disable();
-       wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
+
+       preempt_disable();
+       local_irq_save(flags);
+
+       /*
+        * get current pci bus master state for all devices
+        * and clear bus master bit
+        */
+       dev = NULL;
+       i = 0;
+       do {
+               dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
+               if (dev != NULL) {
+                       pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+                       cmd_state[i++] = pci_cmd;
+                       pci_cmd &= ~PCI_COMMAND_MASTER;
+                       pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+               }
+       } while (dev != NULL);
+
+       tmp_mask=inb(0x21);     /* works on C3. save mask. */
+       outb(0xFE,0x21);        /* TMR0 only */
+       outb(0xFF,0x80);        /* delay */
+
        local_irq_enable();
+
+       __hlt();
+       wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
        __hlt();
 
+       local_irq_disable();
+
+       outb(tmp_mask,0x21);    /* restore mask */
+
+       /* restore pci bus master state for all devices */
+       dev = NULL;
+       i = 0;
+       do {
+               dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
+               if (dev != NULL) {
+                       pci_cmd = cmd_state[i++];
+                       pci_write_config_byte(dev, PCI_COMMAND, pci_cmd);
+               }
+       } while (dev != NULL);
+       local_irq_restore(flags);
+       preempt_enable();
+
+       /* disable bus ratio bit */
        rdmsrl(MSR_VIA_LONGHAUL, longhaul->val);
        longhaul->bits.EnableSoftBusRatio = 0;
        longhaul->bits.RevisionKey = version;
-       local_irq_disable();
        wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
-       local_irq_enable();
 }
 
 /**
@@ -578,7 +626,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
                longhaul_setup_voltagescaling();
 
        policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-       policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+       policy->cpuinfo.transition_latency = 200000;    /* nsec */
        policy->cur = calc_speed(longhaul_get_cpu_mult());
 
        ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
index 913f652623d91f780d0c4a5492f57c6e3afebaee..5c530064eb74bf963a8f43ea4265b96d6042ac65 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/dmi.h>
 
 #include <asm/msr.h>
+#include <asm/timer.h>
 #include <asm/timex.h>
 #include <asm/io.h>
 #include <asm/system.h>
@@ -586,13 +587,17 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
 
        rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 
-       /* A K7 with powernow technology is set to max frequency by BIOS */
-       fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID];
+       /* recalibrate cpu_khz */
+       result = recalibrate_cpu_khz();
+       if (result)
+               return result;
+
+       fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
        if (!fsb) {
                printk(KERN_WARNING PFX "can not determine bus frequency\n");
                return -EINVAL;
        }
-       dprintk("FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000);
+       dprintk("FSB: %3dMHz\n", fsb/1000);
 
        if (dmi_check_system(powernow_dmi_table) || acpi_force) {
                printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
index a65ff7e32e5d09417279a06de1db0f003c77671a..10cc096c0adead9961f48bd79a865f317ce8f27a 100644 (file)
@@ -4,7 +4,7 @@
  *  GNU general public license version 2. See "COPYING" or
  *  http://www.gnu.org/licenses/gpl.html
  *
- *  Support : paul.devriendt@amd.com
+ *  Support : mark.langsdorf@amd.com
  *
  *  Based on the powernow-k7.c module written by Dave Jones.
  *  (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs
  *
  *  Valuable input gratefully received from Dave Jones, Pavel Machek,
  *  Dominik Brodowski, and others.
+ *  Originally developed by Paul Devriendt.
  *  Processor information obtained from Chapter 9 (Power and Thermal Management)
  *  of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
  *  Opteron Processors" available for download from www.amd.com
  *
  *  Tables for specific CPUs can be infrerred from
- *     http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
+ *     http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
  */
 
 #include <linux/kernel.h>
@@ -30,6 +31,7 @@
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/cpumask.h>
 
 #include <asm/msr.h>
 #include <asm/io.h>
@@ -42,7 +44,7 @@
 
 #define PFX "powernow-k8: "
 #define BFX PFX "BIOS error: "
-#define VERSION "version 1.00.09e"
+#define VERSION "version 1.40.2"
 #include "powernow-k8.h"
 
 /* serialize freq changes  */
@@ -50,6 +52,10 @@ static DECLARE_MUTEX(fidvid_sem);
 
 static struct powernow_k8_data *powernow_data[NR_CPUS];
 
+#ifndef CONFIG_SMP
+static cpumask_t cpu_core_map[1];
+#endif
+
 /* Return a frequency in MHz, given an input fid */
 static u32 find_freq_from_fid(u32 fid)
 {
@@ -274,11 +280,18 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
 {
        u32 rvosteps = data->rvo;
        u32 savefid = data->currfid;
+       u32 maxvid, lo;
 
        dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n",
                smp_processor_id(),
                data->currfid, data->currvid, reqvid, data->rvo);
 
+       rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
+       maxvid = 0x1f & (maxvid >> 16);
+       dprintk("ph1 maxvid=0x%x\n", maxvid);
+       if (reqvid < maxvid) /* lower numbers are higher voltages */
+               reqvid = maxvid;
+
        while (data->currvid > reqvid) {
                dprintk("ph1: curr 0x%x, req vid 0x%x\n",
                        data->currvid, reqvid);
@@ -286,8 +299,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
                        return 1;
        }
 
-       while ((rvosteps > 0)  && ((data->rvo + data->currvid) > reqvid)) {
-               if (data->currvid == 0) {
+       while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) {
+               if (data->currvid == maxvid) {
                        rvosteps = 0;
                } else {
                        dprintk("ph1: changing vid for rvo, req 0x%x\n",
@@ -671,7 +684,7 @@ static int find_psb_table(struct powernow_k8_data *data)
         * BIOS and Kernel Developer's Guide, which is available on
         * www.amd.com
         */
-       printk(KERN_ERR PFX "BIOS error - no PSB\n");
+       printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n");
        return -ENODEV;
 }
 
@@ -695,7 +708,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
        struct cpufreq_frequency_table *powernow_table;
 
        if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
-               dprintk("register performance failed\n");
+               dprintk("register performance failed: bad ACPI data\n");
                return -EIO;
        }
 
@@ -746,22 +759,23 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
                        continue;
                }
 
-               if (fid < HI_FID_TABLE_BOTTOM) {
-                       if (cntlofreq) {
-                               /* if both entries are the same, ignore this
-                                * one... 
-                                */
-                               if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
-                                   (powernow_table[i].index != powernow_table[cntlofreq].index)) {
-                                       printk(KERN_ERR PFX "Too many lo freq table entries\n");
-                                       goto err_out_mem;
-                               }
-                               
-                               dprintk("double low frequency table entry, ignoring it.\n");
-                               powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
-                               continue;
-                       } else
-                               cntlofreq = i;
+               /* verify only 1 entry from the lo frequency table */
+               if (fid < HI_FID_TABLE_BOTTOM) {
+                       if (cntlofreq) {
+                               /* if both entries are the same, ignore this
+                                * one... 
+                                */
+                               if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
+                                   (powernow_table[i].index != powernow_table[cntlofreq].index)) {
+                                       printk(KERN_ERR PFX "Too many lo freq table entries\n");
+                                       goto err_out_mem;
+                               }
+
+                               dprintk("double low frequency table entry, ignoring it.\n");
+                               powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+                               continue;
+                       } else
+                               cntlofreq = i;
                }
 
                if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
@@ -816,7 +830,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
 {
        u32 fid;
        u32 vid;
-       int res;
+       int res, i;
        struct cpufreq_freqs freqs;
 
        dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
@@ -841,7 +855,8 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
        }
 
        if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
-               printk("ignoring illegal change in lo freq table-%x to 0x%x\n",
+               printk(KERN_ERR PFX
+                      "ignoring illegal change in lo freq table-%x to 0x%x\n",
                       data->currfid, fid);
                return 1;
        }
@@ -850,18 +865,20 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
                smp_processor_id(), fid, vid);
 
        freqs.cpu = data->cpu;
-
        freqs.old = find_khz_freq_from_fid(data->currfid);
        freqs.new = find_khz_freq_from_fid(fid);
-       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       for_each_cpu_mask(i, cpu_core_map[data->cpu]) {
+               freqs.cpu = i;
+               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       }
 
-       down(&fidvid_sem);
        res = transition_fid_vid(data, fid, vid);
-       up(&fidvid_sem);
 
        freqs.new = find_khz_freq_from_fid(data->currfid);
-       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
+       for_each_cpu_mask(i, cpu_core_map[data->cpu]) {
+               freqs.cpu = i;
+               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+        }
        return res;
 }
 
@@ -874,6 +891,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
        u32 checkvid = data->currvid;
        unsigned int newstate;
        int ret = -EIO;
+       int i;
 
        /* only run on specific CPU from here on */
        oldmask = current->cpus_allowed;
@@ -902,22 +920,41 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
                data->currfid, data->currvid);
 
        if ((checkvid != data->currvid) || (checkfid != data->currfid)) {
-               printk(KERN_ERR PFX
-                      "error - out of sync, fid 0x%x 0x%x, vid 0x%x 0x%x\n",
-                      checkfid, data->currfid, checkvid, data->currvid);
+               printk(KERN_INFO PFX
+                       "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
+                       checkfid, data->currfid, checkvid, data->currvid);
        }
 
        if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate))
                goto err_out;
 
+       down(&fidvid_sem);
+
+       for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
+               /* make sure the sibling is initialized */
+               if (!powernow_data[i]) {
+                        ret = 0;
+                        up(&fidvid_sem);
+                        goto err_out;
+                }
+       }
+
        powernow_k8_acpi_pst_values(data, newstate);
 
        if (transition_frequency(data, newstate)) {
                printk(KERN_ERR PFX "transition frequency failed\n");
                ret = 1;
+               up(&fidvid_sem);
                goto err_out;
        }
 
+       /* Update all the fid/vids of our siblings */
+       for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
+               powernow_data[i]->currvid = data->currvid;
+               powernow_data[i]->currfid = data->currfid;
+       }       
+       up(&fidvid_sem);
+
        pol->cur = find_khz_freq_from_fid(data->currfid);
        ret = 0;
 
@@ -962,7 +999,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
                 */
 
                if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) {
-                       printk(KERN_INFO PFX "MP systems not supported by PSB BIOS structure\n");
+                       printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n");
                        kfree(data);
                        return -ENODEV;
                }
@@ -1003,6 +1040,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
        schedule();
 
        pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
+       pol->cpus = cpu_core_map[pol->cpu];
 
        /* Take a crude guess here. 
         * That guess was in microseconds, so multiply with 1000 */
@@ -1069,7 +1107,7 @@ static unsigned int powernowk8_get (unsigned int cpu)
                return 0;
        }
        preempt_disable();
-
+       
        if (query_current_values_with_pending_wait(data))
                goto out;
 
@@ -1127,9 +1165,10 @@ static void __exit powernowk8_exit(void)
        cpufreq_unregister_driver(&cpufreq_amd64_driver);
 }
 
-MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com>");
+MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com.");
 MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
 MODULE_LICENSE("GPL");
 
 late_initcall(powernowk8_init);
 module_exit(powernowk8_exit);
+
index 63ebc8470f5249e29b64731851a0fcf932e13629..9ed5bf221cb7971fc365de5cde7c50d53024f08d 100644 (file)
@@ -174,3 +174,18 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
 
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
+
+#ifndef for_each_cpu_mask
+#define for_each_cpu_mask(i,mask) for (i=0;i<1;i++)
+#endif
+                                                                                
+#ifdef CONFIG_SMP
+static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
+{
+}
+#else
+static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
+{
+       cpu_set(0, cpu_sharedcore_mask[0]);
+}
+#endif
diff --git a/arch/i386/kernel/cpu/cpufreq/sc520_freq.c b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c
new file mode 100644 (file)
index 0000000..ef457d5
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ *     sc520_freq.c: cpufreq driver for the AMD Elan sc520
+ *
+ *     Copyright (C) 2005 Sean Young <sean@mess.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.
+ *
+ *     Based on elanfreq.c
+ *
+ *     2005-03-30: - initial revision
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/delay.h>
+#include <linux/cpufreq.h>
+
+#include <asm/msr.h>
+#include <asm/timex.h>
+#include <asm/io.h>
+
+#define MMCR_BASE      0xfffef000      /* The default base address */
+#define OFFS_CPUCTL    0x2   /* CPU Control Register */
+
+static __u8 __iomem *cpuctl;
+
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg)
+
+static struct cpufreq_frequency_table sc520_freq_table[] = {
+       {0x01,  100000},
+       {0x02,  133000},
+       {0,     CPUFREQ_TABLE_END},
+};
+
+static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
+{
+       u8 clockspeed_reg = *cpuctl;
+
+       switch (clockspeed_reg & 0x03) {
+       default:
+               printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg);
+       case 0x01:
+               return 100000;
+       case 0x02:
+               return 133000;
+       }
+}
+
+static void sc520_freq_set_cpu_state (unsigned int state)
+{
+
+       struct cpufreq_freqs    freqs;
+       u8 clockspeed_reg;
+
+       freqs.old = sc520_freq_get_cpu_frequency(0);
+       freqs.new = sc520_freq_table[state].frequency;
+       freqs.cpu = 0; /* AMD Elan is UP */
+
+       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+       dprintk("attempting to set frequency to %i kHz\n",
+                       sc520_freq_table[state].frequency);
+
+       local_irq_disable();
+
+       clockspeed_reg = *cpuctl & ~0x03;
+       *cpuctl = clockspeed_reg | sc520_freq_table[state].index;
+
+       local_irq_enable();
+
+       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+};
+
+static int sc520_freq_verify (struct cpufreq_policy *policy)
+{
+       return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]);
+}
+
+static int sc520_freq_target (struct cpufreq_policy *policy,
+                           unsigned int target_freq,
+                           unsigned int relation)
+{
+       unsigned int newstate = 0;
+
+       if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate))
+               return -EINVAL;
+
+       sc520_freq_set_cpu_state(newstate);
+
+       return 0;
+}
+
+
+/*
+ *     Module init and exit code
+ */
+
+static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
+{
+       struct cpuinfo_x86 *c = cpu_data;
+       int result;
+
+       /* capability check */
+       if (c->x86_vendor != X86_VENDOR_AMD ||
+           c->x86 != 4 || c->x86_model != 9)
+               return -ENODEV;
+
+       /* cpuinfo and default policy values */
+       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+       policy->cpuinfo.transition_latency = 1000000; /* 1ms */
+       policy->cur = sc520_freq_get_cpu_frequency(0);
+
+       result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table);
+       if (result)
+               return (result);
+
+       cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu);
+
+       return 0;
+}
+
+
+static int sc520_freq_cpu_exit(struct cpufreq_policy *policy)
+{
+       cpufreq_frequency_table_put_attr(policy->cpu);
+       return 0;
+}
+
+
+static struct freq_attr* sc520_freq_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
+       NULL,
+};
+
+
+static struct cpufreq_driver sc520_freq_driver = {
+       .get    = sc520_freq_get_cpu_frequency,
+       .verify = sc520_freq_verify,
+       .target = sc520_freq_target,
+       .init   = sc520_freq_cpu_init,
+       .exit   = sc520_freq_cpu_exit,
+       .name   = "sc520_freq",
+       .owner  = THIS_MODULE,
+       .attr   = sc520_freq_attr,
+};
+
+
+static int __init sc520_freq_init(void)
+{
+       struct cpuinfo_x86 *c = cpu_data;
+
+       /* Test if we have the right hardware */
+       if(c->x86_vendor != X86_VENDOR_AMD ||
+                               c->x86 != 4 || c->x86_model != 9) {
+               dprintk("no Elan SC520 processor found!\n");
+               return -ENODEV;
+       }
+       cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
+       if(!cpuctl) {
+               printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
+               return -ENOMEM;
+       }
+
+       return cpufreq_register_driver(&sc520_freq_driver);
+}
+
+
+static void __exit sc520_freq_exit(void)
+{
+       cpufreq_unregister_driver(&sc520_freq_driver);
+       iounmap(cpuctl);
+}
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sean Young <sean@mess.org>");
+MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU");
+
+module_init(sc520_freq_init);
+module_exit(sc520_freq_exit);
+
index 07d5612dc00f4f534e8926f669ca45bae2995609..7dcbf70fc16f52afaaf355aa1f4f1c7aae0ca1d5 100644 (file)
@@ -54,6 +54,8 @@ enum {
        CPU_DOTHAN_A1,
        CPU_DOTHAN_A2,
        CPU_DOTHAN_B0,
+       CPU_MP4HT_D0,
+       CPU_MP4HT_E0,
 };
 
 static const struct cpu_id cpu_ids[] = {
@@ -61,6 +63,8 @@ static const struct cpu_id cpu_ids[] = {
        [CPU_DOTHAN_A1] = { 6, 13, 1 },
        [CPU_DOTHAN_A2] = { 6, 13, 2 },
        [CPU_DOTHAN_B0] = { 6, 13, 6 },
+       [CPU_MP4HT_D0]  = {15,  3, 4 },
+       [CPU_MP4HT_E0]  = {15,  4, 1 },
 };
 #define N_IDS  (sizeof(cpu_ids)/sizeof(cpu_ids[0]))
 
@@ -226,6 +230,8 @@ static struct cpu_model models[] =
        { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
        { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
        { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
+       { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
+       { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
 
        { NULL, }
 };
index 8ba430a9c3a21a0db5d6522128d5e5e6b2406c0c..d368b3f5fce85397e9e139eb4f5b0314ac15c178 100644 (file)
@@ -336,7 +336,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
        if (!prev_speed)
                return -EIO;
 
-       dprintk("previous seped is %u\n", prev_speed);
+       dprintk("previous speed is %u\n", prev_speed);
        
        local_irq_save(flags);
 
@@ -348,7 +348,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
                goto out;
        }
 
-       dprintk("low seped is %u\n", *low_speed);
+       dprintk("low speed is %u\n", *low_speed);
 
        /* switch to high state */
        set_state(SPEEDSTEP_HIGH);
@@ -358,7 +358,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
                goto out;
        }
 
-       dprintk("high seped is %u\n", *high_speed);
+       dprintk("high speed is %u\n", *high_speed);
 
        if (*low_speed == *high_speed) {
                ret = -ENODEV;
index 79440b3f087ec9beeca123de97b9da6b572bd171..b25fb6b635ae85e8595454e7c304a864d10c353c 100644 (file)
@@ -357,6 +357,9 @@ static int __init speedstep_init(void)
        case SPEEDSTEP_PROCESSOR_PIII_C:
        case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
                break;
+       case SPEEDSTEP_PROCESSOR_P4M:
+               printk(KERN_INFO "speedstep-smi: you're trying to use this cpufreq driver on a Pentium 4-based CPU. Most likely it will not work.\n");
+               break;
        default:
                speedstep_processor = 0;
        }
index aeb5b4ef8c8b52e095159551bcaaaded2442aaee..a710dc4eb20e33354cc446f6a74549f0e6a6e895 100644 (file)
@@ -118,7 +118,7 @@ struct _cpuid4_info {
 };
 
 #define MAX_CACHE_LEAVES               4
-static unsigned short __devinitdata    num_cache_leaves;
+static unsigned short                  num_cache_leaves;
 
 static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
 {
index 933b0dd62f485524658bb4f1f813c9af2ec4b30a..9027a987006b93890f17363f2d4fac4c749e7f23 100644 (file)
@@ -218,12 +218,12 @@ typedef struct {
        mtrr_type type;
 } arr_state_t;
 
-static arr_state_t arr_state[8] __initdata = {
+static arr_state_t arr_state[8] __devinitdata = {
        {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL},
        {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}
 };
 
-static unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char ccr_state[7] __devinitdata = { 0, 0, 0, 0, 0, 0, 0 };
 
 static void cyrix_set_all(void)
 {
index 14ec354bec926be79ed9b11a13a9b664aa3ef51a..903190a4b3ffbb10f0ccd52ca8c01829fb0d7eeb 100644 (file)
@@ -169,10 +169,6 @@ EXPORT_SYMBOL(rtc_lock);
 EXPORT_SYMBOL_GPL(set_nmi_callback);
 EXPORT_SYMBOL_GPL(unset_nmi_callback);
 
-#undef memcmp
-extern int memcmp(const void *,const void *,__kernel_size_t);
-EXPORT_SYMBOL(memcmp);
-
 EXPORT_SYMBOL(register_die_notifier);
 #ifdef CONFIG_HAVE_DEC_LOCK
 EXPORT_SYMBOL(_atomic_dec_and_lock);
index 67168165924346b68d53a3cd8fe6a8dcd4ea0844..59ff9b45506915270a0ac8671dcf2d8eae410ff0 100644 (file)
@@ -217,6 +217,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
                *tos &= ~(TF_MASK | IF_MASK);
                *tos |= kprobe_old_eflags;
                break;
+       case 0xc3:              /* ret/lret */
+       case 0xcb:
+       case 0xc2:
+       case 0xca:
+               regs->eflags &= ~TF_MASK;
+               /* eip is already adjusted, no more changes required*/
+               return;
        case 0xe8:              /* call relative - Fix return addr */
                *tos = orig_eip + (*tos - copy_eip);
                break;
index 85bd56d4431417836a1b6c3992d57bf36e9186ca..96e3ea6b17c7b989c1bafb3c1ce87f7768348693 100644 (file)
@@ -400,11 +400,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
        int err;
 
        childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
-       *childregs = *regs;
-       childregs->eax = 0;
-       childregs->esp = esp;
-
-       p->thread.esp = (unsigned long) childregs;
        /*
         * The below -8 is to reserve 8 bytes on top of the ring0 stack.
         * This is necessary to guarantee that the entire "struct pt_regs"
@@ -415,7 +410,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
         * "struct pt_regs" is possible, but they may contain the
         * completely wrong values.
         */
-       p->thread.esp0 = (unsigned long) (childregs+1) - 8;
+       childregs = (struct pt_regs *) ((unsigned long) childregs - 8);
+       *childregs = *regs;
+       childregs->eax = 0;
+       childregs->esp = esp;
+
+       p->thread.esp = (unsigned long) childregs;
+       p->thread.esp0 = (unsigned long) (childregs+1);
 
        p->thread.eip = (unsigned long) ret_from_fork;
 
index e8c965ce86eb2ddcc824c8c13d6988a426cb374b..e34f651fa13c001de7b84967c0882d71bda35c1e 100644 (file)
@@ -683,24 +683,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
        /* do the secure computing check first */
        secure_computing(regs->orig_eax);
 
-       if (unlikely(current->audit_context)) {
-               if (!entryexit)
-                       audit_syscall_entry(current, regs->orig_eax,
-                                           regs->ebx, regs->ecx,
-                                           regs->edx, regs->esi);
-               else
-                       audit_syscall_exit(current, regs->eax);
-       }
+       if (unlikely(current->audit_context) && entryexit)
+               audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
 
        if (!(current->ptrace & PT_PTRACED))
-               return;
+               goto out;
 
        /* Fake a debug trap */
        if (test_thread_flag(TIF_SINGLESTEP))
                send_sigtrap(current, regs, 0);
 
        if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               return;
+               goto out;
 
        /* the 0x80 provides a way for the tracing parent to distinguish
           between a syscall stop and SIGTRAP delivery */
@@ -715,4 +709,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
                send_sig(current->exit_code, current, 1);
                current->exit_code = 0;
        }
+ out:
+       if (unlikely(current->audit_context) && !entryexit)
+               audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
+                                   regs->ebx, regs->ecx, regs->edx, regs->esi);
+
 }
index 945ec73163c8c7ed1ff3297fe4530d4316293e6e..2bfbddebdbf80b65642f47663dba8f5042876a05 100644 (file)
@@ -1502,11 +1502,13 @@ void __init setup_arch(char **cmdline_p)
        if (efi_enabled)
                efi_map_memmap();
 
+#ifdef CONFIG_ACPI_BOOT
        /*
         * Parse the ACPI tables for possible boot-time SMP configuration.
         */
        acpi_boot_table_init();
        acpi_boot_init();
+#endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
        if (smp_found_config)
index cbea7ac582e57a09fe919e4cc444c53a6a525ba4..bc1bb6919e6ae68e56d0f2dea2b963cd7f99410d 100644 (file)
@@ -888,6 +888,7 @@ void *xquad_portio;
 
 cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
 cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_core_map);
 
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
@@ -1073,8 +1074,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                        cpu_set(cpu, cpu_sibling_map[cpu]);
                }
 
-               if (siblings != smp_num_siblings)
+               if (siblings != smp_num_siblings) {
                        printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
+                       smp_num_siblings = siblings;
+               }
 
                if (c->x86_num_cores > 1) {
                        for (i = 0; i < NR_CPUS; i++) {
index f7f90005e22e352ffedf7a19347ae0da92fe728b..8e201219f5253f53a84d1254b922ab7a7ff1a519 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/timex.h>
 #include <linux/errno.h>
 #include <linux/jiffies.h>
+#include <linux/module.h>
 
 #include <asm/io.h>
 #include <asm/timer.h>
@@ -24,7 +25,7 @@
 
 #define CALIBRATE_TIME (5 * 1000020/HZ)
 
-unsigned long __init calibrate_tsc(void)
+unsigned long calibrate_tsc(void)
 {
        mach_prepare_counter();
 
@@ -139,7 +140,7 @@ bad_calibration:
 #endif
 
 /* calculate cpu_khz */
-void __init init_cpu_khz(void)
+void init_cpu_khz(void)
 {
        if (cpu_has_tsc) {
                unsigned long tsc_quotient = calibrate_tsc();
@@ -158,3 +159,4 @@ void __init init_cpu_khz(void)
                }
        }
 }
+
index 7926d967be00ddf89718a4c43c4e866b17f09cfc..180444d87824e4299979a68b8f726da94ec50725 100644 (file)
@@ -320,6 +320,26 @@ core_initcall(cpufreq_tsc);
 static inline void cpufreq_delayed_get(void) { return; }
 #endif 
 
+int recalibrate_cpu_khz(void)
+{
+#ifndef CONFIG_SMP
+       unsigned long cpu_khz_old = cpu_khz;
+
+       if (cpu_has_tsc) {
+               init_cpu_khz();
+               cpu_data[0].loops_per_jiffy =
+                   cpufreq_scale(cpu_data[0].loops_per_jiffy,
+                                 cpu_khz_old,
+                                 cpu_khz);
+               return 0;
+       } else
+               return -ENODEV;
+#else
+       return -ENODEV;
+#endif
+}
+EXPORT_SYMBOL(recalibrate_cpu_khz);
+
 static void mark_offset_tsc(void)
 {
        unsigned long lost,delay;
index 903d739ca74ae1543c0e6ddb79c4a3518b86ec91..a6e0ddd65bd0df08dbe59cd23c7f2592d1307dc2 100644 (file)
@@ -97,7 +97,6 @@ static void ack_vic_irq(unsigned int irq);
 static void vic_enable_cpi(void);
 static void do_boot_cpu(__u8 cpuid);
 static void do_quad_bootstrap(void);
-static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *);
 
 int hard_smp_processor_id(void);
 
@@ -125,6 +124,14 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi)
        }
 }
 
+static inline void
+wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
+{
+       irq_enter();
+       smp_local_timer_interrupt(regs);
+       irq_exit();
+}
+
 static inline void
 send_one_CPI(__u8 cpu, __u8 cpi)
 {
@@ -1249,14 +1256,6 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
        smp_local_timer_interrupt(regs);
 }
 
-static inline void
-wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
-{
-       irq_enter();
-       smp_local_timer_interrupt(regs);
-       irq_exit();
-}
-
 /* local (per CPU) timer interrupt.  It does both profiling and
  * process statistics/rescheduling.
  *
index db06f7399913f7da8a3b42d110f0dc24b41272cb..ab542792b27bbab0aa9be9fdf29d865b00e319e5 100644 (file)
@@ -238,19 +238,21 @@ void iounmap(volatile void __iomem *addr)
                        addr < phys_to_virt(ISA_END_ADDRESS))
                return;
 
-       p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
+       write_lock(&vmlist_lock);
+       p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
        if (!p) { 
-               printk("__iounmap: bad address %p\n", addr);
-               return;
+               printk("iounmap: bad address %p\n", addr);
+               goto out_unlock;
        }
 
        if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
-               /* p->size includes the guard page, but cpa doesn't like that */
                change_page_attr(virt_to_page(__va(p->phys_addr)),
                                 p->size >> PAGE_SHIFT,
                                 PAGE_KERNEL);
                global_flush_tlb();
        } 
+out_unlock:
+       write_unlock(&vmlist_lock);
        kfree(p); 
 }
 
index be52c5ac4e054692478d845505b654adf5d869b6..8e8e895e1b5a62749a1a1bf233fdf25dfaf782da 100644 (file)
@@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci
 #define MAX_PCIEROOT   6
 static int quirk_aspm_offset[MAX_PCIEROOT << 3];
 
-#define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b)
+#define GET_INDEX(a, b) ((((a) - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + ((b) & 7))
 
 static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
 {
index d6598da4b67bbc6fc1dde2ad121c692471813175..da21b1d07c15529e954a21ab8b48a0c48bd0df6b 100644 (file)
@@ -1029,7 +1029,6 @@ void pcibios_penalize_isa_irq(int irq)
 static int pirq_enable_irq(struct pci_dev *dev)
 {
        u8 pin;
-       extern int via_interrupt_line_quirk;
        struct pci_dev *temp_dev;
 
        pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@ -1084,10 +1083,6 @@ static int pirq_enable_irq(struct pci_dev *dev)
                printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
                       'A' + pin, pci_name(dev), msg);
        }
-       /* VIA bridges use interrupt line for apic/pci steering across
-          the V-Link */
-       else if (via_interrupt_line_quirk)
-               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
        return 0;
 }
 
index 468dbe8a6b9c22779d583913db85eb6bef1bdd64..3ad2c4af099cf67fa5bff6016347021913d76aee 100644 (file)
@@ -46,6 +46,10 @@ config GENERIC_IOMAP
        bool
        default y
 
+config SCHED_NO_NO_OMIT_FRAME_POINTER
+       bool
+       default y
+
 choice
        prompt "System type"
        default IA64_GENERIC
@@ -217,6 +221,16 @@ config IA64_SGI_SN_SIM
          If you are compiling a kernel that will run under SGI's IA-64
          simulator (Medusa) then say Y, otherwise say N.
 
+config IA64_SGI_SN_XP
+       tristate "Support communication between SGI SSIs"
+       depends on MSPEC
+       help
+         An SGI machine can be divided into multiple Single System
+         Images which act independently of each other and have
+         hardware based memory protection from the others.  Enabling
+         this feature will allow for direct communication between SSIs
+         based on a network adapter and DMA messaging.
+
 config FORCE_MAX_ZONEORDER
        int
        default "18"
@@ -261,6 +275,15 @@ config HOTPLUG_CPU
          can be controlled through /sys/devices/system/cpu/cpu#.
          Say N if you want to disable CPU hotplug.
 
+config SCHED_SMT
+       bool "SMT scheduler support"
+       depends on SMP
+       default off
+       help
+         Improves the CPU scheduler's decision making when dealing with
+         Intel IA64 chips with MultiThreading at a cost of slightly increased
+         overhead in some places. If unsure say N here.
+
 config PREEMPT
        bool "Preemptible Kernel"
         help
index 99830e8fc9ba39e8207e2b10e04169b15f56caba..9086b789f6ac15f65dc588603f03a229dc0a518f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Sat Jan 22 11:17:02 2005
+# Linux kernel version: 2.6.12-rc3
+# Tue May  3 15:55:04 2005
 #
 
 #
@@ -10,6 +10,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -21,24 +22,27 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=20
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -85,6 +89,7 @@ CONFIG_FORCE_MAX_ZONEORDER=18
 CONFIG_SMP=y
 CONFIG_NR_CPUS=4
 CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_IA32_SUPPORT=y
@@ -135,6 +140,7 @@ CONFIG_PCI_DOMAINS=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCI Hotplug Support
@@ -151,10 +157,6 @@ CONFIG_HOTPLUG_PCI_ACPI=m
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # Device Drivers
 #
@@ -195,9 +197,10 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CDROM_PKTCDVD is not set
 
@@ -313,7 +316,6 @@ CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -325,7 +327,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 CONFIG_SCSI_QLOGIC_FC=y
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=y
@@ -336,6 +337,7 @@ CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -358,6 +360,7 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
 
 #
 # Fusion MPT device support
@@ -386,7 +389,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -446,7 +448,6 @@ CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # ARCnet devices
@@ -484,7 +485,6 @@ CONFIG_NET_PCI=y
 # CONFIG_DGRS is not set
 CONFIG_EEPRO100=m
 CONFIG_E100=m
-# CONFIG_E100_NAPI is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -565,25 +565,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-CONFIG_GAMEPORT=m
-CONFIG_SOUND_GAMEPORT=m
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
-# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461X is not set
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -601,6 +582,24 @@ CONFIG_MOUSE_PS2=y
 # 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 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+CONFIG_GAMEPORT=m
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_VORTEX is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461X is not set
+CONFIG_SOUND_GAMEPORT=m
+
 #
 # Character devices
 #
@@ -615,6 +614,8 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_SYNCLINK is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
 # CONFIG_STALDRV is not set
 
 #
@@ -635,6 +636,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 #
 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
@@ -670,6 +672,12 @@ CONFIG_HPET=y
 # CONFIG_HPET_RTC_IRQ is not set
 CONFIG_HPET_MMAP=y
 CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -705,7 +713,6 @@ CONFIG_MAX_RAW_DEVS=256
 #
 CONFIG_VGA_CONSOLE=y
 CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -715,6 +722,8 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -726,8 +735,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -736,6 +743,8 @@ CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_SL811_HCD is not set
 
@@ -751,12 +760,11 @@ CONFIG_USB_UHCI_HCD=y
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT 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_HP8200e 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
@@ -800,6 +808,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -824,6 +833,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -867,7 +877,12 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
 CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=y
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -945,7 +960,7 @@ CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
+CONFIG_EXPORTFS=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
 CONFIG_RPCSEC_GSS_KRB5=m
@@ -1042,8 +1057,10 @@ CONFIG_GENERIC_IRQ_PROBE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=20
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1077,6 +1094,7 @@ CONFIG_CRYPTO_MD5=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_DES=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
index 6a8fcba7a853177996bfcf18213a84fbd3dee9e4..b8db6e3e5e8133bb0a4b055533ed968ce8837d73 100644 (file)
@@ -1944,43 +1944,17 @@ sba_connect_bus(struct pci_bus *bus)
 static void __init
 sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle)
 {
-       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-       union acpi_object *obj;
-       acpi_handle phandle;
        unsigned int node;
+       int pxm;
 
        ioc->node = MAX_NUMNODES;
 
-       /*
-        * Check for a _PXM on this node first.  We don't typically see
-        * one here, so we'll end up getting it from the parent.
-        */
-       if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PXM", NULL, &buffer))) {
-               if (ACPI_FAILURE(acpi_get_parent(handle, &phandle)))
-                       return;
-
-               /* Reset the acpi buffer */
-               buffer.length = ACPI_ALLOCATE_BUFFER;
-               buffer.pointer = NULL;
-
-               if (ACPI_FAILURE(acpi_evaluate_object(phandle, "_PXM", NULL,
-                                                     &buffer)))
-                       return;
-       }
+       pxm = acpi_get_pxm(handle);
 
-       if (!buffer.length || !buffer.pointer)
+       if (pxm < 0)
                return;
 
-       obj = buffer.pointer;
-
-       if (obj->type != ACPI_TYPE_INTEGER ||
-           obj->integer.value >= MAX_PXM_DOMAINS) {
-               acpi_os_free(buffer.pointer);
-               return;
-       }
-
-       node = pxm_to_nid_map[obj->integer.value];
-       acpi_os_free(buffer.pointer);
+       node = pxm_to_nid_map[pxm];
 
        if (node >= MAX_NUMNODES || !node_online(node))
                return;
index 9845dabe2613ae91bf456607b59d48400fe5689d..164b211f417474db5e566c4bab14024b10a3077c 100644 (file)
@@ -13,7 +13,6 @@
   
 #define        INCLUDES
 #include "compat_ioctl.c"
-#include <asm/ioctl32.h>
 
 #define IOCTL_NR(a)    ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
 
index 247a21c64aea33bb41ad5aa591323abcfb81aaaf..c1e20d65dd6cb4688391f928f43445aea644b66b 100644 (file)
@@ -2427,7 +2427,7 @@ sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents,
 {
        struct epoll_event *events64 = NULL;
        mm_segment_t old_fs = get_fs();
-       int error, numevents, size;
+       int numevents, size;
        int evt_idx;
        int do_free_pages = 0;
 
index a8e99c56a768946b673ca443cdc28a2b477119a8..72dfd9e7de0ffc470e3922fab11927b8e3fd0916 100644 (file)
@@ -779,7 +779,7 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
        union acpi_object *obj;
        struct acpi_table_iosapic *iosapic;
        unsigned int gsi_base;
-       int node;
+       int pxm, node;
 
        /* Only care about objects w/ a method that returns the MADT */
        if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
@@ -805,29 +805,16 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
        gsi_base = iosapic->global_irq_base;
 
        acpi_os_free(buffer.pointer);
-       buffer.length = ACPI_ALLOCATE_BUFFER;
-       buffer.pointer = NULL;
 
        /*
-        * OK, it's an IOSAPIC MADT entry, look for a _PXM method to tell
+        * OK, it's an IOSAPIC MADT entry, look for a _PXM value to tell
         * us which node to associate this with.
         */
-       if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PXM", NULL, &buffer)))
-               return AE_OK;
-
-       if (!buffer.length || !buffer.pointer)
-               return AE_OK;
-
-       obj = buffer.pointer;
-
-       if (obj->type != ACPI_TYPE_INTEGER ||
-           obj->integer.value >= MAX_PXM_DOMAINS) {
-               acpi_os_free(buffer.pointer);
+       pxm = acpi_get_pxm(handle);
+       if (pxm < 0)
                return AE_OK;
-       }
 
-       node = pxm_to_nid_map[obj->integer.value];
-       acpi_os_free(buffer.pointer);
+       node = pxm_to_nid_map[pxm];
 
        if (node >= MAX_NUMNODES || !node_online(node) ||
            cpus_empty(node_to_cpumask(node)))
index 9353adc18956aca1dfabf9e21afd05b69ec96c07..8ebfcc0c813aa744c86e32ae5f576af77080405b 100644 (file)
@@ -777,7 +777,7 @@ GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
        st8.spill [r2]=r8       // store return value in slot for r8 and set unat bit
        .mem.offset 8,0
        st8.spill [r3]=r0       // clear error indication in slot for r10 and set unat bit
-END(ia64_ret_from_ia32_execve_syscall)
+END(ia64_ret_from_ia32_execve)
        // fall through
 #endif /* CONFIG_IA32_SUPPORT */
 GLOBAL_ENTRY(ia64_leave_kernel)
@@ -1176,7 +1176,7 @@ ENTRY(notify_resume_user)
        ;;
 (pNonSys) mov out2=0                           // out2==0 => not a syscall
        .fframe 16
-       .spillpsp ar.unat, 16                   // (note that offset is relative to psp+0x10!)
+       .spillsp ar.unat, 16
        st8 [sp]=r9,-16                         // allocate space for ar.unat and save it
        st8 [out1]=loc1,-8                      // save ar.pfs, out1=&sigscratch
        .body
@@ -1202,7 +1202,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend)
        adds out2=8,sp                          // out2=&sigscratch->ar_pfs
        ;;
        .fframe 16
-       .spillpsp ar.unat, 16                   // (note that offset is relative to psp+0x10!)
+       .spillsp ar.unat, 16
        st8 [sp]=r9,-16                         // allocate space for ar.unat and save it
        st8 [out2]=loc1,-8                      // save ar.pfs, out2=&sigscratch
        .body
index f566ff43a389a6882f91b83ef401c511a689ccb7..7d7684a369d38609a149e98db03084f898eacb90 100644 (file)
@@ -460,9 +460,9 @@ EX(.fail_efault, ld8 r14=[r33])                     // r14 <- *set
        ;;
 
        st8 [r2]=r14                            // update current->blocked with new mask
-       cmpxchg4.acq r14=[r9],r18,ar.ccv        // current->thread_info->flags <- r18
+       cmpxchg4.acq r8=[r9],r18,ar.ccv         // current->thread_info->flags <- r18
        ;;
-       cmp.ne p6,p0=r17,r14                    // update failed?
+       cmp.ne p6,p0=r17,r                    // update failed?
 (p6)   br.cond.spnt.few 1b                     // yes -> retry
 
 #ifdef CONFIG_SMP
index 4d6c7b8f667bc6207dc20230c453560e276da516..736e328b5e612865d1173d84ff054dc21bbbfde9 100644 (file)
@@ -1103,8 +1103,6 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
        return IRQ_HANDLED;
 }
 
-#endif /* CONFIG_ACPI */
-
 /*
  *  ia64_mca_cpe_poll
  *
@@ -1122,6 +1120,8 @@ ia64_mca_cpe_poll (unsigned long dummy)
        platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
 }
 
+#endif /* CONFIG_ACPI */
+
 /*
  * C portion of the OS INIT handler
  *
@@ -1390,8 +1390,7 @@ ia64_mca_init(void)
        register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
 
 #ifdef CONFIG_ACPI
-       /* Setup the CPEI/P vector and handler */
-       cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
+       /* Setup the CPEI/P handler */
        register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
 #endif
 
@@ -1436,6 +1435,7 @@ ia64_mca_late_init(void)
 
 #ifdef CONFIG_ACPI
        /* Setup the CPEI/P vector and handler */
+       cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
        init_timer(&cpe_poll_timer);
        cpe_poll_timer.function = ia64_mca_cpe_poll;
 
index ab478172c34956f0524e7f731fe4d5a772109caf..abc0113a821df8eee06fca411866cfe4de324a6d 100644 (file)
@@ -132,8 +132,7 @@ mca_handler_bh(unsigned long paddr)
        spin_unlock(&mca_bh_lock);
 
        /* This process is about to be killed itself */
-       force_sig(SIGKILL, current);
-       schedule();
+       do_exit(SIGKILL);
 }
 
 /**
@@ -439,6 +438,7 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_chec
                        psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
                        psr2->cpl = 0;
                        psr2->ri  = 0;
+                       psr2->i  = 0;
 
                        return 1;
                }
index bcfa05acc561fcd84037934cbe4a860ebc832089..2d7e0217638d29866d13070f4ca4a516e450eaef 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <asm/asmmacro.h>
 #include <asm/processor.h>
+#include <asm/ptrace.h>
 
 GLOBAL_ENTRY(mca_handler_bhhook)
        invala                                          // clear RSE ?
@@ -20,12 +21,21 @@ GLOBAL_ENTRY(mca_handler_bhhook)
        ;;                                              
        alloc           r16=ar.pfs,0,2,1,0              // make a new frame
        ;;
+       mov             ar.rsc=0
+       ;;
        mov             r13=IA64_KR(CURRENT)            // current task pointer
        ;;
-       adds            r12=IA64_TASK_THREAD_KSP_OFFSET,r13
+       mov             r2=r13
+       ;;
+       addl            r22=IA64_RBS_OFFSET,r2
+       ;;
+       mov             ar.bspstore=r22
        ;;
-       ld8             r12=[r12]                       // stack pointer
+       addl            sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2
        ;;
+       adds            r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+       ;;
+       st1             [r2]=r0                         // clear current->thread.on_ustack flag
        mov             loc0=r16
        movl            loc1=mca_handler_bh             // recovery C function
        ;;
@@ -34,7 +44,9 @@ GLOBAL_ENTRY(mca_handler_bhhook)
        ;;
        mov             loc1=rp
        ;;
-       br.call.sptk.many    rp=b6                      // not return ...
+       ssm             psr.i
+       ;;
+       br.call.sptk.many    rp=b6                      // does not return ...
        ;;
        mov             ar.pfs=loc0
        mov             rp=loc1
index 1dbc7b2497c90d4b3c0a8cef4c7afb94e7abc315..f6d8a010d99beacb04dc2d3a9cf8af2e14237a3e 100644 (file)
@@ -41,7 +41,7 @@
 (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;                                                   \
 (pKStk) ld8 r3 = [r3];;                                                                                \
 (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;                                            \
-(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;                                          \
+(pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;                                          \
 (pUStk)        mov ar.rsc=0;           /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */     \
 (pUStk)        addl r22=IA64_RBS_OFFSET,r1;            /* compute base of register backing store */    \
        ;;                                                                                      \
@@ -50,7 +50,6 @@
 (pUStk)        mov r23=ar.bspstore;                            /* save ar.bspstore */                  \
 (pUStk)        dep r22=-1,r22,61,3;                    /* compute kernel virtual addr of RBS */        \
        ;;                                                                                      \
-(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;         /* if in kernel mode, use sp (r12) */           \
 (pUStk)        mov ar.bspstore=r22;                    /* switch to kernel RBS */                      \
        ;;                                                                                      \
 (pUStk)        mov r18=ar.bsp;                                                                         \
index febc091c2f02d318cd4bfa72346a10b536f08d5f..f1aca7cffd120879e446e703a8783f93c36f6654 100644 (file)
@@ -825,14 +825,16 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
                 * XXX Should have an arch-hook for running this after final section
                 *     addresses have been selected...
                 */
-               /* See if gp can cover the entire core module:  */
-               uint64_t gp = (uint64_t) mod->module_core + MAX_LTOFF / 2;
-               if (mod->core_size >= MAX_LTOFF)
+               uint64_t gp;
+               if (mod->core_size > MAX_LTOFF)
                        /*
                         * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
                         * at the end of the module.
                         */
-                       gp = (uint64_t) mod->module_core + mod->core_size - MAX_LTOFF / 2;
+                       gp = mod->core_size - MAX_LTOFF / 2;
+               else
+                       gp = mod->core_size / 2;
+               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
                mod->arch.gp = gp;
                DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
        }
index 376fcbc3f8da879e5803e1001a219522c53ab075..6407bff6bfd7540cb02322b093b7bf860a7e2321 100644 (file)
@@ -11,7 +11,7 @@
  * Version Perfmon-2.x is a rewrite of perfmon-1.x
  * by Stephane Eranian, Hewlett Packard Co.
  *
- * Copyright (C) 1999-2003, 2005  Hewlett Packard Co
+ * Copyright (C) 1999-2005  Hewlett Packard Co
  *               Stephane Eranian <eranian@hpl.hp.com>
  *               David Mosberger-Tang <davidm@hpl.hp.com>
  *
@@ -497,6 +497,9 @@ typedef struct {
 static pfm_stats_t             pfm_stats[NR_CPUS];
 static pfm_session_t           pfm_sessions;   /* global sessions information */
 
+static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED;
+static pfm_intr_handler_desc_t  *pfm_alt_intr_handler;
+
 static struct proc_dir_entry   *perfmon_dir;
 static pfm_uuid_t              pfm_null_uuid = {0,};
 
@@ -606,6 +609,7 @@ DEFINE_PER_CPU(unsigned long, pfm_syst_info);
 DEFINE_PER_CPU(struct task_struct *, pmu_owner);
 DEFINE_PER_CPU(pfm_context_t  *, pmu_ctx);
 DEFINE_PER_CPU(unsigned long, pmu_activation_number);
+EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info);
 
 
 /* forward declaration */
@@ -1265,6 +1269,8 @@ out:
 }
 EXPORT_SYMBOL(pfm_unregister_buffer_fmt);
 
+extern void update_pal_halt_status(int);
+
 static int
 pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
 {
@@ -1311,6 +1317,11 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
                is_syswide,
                cpu));
 
+       /*
+        * disable default_idle() to go to PAL_HALT
+        */
+       update_pal_halt_status(0);
+
        UNLOCK_PFS(flags);
 
        return 0;
@@ -1318,7 +1329,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
 error_conflict:
        DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
                pfm_sessions.pfs_sys_session[cpu]->pid,
-               smp_processor_id()));
+               cpu));
 abort:
        UNLOCK_PFS(flags);
 
@@ -1366,6 +1377,12 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
                is_syswide,
                cpu));
 
+       /*
+        * if possible, enable default_idle() to go into PAL_HALT
+        */
+       if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0)
+               update_pal_halt_status(1);
+
        UNLOCK_PFS(flags);
 
        return 0;
@@ -4202,7 +4219,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
                DPRINT(("cannot load to [%d], invalid ctx_state=%d\n",
                        req->load_pid,
                        ctx->ctx_state));
-               return -EINVAL;
+               return -EBUSY;
        }
 
        DPRINT(("load_pid [%d] using_dbreg=%d\n", req->load_pid, ctx->ctx_fl_using_dbreg));
@@ -4704,16 +4721,26 @@ recheck:
        if (task == current || ctx->ctx_fl_system) return 0;
 
        /*
-        * if context is UNLOADED we are safe to go
+        * we are monitoring another thread
         */
-       if (state == PFM_CTX_UNLOADED) return 0;
-
-       /*
-        * no command can operate on a zombie context
-        */
-       if (state == PFM_CTX_ZOMBIE) {
-               DPRINT(("cmd %d state zombie cannot operate on context\n", cmd));
-               return -EINVAL;
+       switch(state) {
+               case PFM_CTX_UNLOADED:
+                       /*
+                        * if context is UNLOADED we are safe to go
+                        */
+                       return 0;
+               case PFM_CTX_ZOMBIE:
+                       /*
+                        * no command can operate on a zombie context
+                        */
+                       DPRINT(("cmd %d state zombie cannot operate on context\n", cmd));
+                       return -EINVAL;
+               case PFM_CTX_MASKED:
+                       /*
+                        * PMU state has been saved to software even though
+                        * the thread may still be running.
+                        */
+                       if (cmd != PFM_UNLOAD_CONTEXT) return 0;
        }
 
        /*
@@ -5532,26 +5559,32 @@ pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
        int ret;
 
        this_cpu = get_cpu();
-       min      = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
-       max      = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
+       if (likely(!pfm_alt_intr_handler)) {
+               min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
+               max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
 
-       start_cycles = ia64_get_itc();
+               start_cycles = ia64_get_itc();
 
-       ret = pfm_do_interrupt_handler(irq, arg, regs);
+               ret = pfm_do_interrupt_handler(irq, arg, regs);
 
-       total_cycles = ia64_get_itc();
+               total_cycles = ia64_get_itc();
 
-       /*
-        * don't measure spurious interrupts
-        */
-       if (likely(ret == 0)) {
-               total_cycles -= start_cycles;
+               /*
+                * don't measure spurious interrupts
+                */
+               if (likely(ret == 0)) {
+                       total_cycles -= start_cycles;
 
-               if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles;
-               if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles;
+                       if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles;
+                       if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles;
 
-               pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles;
+                       pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles;
+               }
        }
+       else {
+               (*pfm_alt_intr_handler->handler)(irq, arg, regs);
+       }
+
        put_cpu_no_resched();
        return IRQ_HANDLED;
 }
@@ -6402,6 +6435,141 @@ static struct irqaction perfmon_irqaction = {
        .name    = "perfmon"
 };
 
+static void
+pfm_alt_save_pmu_state(void *data)
+{
+       struct pt_regs *regs;
+
+       regs = ia64_task_regs(current);
+
+       DPRINT(("called\n"));
+
+       /*
+        * should not be necessary but
+        * let's take not risk
+        */
+       pfm_clear_psr_up();
+       pfm_clear_psr_pp();
+       ia64_psr(regs)->pp = 0;
+
+       /*
+        * This call is required
+        * May cause a spurious interrupt on some processors
+        */
+       pfm_freeze_pmu();
+
+       ia64_srlz_d();
+}
+
+void
+pfm_alt_restore_pmu_state(void *data)
+{
+       struct pt_regs *regs;
+
+       regs = ia64_task_regs(current);
+
+       DPRINT(("called\n"));
+
+       /*
+        * put PMU back in state expected
+        * by perfmon
+        */
+       pfm_clear_psr_up();
+       pfm_clear_psr_pp();
+       ia64_psr(regs)->pp = 0;
+
+       /*
+        * perfmon runs with PMU unfrozen at all times
+        */
+       pfm_unfreeze_pmu();
+
+       ia64_srlz_d();
+}
+
+int
+pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
+{
+       int ret, i;
+       int reserve_cpu;
+
+       /* some sanity checks */
+       if (hdl == NULL || hdl->handler == NULL) return -EINVAL;
+
+       /* do the easy test first */
+       if (pfm_alt_intr_handler) return -EBUSY;
+
+       /* one at a time in the install or remove, just fail the others */
+       if (!spin_trylock(&pfm_alt_install_check)) {
+               return -EBUSY;
+       }
+
+       /* reserve our session */
+       for_each_online_cpu(reserve_cpu) {
+               ret = pfm_reserve_session(NULL, 1, reserve_cpu);
+               if (ret) goto cleanup_reserve;
+       }
+
+       /* save the current system wide pmu states */
+       ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1);
+       if (ret) {
+               DPRINT(("on_each_cpu() failed: %d\n", ret));
+               goto cleanup_reserve;
+       }
+
+       /* officially change to the alternate interrupt handler */
+       pfm_alt_intr_handler = hdl;
+
+       spin_unlock(&pfm_alt_install_check);
+
+       return 0;
+
+cleanup_reserve:
+       for_each_online_cpu(i) {
+               /* don't unreserve more than we reserved */
+               if (i >= reserve_cpu) break;
+
+               pfm_unreserve_session(NULL, 1, i);
+       }
+
+       spin_unlock(&pfm_alt_install_check);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(pfm_install_alt_pmu_interrupt);
+
+int
+pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
+{
+       int i;
+       int ret;
+
+       if (hdl == NULL) return -EINVAL;
+
+       /* cannot remove someone else's handler! */
+       if (pfm_alt_intr_handler != hdl) return -EINVAL;
+
+       /* one at a time in the install or remove, just fail the others */
+       if (!spin_trylock(&pfm_alt_install_check)) {
+               return -EBUSY;
+       }
+
+       pfm_alt_intr_handler = NULL;
+
+       ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 0, 1);
+       if (ret) {
+               DPRINT(("on_each_cpu() failed: %d\n", ret));
+       }
+
+       for_each_online_cpu(i) {
+               pfm_unreserve_session(NULL, 1, i);
+       }
+
+       spin_unlock(&pfm_alt_install_check);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pfm_remove_alt_pmu_interrupt);
+
 /*
  * perfmon initialization routine, called from the initcall() table
  */
index 7c43aea5f7f7d9b96b7d9837fa029e16b62ef5df..ebb71f3d6d190632aed9819fd4e12fef5d1215b5 100644 (file)
@@ -50,7 +50,7 @@
 #include "sigframe.h"
 
 void (*ia64_mark_idle)(int);
-static cpumask_t cpu_idle_map;
+static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
 
 unsigned long boot_option_idle_override = 0;
 EXPORT_SYMBOL(boot_option_idle_override);
@@ -173,7 +173,9 @@ do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall
                ia64_do_signal(oldset, scr, in_syscall);
 }
 
-static int pal_halt = 1;
+static int pal_halt        = 1;
+static int can_do_pal_halt = 1;
+
 static int __init nohalt_setup(char * str)
 {
        pal_halt = 0;
@@ -181,16 +183,20 @@ static int __init nohalt_setup(char * str)
 }
 __setup("nohalt", nohalt_setup);
 
+void
+update_pal_halt_status(int status)
+{
+       can_do_pal_halt = pal_halt && status;
+}
+
 /*
  * We use this if we don't have any better idle routine..
  */
 void
 default_idle (void)
 {
-       unsigned long pmu_active = ia64_getreg(_IA64_REG_PSR) & (IA64_PSR_PP | IA64_PSR_UP);
-
        while (!need_resched())
-               if (pal_halt && !pmu_active)
+               if (can_do_pal_halt)
                        safe_halt();
                else
                        cpu_relax();
@@ -223,20 +229,31 @@ static inline void play_dead(void)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-
 void cpu_idle_wait(void)
 {
-        int cpu;
-        cpumask_t map;
+       unsigned int cpu, this_cpu = get_cpu();
+       cpumask_t map;
 
-        for_each_online_cpu(cpu)
-                cpu_set(cpu, cpu_idle_map);
+       set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
+       put_cpu();
 
-        wmb();
-        do {
-                ssleep(1);
-                cpus_and(map, cpu_idle_map, cpu_online_map);
-        } while (!cpus_empty(map));
+       cpus_clear(map);
+       for_each_online_cpu(cpu) {
+               per_cpu(cpu_idle_state, cpu) = 1;
+               cpu_set(cpu, map);
+       }
+
+       __get_cpu_var(cpu_idle_state) = 0;
+
+       wmb();
+       do {
+               ssleep(1);
+               for_each_online_cpu(cpu) {
+                       if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
+                               cpu_clear(cpu, map);
+               }
+               cpus_and(map, map, cpu_online_map);
+       } while (!cpus_empty(map));
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
@@ -244,7 +261,6 @@ void __attribute__((noreturn))
 cpu_idle (void)
 {
        void (*mark_idle)(int) = ia64_mark_idle;
-       int cpu = smp_processor_id();
 
        /* endless idle loop with no priority at all */
        while (1) {
@@ -255,12 +271,13 @@ cpu_idle (void)
                while (!need_resched()) {
                        void (*idle)(void);
 
+                       if (__get_cpu_var(cpu_idle_state))
+                               __get_cpu_var(cpu_idle_state) = 0;
+
+                       rmb();
                        if (mark_idle)
                                (*mark_idle)(1);
 
-                       if (cpu_isset(cpu, cpu_idle_map))
-                               cpu_clear(cpu, cpu_idle_map);
-                       rmb();
                        idle = pm_idle;
                        if (!idle)
                                idle = default_idle;
index 9e730c7bf0cd6eb94237bf9ac3db4ff70443686d..4c1d2f5442b3ec4badaf0b9acd85a208b122a930 100644 (file)
@@ -635,11 +635,17 @@ ia64_flush_fph (struct task_struct *task)
 {
        struct ia64_psr *psr = ia64_psr(ia64_task_regs(task));
 
+       /*
+        * Prevent migrating this task while
+        * we're fiddling with the FPU state
+        */
+       preempt_disable();
        if (ia64_is_local_fpu_owner(task) && psr->mfh) {
                psr->mfh = 0;
                task->thread.flags |= IA64_THREAD_FPH_VALID;
                ia64_save_fpu(&task->thread.fph[0]);
        }
+       preempt_enable();
 }
 
 /*
@@ -692,16 +698,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs  *pt,
                        unsigned long cfm)
 {
        struct unw_frame_info info, prev_info;
-       unsigned long ip, pr;
+       unsigned long ip, sp, pr;
 
        unw_init_from_blocked_task(&info, child);
        while (1) {
                prev_info = info;
                if (unw_unwind(&info) < 0)
                        return;
-               if (unw_get_rp(&info, &ip) < 0)
+
+               unw_get_sp(&info, &sp);
+               if ((long)((unsigned long)child + IA64_STK_OFFSET - sp)
+                   < IA64_PT_REGS_SIZE) {
+                       dprintk("ptrace.%s: ran off the top of the kernel "
+                               "stack\n", __FUNCTION__);
+                       return;
+               }
+               if (unw_get_pr (&prev_info, &pr) < 0) {
+                       unw_get_rp(&prev_info, &ip);
+                       dprintk("ptrace.%s: failed to read "
+                               "predicate register (ip=0x%lx)\n",
+                               __FUNCTION__, ip);
                        return;
-               if (ip < FIXADDR_USER_END)
+               }
+               if (unw_is_intr_frame(&info)
+                   && (pr & (1UL << PRED_USER_STACK)))
                        break;
        }
 
@@ -1616,20 +1636,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
                     long arg4, long arg5, long arg6, long arg7,
                     struct pt_regs regs)
 {
-       long syscall;
+       if (test_thread_flag(TIF_SYSCALL_TRACE) 
+           && (current->ptrace & PT_PTRACED))
+               syscall_trace();
 
        if (unlikely(current->audit_context)) {
-               if (IS_IA32_PROCESS(&regs))
+               long syscall;
+               int arch;
+
+               if (IS_IA32_PROCESS(&regs)) {
                        syscall = regs.r1;
-               else
+                       arch = AUDIT_ARCH_I386;
+               } else {
                        syscall = regs.r15;
+                       arch = AUDIT_ARCH_IA64;
+               }
 
-               audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3);
+               audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3);
        }
 
-       if (test_thread_flag(TIF_SYSCALL_TRACE)
-           && (current->ptrace & PT_PTRACED))
-               syscall_trace();
 }
 
 /* "asmlinkage" so the input arguments are preserved... */
@@ -1640,7 +1665,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
                     struct pt_regs regs)
 {
        if (unlikely(current->audit_context))
-               audit_syscall_exit(current, regs.r8);
+               audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8);
 
        if (test_thread_flag(TIF_SYSCALL_TRACE)
            && (current->ptrace & PT_PTRACED))
index b7e6b4cb374b89302f5ba58612bce333f7b8a1cd..d14692e0920acc5c6f0350b9b14bddc801b07221 100644 (file)
@@ -720,7 +720,8 @@ cpu_init (void)
        ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page)));
 
        /*
-        * Initialize default control register to defer all speculative faults.  The
+        * Initialize default control register to defer speculative faults except
+        * for those arising from TLB misses, which are not deferred.  The
         * kernel MUST NOT depend on a particular setting of these bits (in other words,
         * the kernel must have recovery code for all speculative accesses).  Turn on
         * dcr.lc as per recommendation by the architecture team.  Most IA-32 apps
index 6891d86937d92be4038cac575f7e9b153bfe1503..499b7e5317cf4f5ac3564ccf55bfdc5dc2829da5 100644 (file)
@@ -224,7 +224,8 @@ ia64_rt_sigreturn (struct sigscratch *scr)
         * could be corrupted.
         */
        retval = (long) &ia64_leave_kernel;
-       if (test_thread_flag(TIF_SYSCALL_TRACE))
+       if (test_thread_flag(TIF_SYSCALL_TRACE)
+           || test_thread_flag(TIF_SYSCALL_AUDIT))
                /*
                 * strace expects to be notified after sigreturn returns even though the
                 * context to which we return may not be in the middle of a syscall.
index 0d5ee57c9865ce10128cdf89a05d0af48d8d7020..3865f088ffa26d9c7db30c932098a09db0762ba0 100644 (file)
@@ -624,7 +624,7 @@ static struct {
        __u16   thread_id;
        __u16   proc_fixed_addr;
        __u8    valid;
-}mt_info[NR_CPUS] __devinit;
+} mt_info[NR_CPUS] __devinitdata;
 
 #ifdef CONFIG_HOTPLUG_CPU
 static inline void
index a8cf6d8a509cb07c780ccde59b8a71a30c437b46..770fab37928ee9e4c3870b8875473f7a53d1213b 100644 (file)
@@ -182,13 +182,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un
                }
        }
 
-       /*
-        * A zero mmap always succeeds in Linux, independent of whether or not the
-        * remaining arguments are valid.
-        */
-       if (len == 0)
-               goto out;
-
        /* Careful about overflows.. */
        len = PAGE_ALIGN(len);
        if (!len || len > TASK_SIZE) {
index e82ad78081b38724e5f80c2cbe8d107e0fbcb871..1861173bd4f6a7be2d76edeb008e7b83a3231856 100644 (file)
@@ -111,6 +111,24 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
        siginfo_t siginfo;
        int sig, code;
 
+       /* break.b always sets cr.iim to 0, which causes problems for
+        * debuggers.  Get the real break number from the original instruction,
+        * but only for kernel code.  User space break.b is left alone, to
+        * preserve the existing behaviour.  All break codings have the same
+        * format, so there is no need to check the slot type.
+        */
+       if (break_num == 0 && !user_mode(regs)) {
+               struct ia64_psr *ipsr = ia64_psr(regs);
+               unsigned long *bundle = (unsigned long *)regs->cr_iip;
+               unsigned long slot;
+               switch (ipsr->ri) {
+                     case 0:  slot = (bundle[0] >>  5); break;
+                     case 1:  slot = (bundle[0] >> 46) | (bundle[1] << 18); break;
+                     default: slot = (bundle[1] >> 23); break;
+               }
+               break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff);
+       }
+
        /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
        siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
        siginfo.si_imm = break_num;
@@ -202,13 +220,21 @@ disabled_fph_fault (struct pt_regs *regs)
 
        /* first, grant user-level access to fph partition: */
        psr->dfh = 0;
+
+       /*
+        * Make sure that no other task gets in on this processor
+        * while we're claiming the FPU
+        */
+       preempt_disable();
 #ifndef CONFIG_SMP
        {
                struct task_struct *fpu_owner
                        = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
 
-               if (ia64_is_local_fpu_owner(current))
+               if (ia64_is_local_fpu_owner(current)) {
+                       preempt_enable_no_resched();
                        return;
+               }
 
                if (fpu_owner)
                        ia64_flush_fph(fpu_owner);
@@ -226,6 +252,7 @@ disabled_fph_fault (struct pt_regs *regs)
                 */
                psr->mfh = 1;
        }
+       preempt_enable_no_resched();
 }
 
 static inline int
index 29c802b19669626aa47e08c5cf08334f5d3385d6..a1af9146cfdbea5fa0530f8a3f68afd0fad70094 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Cache flushing routines.
  *
- * Copyright (C) 1999-2001 Hewlett-Packard Co
- * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co
+ *     David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <asm/asmmacro.h>
 #include <asm/page.h>
@@ -26,7 +26,7 @@ GLOBAL_ENTRY(flush_icache_range)
 
        mov ar.lc=r8
        ;;
-.Loop: fc in0                          // issuable on M0 only
+.Loop: fc.i in0                        // issuable on M2 only
        add in0=32,in0
        br.cloop.sptk.few .Loop
        ;;
index 3c2cd2f04db96dadd528501a625a26b8fbeb2cf6..6f308e62c1377cc04ee24efcd08775a66ed24dae 100644 (file)
@@ -75,6 +75,7 @@ GLOBAL_ENTRY(memcpy)
        mov     f6=f0
        br.cond.sptk .common_code
        ;;
+END(memcpy)
 GLOBAL_ENTRY(__copy_user)
        .prologue
 // check dest alignment
@@ -524,7 +525,6 @@ EK(.ex_handler,  (p17)      st8     [dst1]=r39,8);                                          \
 #undef B
 #undef C
 #undef D
-END(memcpy)
 
 /*
  * Due to lack of local tag support in gcc 2.x assembler, it is not clear which
index bd8cf907fe227d60e488f4817f302da0335e508b..f26c16aefb1cbfdec5cd2fa5e466ae5426c627ca 100644 (file)
@@ -57,10 +57,10 @@ GLOBAL_ENTRY(memset)
 { .mmi
        .prologue
        alloc   tmp = ar.pfs, 3, 0, 0, 0
-       .body
        lfetch.nt1 [dest]                       //
        .save   ar.lc, save_lc
        mov.i   save_lc = ar.lc
+       .body
 } { .mmi
        mov     ret0 = dest                     // return value
        cmp.ne  p_nz, p_zr = value, r0          // use stf.spill if value is zero
index 547785e3cba2fb3e63a7a9c7dbd10931caf47bba..4eb2f52b87a16b436007740a56abaf79574d51fa 100644 (file)
@@ -305,8 +305,9 @@ setup_gate (void)
        struct page *page;
 
        /*
-        * Map the gate page twice: once read-only to export the ELF headers etc. and once
-        * execute-only page to enable privilege-promotion via "epc":
+        * Map the gate page twice: once read-only to export the ELF
+        * headers etc. and once execute-only page to enable
+        * privilege-promotion via "epc":
         */
        page = virt_to_page(ia64_imva(__start_gate_section));
        put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
@@ -315,6 +316,20 @@ setup_gate (void)
        put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
 #else
        put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
+       /* Fill in the holes (if any) with read-only zero pages: */
+       {
+               unsigned long addr;
+
+               for (addr = GATE_ADDR + PAGE_SIZE;
+                    addr < GATE_ADDR + PERCPU_PAGE_SIZE;
+                    addr += PAGE_SIZE)
+               {
+                       put_kernel_page(ZERO_PAGE(0), addr,
+                                       PAGE_READONLY);
+                       put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE,
+                                       PAGE_READONLY);
+               }
+       }
 #endif
        ia64_patch_gate();
 }
index 4f381fb25049b6b87c9e4bcab0f9dc61224e4711..4351c4ff984582470403bfe4333e8f693be5dde2 100644 (file)
@@ -4,10 +4,15 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
+# Copyright (C) 1999,2001-2005 Silicon Graphics, Inc.  All Rights Reserved.
 #
 
 obj-y                          += setup.o bte.o bte_error.o irq.o mca.o idle.o \
                                   huberror.o io_init.o iomv.o klconflib.o sn2/
 obj-$(CONFIG_IA64_GENERIC)      += machvec.o
 obj-$(CONFIG_SGI_TIOCX)                += tiocx.o
+obj-$(CONFIG_IA64_SGI_SN_XP)   += xp.o
+xp-y                           := xp_main.o xp_nofault.o
+obj-$(CONFIG_IA64_SGI_SN_XP)   += xpc.o
+xpc-y                          := xpc_main.o xpc_channel.o xpc_partition.o
+obj-$(CONFIG_IA64_SGI_SN_XP)   += xpnet.o
index 18160a06a8c9eb3bfaba5257e639a12816c80158..9e07f5463f21d53fcac34ec658f443ca550b4222 100644 (file)
@@ -174,6 +174,12 @@ static void sn_fixup_ionodes(void)
                if (status)
                        continue;
 
+               /* Attach the error interrupt handlers */
+               if (nasid & 1)
+                       ice_error_init(hubdev);
+               else
+                       hub_error_init(hubdev);
+
                for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++)
                        hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev;
 
@@ -211,10 +217,6 @@ static void sn_fixup_ionodes(void)
                            sn_flush_device_list;
                }
 
-               if (!(i & 1))
-                       hub_error_init(hubdev);
-               else
-                       ice_error_init(hubdev);
        }
 
 }
index 857774bb2c9adeb5dde27e6b150821e4fe67d4ea..6546db6abdba4b7c93c60b6ff7d72a8f1a7c8363 100644 (file)
@@ -37,6 +37,11 @@ static u64 *sn_oemdata_size, sn_oemdata_bufsize;
  * This function is the callback routine that SAL calls to log error
  * info for platform errors.  buf is appended to sn_oemdata, resizing as
  * required.
+ * Note: this is a SAL to OS callback, running under the same rules as the SAL
+ * code.  SAL calls are run with preempt disabled so this routine must not
+ * sleep.  vmalloc can sleep so print_hook cannot resize the output buffer
+ * itself, instead it must set the required size and return to let the caller
+ * resize the buffer then redrive the SAL call.
  */
 static int print_hook(const char *fmt, ...)
 {
@@ -47,18 +52,8 @@ static int print_hook(const char *fmt, ...)
        vsnprintf(buf, sizeof(buf), fmt, args);
        va_end(args);
        len = strlen(buf);
-       while (*sn_oemdata_size + len + 1 > sn_oemdata_bufsize) {
-               u8 *newbuf = vmalloc(sn_oemdata_bufsize += 1000);
-               if (!newbuf) {
-                       printk(KERN_ERR "%s: unable to extend sn_oemdata\n",
-                              __FUNCTION__);
-                       return 0;
-               }
-               memcpy(newbuf, *sn_oemdata, *sn_oemdata_size);
-               vfree(*sn_oemdata);
-               *sn_oemdata = newbuf;
-       }
-       memcpy(*sn_oemdata + *sn_oemdata_size, buf, len + 1);
+       if (*sn_oemdata_size + len <= sn_oemdata_bufsize)
+               memcpy(*sn_oemdata + *sn_oemdata_size, buf, len);
        *sn_oemdata_size += len;
        return 0;
 }
@@ -98,7 +93,20 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
        sn_oemdata = oemdata;
        sn_oemdata_size = oemdata_size;
        sn_oemdata_bufsize = 0;
-       ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
+       *sn_oemdata_size = PAGE_SIZE;   /* first guess at how much data will be generated */
+       while (*sn_oemdata_size > sn_oemdata_bufsize) {
+               u8 *newbuf = vmalloc(*sn_oemdata_size);
+               if (!newbuf) {
+                       printk(KERN_ERR "%s: unable to extend sn_oemdata\n",
+                              __FUNCTION__);
+                       return 1;
+               }
+               vfree(*sn_oemdata);
+               *sn_oemdata = newbuf;
+               sn_oemdata_bufsize = *sn_oemdata_size;
+               *sn_oemdata_size = 0;
+               ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
+       }
        up(&sn_oemdata_mutex);
        return 0;
 }
index d35f2a6f9c948a7dd974758b3b43cd66fa0f6118..44bfc7f318cbd611752fcede5459ee3182807191 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -73,6 +73,12 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second);
 DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
 EXPORT_PER_CPU_SYMBOL(__sn_hub_info);
 
+DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]);
+EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
+
+DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda);
+EXPORT_PER_CPU_SYMBOL(__sn_nodepda);
+
 partid_t sn_partid = -1;
 EXPORT_SYMBOL(sn_partid);
 char sn_system_serial_number_string[128];
@@ -216,7 +222,7 @@ void __init early_sn_setup(void)
 
 extern int platform_intr_list[];
 extern nasid_t master_nasid;
-static int shub_1_1_found __initdata;
+static int __initdata shub_1_1_found = 0;
 
 /*
  * sn_check_for_wars
@@ -245,7 +251,7 @@ static void __init sn_check_for_wars(void)
        } else {
                for_each_online_node(cnode) {
                        if (is_shub_1_1(cnodeid_to_nasid(cnode)))
-                               sn_hub_info->shub_1_1_found = 1;
+                               shub_1_1_found = 1;
                }
        }
 }
@@ -265,6 +271,8 @@ void __init sn_setup(char **cmdline_p)
        int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
        extern void sn_cpu_init(void);
 
+       ia64_sn_plat_set_error_handling_features();
+
        /*
         * If the generic code has enabled vga console support - lets
         * get rid of it again. This is a kludge for the fact that ACPI
@@ -373,11 +381,11 @@ static void __init sn_init_pdas(char **cmdline_p)
 {
        cnodeid_t cnode;
 
-       memset(pda->cnodeid_to_nasid_table, -1,
-              sizeof(pda->cnodeid_to_nasid_table));
+       memset(sn_cnodeid_to_nasid, -1,
+                       sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
        for_each_online_node(cnode)
-               pda->cnodeid_to_nasid_table[cnode] =
-                   pxm_to_nasid(nid_to_pxm_map[cnode]);
+               sn_cnodeid_to_nasid[cnode] =
+                               pxm_to_nasid(nid_to_pxm_map[cnode]);
 
        numionodes = num_online_nodes();
        scan_for_ionodes();
@@ -477,7 +485,8 @@ void __init sn_cpu_init(void)
 
        cnode = nasid_to_cnodeid(nasid);
 
-       pda->p_nodepda = nodepdaindr[cnode];
+       sn_nodepda = nodepdaindr[cnode];
+
        pda->led_address =
            (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT));
        pda->led_state = LED_ALWAYS_SET;
@@ -486,15 +495,18 @@ void __init sn_cpu_init(void)
        pda->idle_flag = 0;
 
        if (cpuid != 0) {
-               memcpy(pda->cnodeid_to_nasid_table,
-                      pdacpu(0)->cnodeid_to_nasid_table,
-                      sizeof(pda->cnodeid_to_nasid_table));
+               /* copy cpu 0's sn_cnodeid_to_nasid table to this cpu's */
+               memcpy(sn_cnodeid_to_nasid,
+                      (&per_cpu(__sn_cnodeid_to_nasid, 0)),
+                      sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
        }
 
        /*
         * Check for WARs.
         * Only needs to be done once, on BSP.
-        * Has to be done after loop above, because it uses pda.cnodeid_to_nasid_table[i].
+        * Has to be done after loop above, because it uses this cpu's
+        * sn_cnodeid_to_nasid table which was just initialized if this
+        * isn't cpu 0.
         * Has to be done before assignment below.
         */
        if (!wars_have_been_checked) {
@@ -580,8 +592,7 @@ static void __init scan_for_ionodes(void)
                brd = find_lboard_any(brd, KLTYPE_SNIA);
 
                while (brd) {
-                       pda->cnodeid_to_nasid_table[numionodes] =
-                           brd->brd_nasid;
+                       sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
                        physical_node_map[brd->brd_nasid] = numionodes;
                        root_lboard[numionodes] = brd;
                        numionodes++;
@@ -602,8 +613,7 @@ static void __init scan_for_ionodes(void)
                                      root_lboard[nasid_to_cnodeid(nasid)],
                                      KLTYPE_TIO);
                while (brd) {
-                       pda->cnodeid_to_nasid_table[numionodes] =
-                           brd->brd_nasid;
+                       sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid;
                        physical_node_map[brd->brd_nasid] = numionodes;
                        root_lboard[numionodes] = brd;
                        numionodes++;
@@ -614,7 +624,6 @@ static void __init scan_for_ionodes(void)
                        brd = find_lboard_any(brd, KLTYPE_TIO);
                }
        }
-
 }
 
 int
@@ -623,7 +632,8 @@ nasid_slice_to_cpuid(int nasid, int slice)
        long cpu;
        
        for (cpu=0; cpu < NR_CPUS; cpu++) 
-               if (nodepda->phys_cpuid[cpu].nasid == nasid && nodepda->phys_cpuid[cpu].slice == slice)
+               if (cpuid_to_nasid(cpu) == nasid &&
+                                       cpuid_to_slice(cpu) == slice)
                        return cpu;
 
        return -1;
index 66190d7e492d63ad243ba8a4b2dc5590e00a7ee3..ab9b5f35c2a72ba9bf6a398029e888dbeed3d129 100644 (file)
@@ -21,6 +21,8 @@
 #include <asm/sn/types.h>
 #include <asm/sn/shubio.h>
 #include <asm/sn/tiocx.h>
+#include <asm/sn/l1.h>
+#include <asm/sn/module.h>
 #include "tio.h"
 #include "xtalk/xwidgetdev.h"
 #include "xtalk/hubdev.h"
@@ -308,14 +310,12 @@ void tiocx_irq_free(struct sn_irq_info *sn_irq_info)
        }
 }
 
-uint64_t
-tiocx_dma_addr(uint64_t addr)
+uint64_t tiocx_dma_addr(uint64_t addr)
 {
        return PHYS_TO_TIODMA(addr);
 }
 
-uint64_t
-tiocx_swin_base(int nasid)
+uint64_t tiocx_swin_base(int nasid)
 {
        return TIO_SWIN_BASE(nasid, TIOCX_CORELET);
 }
@@ -330,19 +330,6 @@ EXPORT_SYMBOL(tiocx_bus_type);
 EXPORT_SYMBOL(tiocx_dma_addr);
 EXPORT_SYMBOL(tiocx_swin_base);
 
-static uint64_t tiocx_get_hubdev_info(u64 handle, u64 address)
-{
-
-       struct ia64_sal_retval ret_stuff;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       ia64_sal_oemcall_nolock(&ret_stuff,
-                               SN_SAL_IOIF_GET_HUBDEV_INFO,
-                               handle, address, 0, 0, 0, 0, 0);
-       return ret_stuff.v0;
-}
-
 static void tio_conveyor_set(nasid_t nasid, int enable_flag)
 {
        uint64_t ice_frz;
@@ -379,7 +366,29 @@ static void tio_corelet_reset(nasid_t nasid, int corelet)
        udelay(2000);
 }
 
-static int fpga_attached(nasid_t nasid)
+static int tiocx_btchar_get(int nasid)
+{
+       moduleid_t module_id;
+       geoid_t geoid;
+       int cnodeid;
+
+       cnodeid = nasid_to_cnodeid(nasid);
+       geoid = cnodeid_get_geoid(cnodeid);
+       module_id = geo_module(geoid);
+       return MODULE_GET_BTCHAR(module_id);
+}
+
+static int is_fpga_brick(int nasid)
+{
+       switch (tiocx_btchar_get(nasid)) {
+       case L1_BRICKTYPE_SA:
+       case L1_BRICKTYPE_ATHENA:
+               return 1;
+       }
+       return 0;
+}
+
+static int bitstream_loaded(nasid_t nasid)
 {
        uint64_t cx_credits;
 
@@ -396,7 +405,7 @@ static int tiocx_reload(struct cx_dev *cx_dev)
        int mfg_num = CX_DEV_NONE;
        nasid_t nasid = cx_dev->cx_id.nasid;
 
-       if (fpga_attached(nasid)) {
+       if (bitstream_loaded(nasid)) {
                uint64_t cx_id;
 
                cx_id =
@@ -427,9 +436,10 @@ static ssize_t show_cxdev_control(struct device *dev, char *buf)
 {
        struct cx_dev *cx_dev = to_cx_dev(dev);
 
-       return sprintf(buf, "0x%x 0x%x 0x%x\n",
+       return sprintf(buf, "0x%x 0x%x 0x%x %d\n",
                       cx_dev->cx_id.nasid,
-                      cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num);
+                      cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num,
+                      tiocx_btchar_get(cx_dev->cx_id.nasid));
 }
 
 static ssize_t store_cxdev_control(struct device *dev, const char *buf,
@@ -475,20 +485,14 @@ static int __init tiocx_init(void)
                if ((nasid = cnodeid_to_nasid(cnodeid)) < 0)
                        break;  /* No more nasids .. bail out of loop */
 
-               if (nasid & 0x1) {      /* TIO's are always odd */
+               if ((nasid & 0x1) && is_fpga_brick(nasid)) {
                        struct hubdev_info *hubdev;
-                       uint64_t status;
                        struct xwidget_info *widgetp;
 
                        DBG("Found TIO at nasid 0x%x\n", nasid);
 
                        hubdev =
                            (struct hubdev_info *)(NODEPDA(cnodeid)->pdinfo);
-                       status =
-                           tiocx_get_hubdev_info(nasid,
-                                                 (uint64_t) __pa(hubdev));
-                       if (status)
-                               continue;
 
                        widgetp = &hubdev->hdi_xwidget_info[TIOCX_CORELET];
 
diff --git a/arch/ia64/sn/kernel/xp_main.c b/arch/ia64/sn/kernel/xp_main.c
new file mode 100644 (file)
index 0000000..3be52a3
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * 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-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+
+/*
+ * Cross Partition (XP) base.
+ *
+ *     XP provides a base from which its users can interact
+ *     with XPC, yet not be dependent on XPC.
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/xp.h>
+
+
+/*
+ * Target of nofault PIO read.
+ */
+u64 xp_nofault_PIOR_target;
+
+
+/*
+ * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
+ * users of XPC.
+ */
+struct xpc_registration xpc_registrations[XPC_NCHANNELS];
+
+
+/*
+ * Initialize the XPC interface to indicate that XPC isn't loaded.
+ */
+static enum xpc_retval xpc_notloaded(void) { return xpcNotLoaded; }
+
+struct xpc_interface xpc_interface = {
+       (void (*)(int)) xpc_notloaded,
+       (void (*)(int)) xpc_notloaded,
+       (enum xpc_retval (*)(partid_t, int, u32, void **)) xpc_notloaded,
+       (enum xpc_retval (*)(partid_t, int, void *)) xpc_notloaded,
+       (enum xpc_retval (*)(partid_t, int, void *, xpc_notify_func, void *))
+                                                       xpc_notloaded,
+       (void (*)(partid_t, int, void *)) xpc_notloaded,
+       (enum xpc_retval (*)(partid_t, void *)) xpc_notloaded
+};
+
+
+/*
+ * XPC calls this when it (the XPC module) has been loaded.
+ */
+void
+xpc_set_interface(void (*connect)(int),
+               void (*disconnect)(int),
+               enum xpc_retval (*allocate)(partid_t, int, u32, void **),
+               enum xpc_retval (*send)(partid_t, int, void *),
+               enum xpc_retval (*send_notify)(partid_t, int, void *,
+                                               xpc_notify_func, void *),
+               void (*received)(partid_t, int, void *),
+               enum xpc_retval (*partid_to_nasids)(partid_t, void *))
+{
+       xpc_interface.connect = connect;
+       xpc_interface.disconnect = disconnect;
+       xpc_interface.allocate = allocate;
+       xpc_interface.send = send;
+       xpc_interface.send_notify = send_notify;
+       xpc_interface.received = received;
+       xpc_interface.partid_to_nasids = partid_to_nasids;
+}
+
+
+/*
+ * XPC calls this when it (the XPC module) is being unloaded.
+ */
+void
+xpc_clear_interface(void)
+{
+       xpc_interface.connect = (void (*)(int)) xpc_notloaded;
+       xpc_interface.disconnect = (void (*)(int)) xpc_notloaded;
+       xpc_interface.allocate = (enum xpc_retval (*)(partid_t, int, u32,
+                                       void **)) xpc_notloaded;
+       xpc_interface.send = (enum xpc_retval (*)(partid_t, int, void *))
+                                       xpc_notloaded;
+       xpc_interface.send_notify = (enum xpc_retval (*)(partid_t, int, void *,
+                                   xpc_notify_func, void *)) xpc_notloaded;
+       xpc_interface.received = (void (*)(partid_t, int, void *))
+                                       xpc_notloaded;
+       xpc_interface.partid_to_nasids = (enum xpc_retval (*)(partid_t, void *))
+                                       xpc_notloaded;
+}
+
+
+/*
+ * Register for automatic establishment of a channel connection whenever
+ * a partition comes up.
+ *
+ * Arguments:
+ *
+ *     ch_number - channel # to register for connection.
+ *     func - function to call for asynchronous notification of channel
+ *            state changes (i.e., connection, disconnection, error) and
+ *            the arrival of incoming messages.
+ *      key - pointer to optional user-defined value that gets passed back
+ *           to the user on any callouts made to func.
+ *     payload_size - size in bytes of the XPC message's payload area which
+ *                    contains a user-defined message. The user should make
+ *                    this large enough to hold their largest message.
+ *     nentries - max #of XPC message entries a message queue can contain.
+ *                The actual number, which is determined when a connection
+ *                is established and may be less then requested, will be
+ *                passed to the user via the xpcConnected callout.
+ *     assigned_limit - max number of kthreads allowed to be processing
+ *                      messages (per connection) at any given instant.
+ *     idle_limit - max number of kthreads allowed to be idle at any given
+ *                  instant.
+ */
+enum xpc_retval
+xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
+               u16 nentries, u32 assigned_limit, u32 idle_limit)
+{
+       struct xpc_registration *registration;
+
+
+       DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
+       DBUG_ON(payload_size == 0 || nentries == 0);
+       DBUG_ON(func == NULL);
+       DBUG_ON(assigned_limit == 0 || idle_limit > assigned_limit);
+
+       registration = &xpc_registrations[ch_number];
+
+       if (down_interruptible(&registration->sema) != 0) {
+               return xpcInterrupted;
+       }
+
+       /* if XPC_CHANNEL_REGISTERED(ch_number) */
+       if (registration->func != NULL) {
+               up(&registration->sema);
+               return xpcAlreadyRegistered;
+       }
+
+       /* register the channel for connection */
+       registration->msg_size = XPC_MSG_SIZE(payload_size);
+       registration->nentries = nentries;
+       registration->assigned_limit = assigned_limit;
+       registration->idle_limit = idle_limit;
+       registration->key = key;
+       registration->func = func;
+
+       up(&registration->sema);
+
+       xpc_interface.connect(ch_number);
+
+       return xpcSuccess;
+}
+
+
+/*
+ * Remove the registration for automatic connection of the specified channel
+ * when a partition comes up.
+ *
+ * Before returning this xpc_disconnect() will wait for all connections on the
+ * specified channel have been closed/torndown. So the caller can be assured
+ * that they will not be receiving any more callouts from XPC to their
+ * function registered via xpc_connect().
+ *
+ * Arguments:
+ *
+ *     ch_number - channel # to unregister.
+ */
+void
+xpc_disconnect(int ch_number)
+{
+       struct xpc_registration *registration;
+
+
+       DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
+
+       registration = &xpc_registrations[ch_number];
+
+       /*
+        * We've decided not to make this a down_interruptible(), since we
+        * figured XPC's users will just turn around and call xpc_disconnect()
+        * again anyways, so we might as well wait, if need be.
+        */
+       down(&registration->sema);
+
+       /* if !XPC_CHANNEL_REGISTERED(ch_number) */
+       if (registration->func == NULL) {
+               up(&registration->sema);
+               return;
+       }
+
+       /* remove the connection registration for the specified channel */
+       registration->func = NULL;
+       registration->key = NULL;
+       registration->nentries = 0;
+       registration->msg_size = 0;
+       registration->assigned_limit = 0;
+       registration->idle_limit = 0;
+
+       xpc_interface.disconnect(ch_number);
+
+       up(&registration->sema);
+
+       return;
+}
+
+
+int __init
+xp_init(void)
+{
+       int ret, ch_number;
+       u64 func_addr = *(u64 *) xp_nofault_PIOR;
+       u64 err_func_addr = *(u64 *) xp_error_PIOR;
+
+
+       if (!ia64_platform_is("sn2")) {
+               return -ENODEV;
+       }
+
+       /*
+        * Register a nofault code region which performs a cross-partition
+        * PIO read. If the PIO read times out, the MCA handler will consume
+        * the error and return to a kernel-provided instruction to indicate
+        * an error. This PIO read exists because it is guaranteed to timeout
+        * if the destination is down (AMO operations do not timeout on at
+        * least some CPUs on Shubs <= v1.2, which unfortunately we have to
+        * work around).
+        */
+       if ((ret = sn_register_nofault_code(func_addr, err_func_addr,
+                                               err_func_addr, 1, 1)) != 0) {
+               printk(KERN_ERR "XP: can't register nofault code, error=%d\n",
+                       ret);
+       }
+       /*
+        * Setup the nofault PIO read target. (There is no special reason why
+        * SH_IPI_ACCESS was selected.)
+        */
+       if (is_shub2()) {
+               xp_nofault_PIOR_target = SH2_IPI_ACCESS0;
+       } else {
+               xp_nofault_PIOR_target = SH1_IPI_ACCESS;
+       }
+
+       /* initialize the connection registration semaphores */
+       for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
+               sema_init(&xpc_registrations[ch_number].sema, 1);  /* mutex */
+       }
+
+       return 0;
+}
+module_init(xp_init);
+
+
+void __exit
+xp_exit(void)
+{
+       u64 func_addr = *(u64 *) xp_nofault_PIOR;
+       u64 err_func_addr = *(u64 *) xp_error_PIOR;
+
+
+       /* unregister the PIO read nofault code region */
+       (void) sn_register_nofault_code(func_addr, err_func_addr,
+                                       err_func_addr, 1, 0);
+}
+module_exit(xp_exit);
+
+
+MODULE_AUTHOR("Silicon Graphics, Inc.");
+MODULE_DESCRIPTION("Cross Partition (XP) base");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(xp_nofault_PIOR);
+EXPORT_SYMBOL(xp_nofault_PIOR_target);
+EXPORT_SYMBOL(xpc_registrations);
+EXPORT_SYMBOL(xpc_interface);
+EXPORT_SYMBOL(xpc_clear_interface);
+EXPORT_SYMBOL(xpc_set_interface);
+EXPORT_SYMBOL(xpc_connect);
+EXPORT_SYMBOL(xpc_disconnect);
+
diff --git a/arch/ia64/sn/kernel/xp_nofault.S b/arch/ia64/sn/kernel/xp_nofault.S
new file mode 100644 (file)
index 0000000..b772543
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+
+/*
+ * The xp_nofault_PIOR function takes a pointer to a remote PIO register
+ * and attempts to load and consume a value from it.  This function
+ * will be registered as a nofault code block.  In the event that the
+ * PIO read fails, the MCA handler will force the error to look
+ * corrected and vector to the xp_error_PIOR which will return an error.
+ *
+ *     extern int xp_nofault_PIOR(void *remote_register);
+ */
+
+       .global xp_nofault_PIOR
+xp_nofault_PIOR:
+       mov     r8=r0                   // Stage a success return value
+       ld8.acq r9=[r32];;              // PIO Read the specified register
+       adds    r9=1,r9                 // Add to force a consume
+       br.ret.sptk.many b0;;           // Return success
+
+       .global xp_error_PIOR
+xp_error_PIOR:
+       mov     r8=1                    // Return value of 1
+       br.ret.sptk.many b0;;           // Return failure
+
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
new file mode 100644 (file)
index 0000000..1a0aed8
--- /dev/null
@@ -0,0 +1,991 @@
+/*
+ * 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-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+
+/*
+ * Cross Partition Communication (XPC) structures and macros.
+ */
+
+#ifndef _IA64_SN_KERNEL_XPC_H
+#define _IA64_SN_KERNEL_XPC_H
+
+
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/sysctl.h>
+#include <linux/device.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/sn/bte.h>
+#include <asm/sn/clksupport.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/mspec.h>
+#include <asm/sn/shub_mmr.h>
+#include <asm/sn/xp.h>
+
+
+/*
+ * XPC Version numbers consist of a major and minor number. XPC can always
+ * talk to versions with same major #, and never talk to versions with a
+ * different major #.
+ */
+#define _XPC_VERSION(_maj, _min)       (((_maj) << 4) | ((_min) & 0xf))
+#define XPC_VERSION_MAJOR(_v)          ((_v) >> 4)
+#define XPC_VERSION_MINOR(_v)          ((_v) & 0xf)
+
+
+/*
+ * The next macros define word or bit representations for given
+ * C-brick nasid in either the SAL provided bit array representing
+ * nasids in the partition/machine or the AMO_t array used for
+ * inter-partition initiation communications.
+ *
+ * For SN2 machines, C-Bricks are alway even numbered NASIDs.  As
+ * such, some space will be saved by insisting that nasid information
+ * passed from SAL always be packed for C-Bricks and the
+ * cross-partition interrupts use the same packing scheme.
+ */
+#define XPC_NASID_W_INDEX(_n)  (((_n) / 64) / 2)
+#define XPC_NASID_B_INDEX(_n)  (((_n) / 2) & (64 - 1))
+#define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[XPC_NASID_W_INDEX(_n)] & \
+                                   (1UL << XPC_NASID_B_INDEX(_n)))
+#define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2)
+
+#define XPC_HB_DEFAULT_INTERVAL                5       /* incr HB every x secs */
+#define XPC_HB_CHECK_DEFAULT_TIMEOUT   20      /* check HB every x secs */
+
+/* define the process name of HB checker and the CPU it is pinned to */
+#define XPC_HB_CHECK_THREAD_NAME       "xpc_hb"
+#define XPC_HB_CHECK_CPU               0
+
+/* define the process name of the discovery thread */
+#define XPC_DISCOVERY_THREAD_NAME      "xpc_discovery"
+
+
+#define XPC_HB_ALLOWED(_p, _v) ((_v)->heartbeating_to_mask & (1UL << (_p)))
+#define XPC_ALLOW_HB(_p, _v)   (_v)->heartbeating_to_mask |= (1UL << (_p))
+#define XPC_DISALLOW_HB(_p, _v)        (_v)->heartbeating_to_mask &= (~(1UL << (_p)))
+
+
+/*
+ * Reserved Page provided by SAL.
+ *
+ * SAL provides one page per partition of reserved memory.  When SAL
+ * initialization is complete, SAL_signature, SAL_version, partid,
+ * part_nasids, and mach_nasids are set.
+ *
+ * Note: Until vars_pa is set, the partition XPC code has not been initialized.
+ */
+struct xpc_rsvd_page {
+       u64 SAL_signature;      /* SAL unique signature */
+       u64 SAL_version;        /* SAL specified version */
+       u8 partid;              /* partition ID from SAL */
+       u8 version;
+       u8 pad[6];              /* pad to u64 align */
+       u64 vars_pa;
+       u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
+       u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
+};
+#define XPC_RP_VERSION _XPC_VERSION(1,0) /* version 1.0 of the reserved page */
+
+#define XPC_RSVD_PAGE_ALIGNED_SIZE \
+                       (L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page)))
+
+
+/*
+ * Define the structures by which XPC variables can be exported to other
+ * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
+ */
+
+/*
+ * The following structure describes the partition generic variables
+ * needed by other partitions in order to properly initialize.
+ *
+ * struct xpc_vars version number also applies to struct xpc_vars_part.
+ * Changes to either structure and/or related functionality should be
+ * reflected by incrementing either the major or minor version numbers
+ * of struct xpc_vars.
+ */
+struct xpc_vars {
+       u8 version;
+       u64 heartbeat;
+       u64 heartbeating_to_mask;
+       u64 kdb_status;         /* 0 = machine running */
+       int act_nasid;
+       int act_phys_cpuid;
+       u64 vars_part_pa;
+       u64 amos_page_pa;       /* paddr of page of AMOs from MSPEC driver */
+       AMO_t *amos_page;       /* vaddr of page of AMOs from MSPEC driver */
+       AMO_t *act_amos;        /* pointer to the first activation AMO */
+};
+#define XPC_V_VERSION _XPC_VERSION(3,0) /* version 3.0 of the cross vars */
+
+#define XPC_VARS_ALIGNED_SIZE  (L1_CACHE_ALIGN(sizeof(struct xpc_vars)))
+
+/*
+ * The following structure describes the per partition specific variables.
+ *
+ * An array of these structures, one per partition, will be defined. As a
+ * partition becomes active XPC will copy the array entry corresponding to
+ * itself from that partition. It is desirable that the size of this
+ * structure evenly divide into a cacheline, such that none of the entries
+ * in this array crosses a cacheline boundary. As it is now, each entry
+ * occupies half a cacheline.
+ */
+struct xpc_vars_part {
+       u64 magic;
+
+       u64 openclose_args_pa;  /* physical address of open and close args */
+       u64 GPs_pa;             /* physical address of Get/Put values */
+
+       u64 IPI_amo_pa;         /* physical address of IPI AMO_t structure */
+       int IPI_nasid;          /* nasid of where to send IPIs */
+       int IPI_phys_cpuid;     /* physical CPU ID of where to send IPIs */
+
+       u8 nchannels;           /* #of defined channels supported */
+
+       u8 reserved[23];        /* pad to a full 64 bytes */
+};
+
+/*
+ * The vars_part MAGIC numbers play a part in the first contact protocol.
+ *
+ * MAGIC1 indicates that the per partition specific variables for a remote
+ * partition have been initialized by this partition.
+ *
+ * MAGIC2 indicates that this partition has pulled the remote partititions
+ * per partition variables that pertain to this partition.
+ */
+#define XPC_VP_MAGIC1  0x0053524156435058L  /* 'XPCVARS\0'L (little endian) */
+#define XPC_VP_MAGIC2  0x0073726176435058L  /* 'XPCvars\0'L (little endian) */
+
+
+
+/*
+ * Functions registered by add_timer() or called by kernel_thread() only
+ * allow for a single 64-bit argument. The following macros can be used to
+ * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from
+ * the passed argument.
+ */
+#define XPC_PACK_ARGS(_arg1, _arg2) \
+                       ((((u64) _arg1) & 0xffffffff) | \
+                       ((((u64) _arg2) & 0xffffffff) << 32))
+
+#define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff)
+#define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff)
+
+
+
+/*
+ * Define a Get/Put value pair (pointers) used with a message queue.
+ */
+struct xpc_gp {
+       s64 get;        /* Get value */
+       s64 put;        /* Put value */
+};
+
+#define XPC_GP_SIZE \
+               L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS)
+
+
+
+/*
+ * Define a structure that contains arguments associated with opening and
+ * closing a channel.
+ */
+struct xpc_openclose_args {
+       u16 reason;             /* reason why channel is closing */
+       u16 msg_size;           /* sizeof each message entry */
+       u16 remote_nentries;    /* #of message entries in remote msg queue */
+       u16 local_nentries;     /* #of message entries in local msg queue */
+       u64 local_msgqueue_pa;  /* physical address of local message queue */
+};
+
+#define XPC_OPENCLOSE_ARGS_SIZE \
+             L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS)
+
+
+
+/* struct xpc_msg flags */
+
+#define        XPC_M_DONE              0x01    /* msg has been received/consumed */
+#define        XPC_M_READY             0x02    /* msg is ready to be sent */
+#define        XPC_M_INTERRUPT         0x04    /* send interrupt when msg consumed */
+
+
+#define XPC_MSG_ADDRESS(_payload) \
+               ((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET))
+
+
+
+/*
+ * Defines notify entry.
+ *
+ * This is used to notify a message's sender that their message was received
+ * and consumed by the intended recipient.
+ */
+struct xpc_notify {
+       struct semaphore sema;          /* notify semaphore */
+       u8 type;                        /* type of notification */
+
+       /* the following two fields are only used if type == XPC_N_CALL */
+       xpc_notify_func func;           /* user's notify function */
+       void *key;                      /* pointer to user's key */
+};
+
+/* struct xpc_notify type of notification */
+
+#define        XPC_N_CALL              0x01    /* notify function provided by user */
+
+
+
+/*
+ * Define the structure that manages all the stuff required by a channel. In
+ * particular, they are used to manage the messages sent across the channel.
+ *
+ * This structure is private to a partition, and is NOT shared across the
+ * partition boundary.
+ *
+ * There is an array of these structures for each remote partition. It is
+ * allocated at the time a partition becomes active. The array contains one
+ * of these structures for each potential channel connection to that partition.
+ *
+ * Each of these structures manages two message queues (circular buffers).
+ * They are allocated at the time a channel connection is made. One of
+ * these message queues (local_msgqueue) holds the locally created messages
+ * that are destined for the remote partition. The other of these message
+ * queues (remote_msgqueue) is a locally cached copy of the remote partition's
+ * own local_msgqueue.
+ *
+ * The following is a description of the Get/Put pointers used to manage these
+ * two message queues. Consider the local_msgqueue to be on one partition
+ * and the remote_msgqueue to be its cached copy on another partition. A
+ * description of what each of the lettered areas contains is included.
+ *
+ *
+ *                     local_msgqueue      remote_msgqueue
+ *
+ *                        |/////////|      |/////////|
+ *    w_remote_GP.get --> +---------+      |/////////|
+ *                        |    F    |      |/////////|
+ *     remote_GP.get  --> +---------+      +---------+ <-- local_GP->get
+ *                        |         |      |         |
+ *                        |         |      |    E    |
+ *                        |         |      |         |
+ *                        |         |      +---------+ <-- w_local_GP.get
+ *                        |    B    |      |/////////|
+ *                        |         |      |////D////|
+ *                        |         |      |/////////|
+ *                        |         |      +---------+ <-- w_remote_GP.put
+ *                        |         |      |////C////|
+ *      local_GP->put --> +---------+      +---------+ <-- remote_GP.put
+ *                        |         |      |/////////|
+ *                        |    A    |      |/////////|
+ *                        |         |      |/////////|
+ *     w_local_GP.put --> +---------+      |/////////|
+ *                        |/////////|      |/////////|
+ *
+ *
+ *         ( remote_GP.[get|put] are cached copies of the remote
+ *           partition's local_GP->[get|put], and thus their values can
+ *           lag behind their counterparts on the remote partition. )
+ *
+ *
+ *  A - Messages that have been allocated, but have not yet been sent to the
+ *     remote partition.
+ *
+ *  B - Messages that have been sent, but have not yet been acknowledged by the
+ *      remote partition as having been received.
+ *
+ *  C - Area that needs to be prepared for the copying of sent messages, by
+ *     the clearing of the message flags of any previously received messages.
+ *
+ *  D - Area into which sent messages are to be copied from the remote
+ *     partition's local_msgqueue and then delivered to their intended
+ *     recipients. [ To allow for a multi-message copy, another pointer
+ *     (next_msg_to_pull) has been added to keep track of the next message
+ *     number needing to be copied (pulled). It chases after w_remote_GP.put.
+ *     Any messages lying between w_local_GP.get and next_msg_to_pull have
+ *     been copied and are ready to be delivered. ]
+ *
+ *  E - Messages that have been copied and delivered, but have not yet been
+ *     acknowledged by the recipient as having been received.
+ *
+ *  F - Messages that have been acknowledged, but XPC has not yet notified the
+ *     sender that the message was received by its intended recipient.
+ *     This is also an area that needs to be prepared for the allocating of
+ *     new messages, by the clearing of the message flags of the acknowledged
+ *     messages.
+ */
+struct xpc_channel {
+       partid_t partid;                /* ID of remote partition connected */
+       spinlock_t lock;                /* lock for updating this structure */
+       u32 flags;                      /* general flags */
+
+       enum xpc_retval reason;         /* reason why channel is disconnect'g */
+       int reason_line;                /* line# disconnect initiated from */
+
+       u16 number;                     /* channel # */
+
+       u16 msg_size;                   /* sizeof each msg entry */
+       u16 local_nentries;             /* #of msg entries in local msg queue */
+       u16 remote_nentries;            /* #of msg entries in remote msg queue*/
+
+       void *local_msgqueue_base;      /* base address of kmalloc'd space */
+       struct xpc_msg *local_msgqueue; /* local message queue */
+       void *remote_msgqueue_base;     /* base address of kmalloc'd space */
+       struct xpc_msg *remote_msgqueue;/* cached copy of remote partition's */
+                                       /* local message queue */
+       u64 remote_msgqueue_pa;         /* phys addr of remote partition's */
+                                       /* local message queue */
+
+       atomic_t references;            /* #of external references to queues */
+
+       atomic_t n_on_msg_allocate_wq;   /* #on msg allocation wait queue */
+       wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */
+
+       /* queue of msg senders who want to be notified when msg received */
+
+       atomic_t n_to_notify;           /* #of msg senders to notify */
+       struct xpc_notify *notify_queue;/* notify queue for messages sent */
+
+       xpc_channel_func func;          /* user's channel function */
+       void *key;                      /* pointer to user's key */
+
+       struct semaphore msg_to_pull_sema; /* next msg to pull serialization */
+       struct semaphore teardown_sema;    /* wait for teardown completion */
+
+       struct xpc_openclose_args *local_openclose_args; /* args passed on */
+                                       /* opening or closing of channel */
+
+       /* various flavors of local and remote Get/Put values */
+
+       struct xpc_gp *local_GP;        /* local Get/Put values */
+       struct xpc_gp remote_GP;        /* remote Get/Put values */
+       struct xpc_gp w_local_GP;       /* working local Get/Put values */
+       struct xpc_gp w_remote_GP;      /* working remote Get/Put values */
+       s64 next_msg_to_pull;           /* Put value of next msg to pull */
+
+       /* kthread management related fields */
+
+// >>> rethink having kthreads_assigned_limit and kthreads_idle_limit; perhaps
+// >>> allow the assigned limit be unbounded and let the idle limit be dynamic
+// >>> dependent on activity over the last interval of time
+       atomic_t kthreads_assigned;     /* #of kthreads assigned to channel */
+       u32 kthreads_assigned_limit;    /* limit on #of kthreads assigned */
+       atomic_t kthreads_idle;         /* #of kthreads idle waiting for work */
+       u32 kthreads_idle_limit;        /* limit on #of kthreads idle */
+       atomic_t kthreads_active;       /* #of kthreads actively working */
+       // >>> following field is temporary
+       u32 kthreads_created;           /* total #of kthreads created */
+
+       wait_queue_head_t idle_wq;      /* idle kthread wait queue */
+
+} ____cacheline_aligned;
+
+
+/* struct xpc_channel flags */
+
+#define        XPC_C_WASCONNECTED      0x00000001 /* channel was connected */
+
+#define        XPC_C_ROPENREPLY        0x00000002 /* remote open channel reply */
+#define        XPC_C_OPENREPLY         0x00000004 /* local open channel reply */
+#define        XPC_C_ROPENREQUEST      0x00000008 /* remote open channel request */
+#define        XPC_C_OPENREQUEST       0x00000010 /* local open channel request */
+
+#define        XPC_C_SETUP             0x00000020 /* channel's msgqueues are alloc'd */
+#define        XPC_C_CONNECTCALLOUT    0x00000040 /* channel connected callout made */
+#define        XPC_C_CONNECTED         0x00000080 /* local channel is connected */
+#define        XPC_C_CONNECTING        0x00000100 /* channel is being connected */
+
+#define        XPC_C_RCLOSEREPLY       0x00000200 /* remote close channel reply */
+#define        XPC_C_CLOSEREPLY        0x00000400 /* local close channel reply */
+#define        XPC_C_RCLOSEREQUEST     0x00000800 /* remote close channel request */
+#define        XPC_C_CLOSEREQUEST      0x00001000 /* local close channel request */
+
+#define        XPC_C_DISCONNECTED      0x00002000 /* channel is disconnected */
+#define        XPC_C_DISCONNECTING     0x00004000 /* channel is being disconnected */
+
+
+
+/*
+ * Manages channels on a partition basis. There is one of these structures
+ * for each partition (a partition will never utilize the structure that
+ * represents itself).
+ */
+struct xpc_partition {
+
+       /* XPC HB infrastructure */
+
+       u64 remote_rp_pa;               /* phys addr of partition's rsvd pg */
+       u64 remote_vars_pa;             /* phys addr of partition's vars */
+       u64 remote_vars_part_pa;        /* phys addr of partition's vars part */
+       u64 last_heartbeat;             /* HB at last read */
+       u64 remote_amos_page_pa;        /* phys addr of partition's amos page */
+       int remote_act_nasid;           /* active part's act/deact nasid */
+       int remote_act_phys_cpuid;      /* active part's act/deact phys cpuid */
+       u32 act_IRQ_rcvd;               /* IRQs since activation */
+       spinlock_t act_lock;            /* protect updating of act_state */
+       u8 act_state;                   /* from XPC HB viewpoint */
+       enum xpc_retval reason;         /* reason partition is deactivating */
+       int reason_line;                /* line# deactivation initiated from */
+       int reactivate_nasid;           /* nasid in partition to reactivate */
+
+
+       /* XPC infrastructure referencing and teardown control */
+
+       u8 setup_state;                 /* infrastructure setup state */
+       wait_queue_head_t teardown_wq;  /* kthread waiting to teardown infra */
+       atomic_t references;            /* #of references to infrastructure */
+
+
+       /*
+        * NONE OF THE PRECEDING FIELDS OF THIS STRUCTURE WILL BE CLEARED WHEN
+        * XPC SETS UP THE NECESSARY INFRASTRUCTURE TO SUPPORT CROSS PARTITION
+        * COMMUNICATION. ALL OF THE FOLLOWING FIELDS WILL BE CLEARED. (THE
+        * 'nchannels' FIELD MUST BE THE FIRST OF THE FIELDS TO BE CLEARED.)
+        */
+
+
+       u8 nchannels;              /* #of defined channels supported */
+       atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */
+       struct xpc_channel *channels;/* array of channel structures */
+
+       void *local_GPs_base;     /* base address of kmalloc'd space */
+       struct xpc_gp *local_GPs; /* local Get/Put values */
+       void *remote_GPs_base;    /* base address of kmalloc'd space */
+       struct xpc_gp *remote_GPs;/* copy of remote partition's local Get/Put */
+                                 /* values */
+       u64 remote_GPs_pa;        /* phys address of remote partition's local */
+                                 /* Get/Put values */
+
+
+       /* fields used to pass args when opening or closing a channel */
+
+       void *local_openclose_args_base;  /* base address of kmalloc'd space */
+       struct xpc_openclose_args *local_openclose_args;  /* local's args */
+       void *remote_openclose_args_base; /* base address of kmalloc'd space */
+       struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
+                                         /* args */
+       u64 remote_openclose_args_pa;     /* phys addr of remote's args */
+
+
+       /* IPI sending, receiving and handling related fields */
+
+       int remote_IPI_nasid;       /* nasid of where to send IPIs */
+       int remote_IPI_phys_cpuid;  /* phys CPU ID of where to send IPIs */
+       AMO_t *remote_IPI_amo_va;   /* address of remote IPI AMO_t structure */
+
+       AMO_t *local_IPI_amo_va;    /* address of IPI AMO_t structure */
+       u64 local_IPI_amo;          /* IPI amo flags yet to be handled */
+       char IPI_owner[8];          /* IPI owner's name */
+       struct timer_list dropped_IPI_timer; /* dropped IPI timer */
+
+       spinlock_t IPI_lock;        /* IPI handler lock */
+
+
+       /* channel manager related fields */
+
+       atomic_t channel_mgr_requests;  /* #of requests to activate chan mgr */
+       wait_queue_head_t channel_mgr_wq; /* channel mgr's wait queue */
+
+} ____cacheline_aligned;
+
+
+/* struct xpc_partition act_state values (for XPC HB) */
+
+#define        XPC_P_INACTIVE          0x00    /* partition is not active */
+#define XPC_P_ACTIVATION_REQ   0x01    /* created thread to activate */
+#define XPC_P_ACTIVATING       0x02    /* activation thread started */
+#define XPC_P_ACTIVE           0x03    /* xpc_partition_up() was called */
+#define XPC_P_DEACTIVATING     0x04    /* partition deactivation initiated */
+
+
+#define XPC_DEACTIVATE_PARTITION(_p, _reason) \
+                       xpc_deactivate_partition(__LINE__, (_p), (_reason))
+
+
+/* struct xpc_partition setup_state values */
+
+#define XPC_P_UNSET            0x00    /* infrastructure was never setup */
+#define XPC_P_SETUP            0x01    /* infrastructure is setup */
+#define XPC_P_WTEARDOWN                0x02    /* waiting to teardown infrastructure */
+#define XPC_P_TORNDOWN         0x03    /* infrastructure is torndown */
+
+
+/*
+ * struct xpc_partition IPI_timer #of seconds to wait before checking for
+ * dropped IPIs. These occur whenever an IPI amo write doesn't complete until
+ * after the IPI was received.
+ */
+#define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ)
+
+
+#define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0]))
+
+
+
+/* found in xp_main.c */
+extern struct xpc_registration xpc_registrations[];
+
+
+/* >>> found in xpc_main.c only */
+extern struct device *xpc_part;
+extern struct device *xpc_chan;
+extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *);
+extern void xpc_dropped_IPI_check(struct xpc_partition *);
+extern void xpc_activate_kthreads(struct xpc_channel *, int);
+extern void xpc_create_kthreads(struct xpc_channel *, int);
+extern void xpc_disconnect_wait(int);
+
+
+/* found in xpc_main.c and efi-xpc.c */
+extern void xpc_activate_partition(struct xpc_partition *);
+
+
+/* found in xpc_partition.c */
+extern int xpc_exiting;
+extern int xpc_hb_interval;
+extern int xpc_hb_check_interval;
+extern struct xpc_vars *xpc_vars;
+extern struct xpc_rsvd_page *xpc_rsvd_page;
+extern struct xpc_vars_part *xpc_vars_part;
+extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
+extern char xpc_remote_copy_buffer[];
+extern struct xpc_rsvd_page *xpc_rsvd_page_init(void);
+extern void xpc_allow_IPI_ops(void);
+extern void xpc_restrict_IPI_ops(void);
+extern int xpc_identify_act_IRQ_sender(void);
+extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *);
+extern void xpc_mark_partition_inactive(struct xpc_partition *);
+extern void xpc_discovery(void);
+extern void xpc_check_remote_hb(void);
+extern void xpc_deactivate_partition(const int, struct xpc_partition *,
+                                               enum xpc_retval);
+extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *);
+
+
+/* found in xpc_channel.c */
+extern void xpc_initiate_connect(int);
+extern void xpc_initiate_disconnect(int);
+extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **);
+extern enum xpc_retval xpc_initiate_send(partid_t, int, void *);
+extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *,
+                                               xpc_notify_func, void *);
+extern void xpc_initiate_received(partid_t, int, void *);
+extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *);
+extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *);
+extern void xpc_process_channel_activity(struct xpc_partition *);
+extern void xpc_connected_callout(struct xpc_channel *);
+extern void xpc_deliver_msg(struct xpc_channel *);
+extern void xpc_disconnect_channel(const int, struct xpc_channel *,
+                                       enum xpc_retval, unsigned long *);
+extern void xpc_disconnected_callout(struct xpc_channel *);
+extern void xpc_partition_down(struct xpc_partition *, enum xpc_retval);
+extern void xpc_teardown_infrastructure(struct xpc_partition *);
+
+
+
+static inline void
+xpc_wakeup_channel_mgr(struct xpc_partition *part)
+{
+       if (atomic_inc_return(&part->channel_mgr_requests) == 1) {
+               wake_up(&part->channel_mgr_wq);
+       }
+}
+
+
+
+/*
+ * These next two inlines are used to keep us from tearing down a channel's
+ * msg queues while a thread may be referencing them.
+ */
+static inline void
+xpc_msgqueue_ref(struct xpc_channel *ch)
+{
+       atomic_inc(&ch->references);
+}
+
+static inline void
+xpc_msgqueue_deref(struct xpc_channel *ch)
+{
+       s32 refs = atomic_dec_return(&ch->references);
+
+       DBUG_ON(refs < 0);
+       if (refs == 0) {
+               xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
+       }
+}
+
+
+
+#define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
+               xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
+
+
+/*
+ * These two inlines are used to keep us from tearing down a partition's
+ * setup infrastructure while a thread may be referencing it.
+ */
+static inline void
+xpc_part_deref(struct xpc_partition *part)
+{
+       s32 refs = atomic_dec_return(&part->references);
+
+
+       DBUG_ON(refs < 0);
+       if (refs == 0 && part->setup_state == XPC_P_WTEARDOWN) {
+               wake_up(&part->teardown_wq);
+       }
+}
+
+static inline int
+xpc_part_ref(struct xpc_partition *part)
+{
+       int setup;
+
+
+       atomic_inc(&part->references);
+       setup = (part->setup_state == XPC_P_SETUP);
+       if (!setup) {
+               xpc_part_deref(part);
+       }
+       return setup;
+}
+
+
+
+/*
+ * The following macro is to be used for the setting of the reason and
+ * reason_line fields in both the struct xpc_channel and struct xpc_partition
+ * structures.
+ */
+#define XPC_SET_REASON(_p, _reason, _line) \
+       { \
+               (_p)->reason = _reason; \
+               (_p)->reason_line = _line; \
+       }
+
+
+
+/*
+ * The following set of macros and inlines are used for the sending and
+ * receiving of IPIs (also known as IRQs). There are two flavors of IPIs,
+ * one that is associated with partition activity (SGI_XPC_ACTIVATE) and
+ * the other that is associated with channel activity (SGI_XPC_NOTIFY).
+ */
+
+static inline u64
+xpc_IPI_receive(AMO_t *amo)
+{
+       return FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_CLEAR);
+}
+
+
+static inline enum xpc_retval
+xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
+{
+       int ret = 0;
+       unsigned long irq_flags;
+
+
+       local_irq_save(irq_flags);
+
+       FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, flag);
+       sn_send_IPI_phys(nasid, phys_cpuid, vector, 0);
+
+       /*
+        * We must always use the nofault function regardless of whether we
+        * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
+        * didn't, we'd never know that the other partition is down and would
+        * keep sending IPIs and AMOs to it until the heartbeat times out.
+        */
+       ret = xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->variable),
+                               xp_nofault_PIOR_target));
+
+       local_irq_restore(irq_flags);
+
+       return ((ret == 0) ? xpcSuccess : xpcPioReadError);
+}
+
+
+/*
+ * IPIs associated with SGI_XPC_ACTIVATE IRQ.
+ */
+
+/*
+ * Flag the appropriate AMO variable and send an IPI to the specified node.
+ */
+static inline void
+xpc_activate_IRQ_send(u64 amos_page, int from_nasid, int to_nasid,
+                       int to_phys_cpuid)
+{
+       int w_index = XPC_NASID_W_INDEX(from_nasid);
+       int b_index = XPC_NASID_B_INDEX(from_nasid);
+       AMO_t *amos = (AMO_t *) __va(amos_page +
+                                       (XP_MAX_PARTITIONS * sizeof(AMO_t)));
+
+
+       (void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid,
+                               to_phys_cpuid, SGI_XPC_ACTIVATE);
+}
+
+static inline void
+xpc_IPI_send_activate(struct xpc_vars *vars)
+{
+       xpc_activate_IRQ_send(vars->amos_page_pa, cnodeid_to_nasid(0),
+                               vars->act_nasid, vars->act_phys_cpuid);
+}
+
+static inline void
+xpc_IPI_send_activated(struct xpc_partition *part)
+{
+       xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
+                       part->remote_act_nasid, part->remote_act_phys_cpuid);
+}
+
+static inline void
+xpc_IPI_send_reactivate(struct xpc_partition *part)
+{
+       xpc_activate_IRQ_send(xpc_vars->amos_page_pa, part->reactivate_nasid,
+                               xpc_vars->act_nasid, xpc_vars->act_phys_cpuid);
+}
+
+
+/*
+ * IPIs associated with SGI_XPC_NOTIFY IRQ.
+ */
+
+/*
+ * Send an IPI to the remote partition that is associated with the
+ * specified channel.
+ */
+#define XPC_NOTIFY_IRQ_SEND(_ch, _ipi_f, _irq_f) \
+               xpc_notify_IRQ_send(_ch, _ipi_f, #_ipi_f, _irq_f)
+
+static inline void
+xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
+                       unsigned long *irq_flags)
+{
+       struct xpc_partition *part = &xpc_partitions[ch->partid];
+       enum xpc_retval ret;
+
+
+       if (likely(part->act_state != XPC_P_DEACTIVATING)) {
+               ret = xpc_IPI_send(part->remote_IPI_amo_va,
+                                       (u64) ipi_flag << (ch->number * 8),
+                                       part->remote_IPI_nasid,
+                                       part->remote_IPI_phys_cpuid,
+                                       SGI_XPC_NOTIFY);
+               dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
+                       ipi_flag_string, ch->partid, ch->number, ret);
+               if (unlikely(ret != xpcSuccess)) {
+                       if (irq_flags != NULL) {
+                               spin_unlock_irqrestore(&ch->lock, *irq_flags);
+                       }
+                       XPC_DEACTIVATE_PARTITION(part, ret);
+                       if (irq_flags != NULL) {
+                               spin_lock_irqsave(&ch->lock, *irq_flags);
+                       }
+               }
+       }
+}
+
+
+/*
+ * Make it look like the remote partition, which is associated with the
+ * specified channel, sent us an IPI. This faked IPI will be handled
+ * by xpc_dropped_IPI_check().
+ */
+#define XPC_NOTIFY_IRQ_SEND_LOCAL(_ch, _ipi_f) \
+               xpc_notify_IRQ_send_local(_ch, _ipi_f, #_ipi_f)
+
+static inline void
+xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag,
+                               char *ipi_flag_string)
+{
+       struct xpc_partition *part = &xpc_partitions[ch->partid];
+
+
+       FETCHOP_STORE_OP(TO_AMO((u64) &part->local_IPI_amo_va->variable),
+                       FETCHOP_OR, ((u64) ipi_flag << (ch->number * 8)));
+       dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n",
+               ipi_flag_string, ch->partid, ch->number);
+}
+
+
+/*
+ * The sending and receiving of IPIs includes the setting of an AMO variable
+ * to indicate the reason the IPI was sent. The 64-bit variable is divided
+ * up into eight bytes, ordered from right to left. Byte zero pertains to
+ * channel 0, byte one to channel 1, and so on. Each byte is described by
+ * the following IPI flags.
+ */
+
+#define        XPC_IPI_CLOSEREQUEST    0x01
+#define        XPC_IPI_CLOSEREPLY      0x02
+#define        XPC_IPI_OPENREQUEST     0x04
+#define        XPC_IPI_OPENREPLY       0x08
+#define        XPC_IPI_MSGREQUEST      0x10
+
+
+/* given an AMO variable and a channel#, get its associated IPI flags */
+#define XPC_GET_IPI_FLAGS(_amo, _c)    ((u8) (((_amo) >> ((_c) * 8)) & 0xff))
+
+#define        XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f)
+#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo)       ((_amo) & 0x1010101010101010)
+
+
+static inline void
+xpc_IPI_send_closerequest(struct xpc_channel *ch, unsigned long *irq_flags)
+{
+       struct xpc_openclose_args *args = ch->local_openclose_args;
+
+
+       args->reason = ch->reason;
+
+       XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREQUEST, irq_flags);
+}
+
+static inline void
+xpc_IPI_send_closereply(struct xpc_channel *ch, unsigned long *irq_flags)
+{
+       XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREPLY, irq_flags);
+}
+
+static inline void
+xpc_IPI_send_openrequest(struct xpc_channel *ch, unsigned long *irq_flags)
+{
+       struct xpc_openclose_args *args = ch->local_openclose_args;
+
+
+       args->msg_size = ch->msg_size;
+       args->local_nentries = ch->local_nentries;
+
+       XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREQUEST, irq_flags);
+}
+
+static inline void
+xpc_IPI_send_openreply(struct xpc_channel *ch, unsigned long *irq_flags)
+{
+       struct xpc_openclose_args *args = ch->local_openclose_args;
+
+
+       args->remote_nentries = ch->remote_nentries;
+       args->local_nentries = ch->local_nentries;
+       args->local_msgqueue_pa = __pa(ch->local_msgqueue);
+
+       XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREPLY, irq_flags);
+}
+
+static inline void
+xpc_IPI_send_msgrequest(struct xpc_channel *ch)
+{
+       XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_MSGREQUEST, NULL);
+}
+
+static inline void
+xpc_IPI_send_local_msgrequest(struct xpc_channel *ch)
+{
+       XPC_NOTIFY_IRQ_SEND_LOCAL(ch, XPC_IPI_MSGREQUEST);
+}
+
+
+/*
+ * Memory for XPC's AMO variables is allocated by the MSPEC driver. These
+ * pages are located in the lowest granule. The lowest granule uses 4k pages
+ * for cached references and an alternate TLB handler to never provide a
+ * cacheable mapping for the entire region. This will prevent speculative
+ * reading of cached copies of our lines from being issued which will cause
+ * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
+ * (XP_MAX_PARTITIONS) AMO variables for message notification (xpc_main.c)
+ * and an additional 16 AMO variables for partition activation (xpc_hb.c).
+ */
+static inline AMO_t *
+xpc_IPI_init(partid_t partid)
+{
+       AMO_t *part_amo = xpc_vars->amos_page + partid;
+
+
+       xpc_IPI_receive(part_amo);
+       return part_amo;
+}
+
+
+
+static inline enum xpc_retval
+xpc_map_bte_errors(bte_result_t error)
+{
+       switch (error) {
+       case BTE_SUCCESS:       return xpcSuccess;
+       case BTEFAIL_DIR:       return xpcBteDirectoryError;
+       case BTEFAIL_POISON:    return xpcBtePoisonError;
+       case BTEFAIL_WERR:      return xpcBteWriteError;
+       case BTEFAIL_ACCESS:    return xpcBteAccessError;
+       case BTEFAIL_PWERR:     return xpcBtePWriteError;
+       case BTEFAIL_PRERR:     return xpcBtePReadError;
+       case BTEFAIL_TOUT:      return xpcBteTimeOutError;
+       case BTEFAIL_XTERR:     return xpcBteXtalkError;
+       case BTEFAIL_NOTAVAIL:  return xpcBteNotAvailable;
+       default:                return xpcBteUnmappedError;
+       }
+}
+
+
+
+static inline void *
+xpc_kmalloc_cacheline_aligned(size_t size, int flags, void **base)
+{
+       /* see if kmalloc will give us cachline aligned memory by default */
+       *base = kmalloc(size, flags);
+       if (*base == NULL) {
+               return NULL;
+       }
+       if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) {
+               return *base;
+       }
+       kfree(*base);
+
+       /* nope, we'll have to do it ourselves */
+       *base = kmalloc(size + L1_CACHE_BYTES, flags);
+       if (*base == NULL) {
+               return NULL;
+       }
+       return (void *) L1_CACHE_ALIGN((u64) *base);
+}
+
+
+/*
+ * Check to see if there is any channel activity to/from the specified
+ * partition.
+ */
+static inline void
+xpc_check_for_channel_activity(struct xpc_partition *part)
+{
+       u64 IPI_amo;
+       unsigned long irq_flags;
+
+
+       IPI_amo = xpc_IPI_receive(part->local_IPI_amo_va);
+       if (IPI_amo == 0) {
+               return;
+       }
+
+       spin_lock_irqsave(&part->IPI_lock, irq_flags);
+       part->local_IPI_amo |= IPI_amo;
+       spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
+
+       dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n",
+               XPC_PARTID(part), IPI_amo);
+
+       xpc_wakeup_channel_mgr(part);
+}
+
+
+#endif /* _IA64_SN_KERNEL_XPC_H */
+
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
new file mode 100644 (file)
index 0000000..0bf6fbc
--- /dev/null
@@ -0,0 +1,2297 @@
+/*
+ * 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-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+
+/*
+ * Cross Partition Communication (XPC) channel support.
+ *
+ *     This is the part of XPC that manages the channels and
+ *     sends/receives messages across them to/from other partitions.
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/cache.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <asm/sn/bte.h>
+#include <asm/sn/sn_sal.h>
+#include "xpc.h"
+
+
+/*
+ * Set up the initial values for the XPartition Communication channels.
+ */
+static void
+xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
+{
+       int ch_number;
+       struct xpc_channel *ch;
+
+
+       for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
+               ch = &part->channels[ch_number];
+
+               ch->partid = partid;
+               ch->number = ch_number;
+               ch->flags = XPC_C_DISCONNECTED;
+
+               ch->local_GP = &part->local_GPs[ch_number];
+               ch->local_openclose_args =
+                                       &part->local_openclose_args[ch_number];
+
+               atomic_set(&ch->kthreads_assigned, 0);
+               atomic_set(&ch->kthreads_idle, 0);
+               atomic_set(&ch->kthreads_active, 0);
+
+               atomic_set(&ch->references, 0);
+               atomic_set(&ch->n_to_notify, 0);
+
+               spin_lock_init(&ch->lock);
+               sema_init(&ch->msg_to_pull_sema, 1);    /* mutex */
+
+               atomic_set(&ch->n_on_msg_allocate_wq, 0);
+               init_waitqueue_head(&ch->msg_allocate_wq);
+               init_waitqueue_head(&ch->idle_wq);
+       }
+}
+
+
+/*
+ * Setup the infrastructure necessary to support XPartition Communication
+ * between the specified remote partition and the local one.
+ */
+enum xpc_retval
+xpc_setup_infrastructure(struct xpc_partition *part)
+{
+       int ret;
+       struct timer_list *timer;
+       partid_t partid = XPC_PARTID(part);
+
+
+       /*
+        * Zero out MOST of the entry for this partition. Only the fields
+        * starting with `nchannels' will be zeroed. The preceding fields must
+        * remain `viable' across partition ups and downs, since they may be
+        * referenced during this memset() operation.
+        */
+       memset(&part->nchannels, 0, sizeof(struct xpc_partition) -
+                               offsetof(struct xpc_partition, nchannels));
+
+       /*
+        * Allocate all of the channel structures as a contiguous chunk of
+        * memory.
+        */
+       part->channels = kmalloc(sizeof(struct xpc_channel) * XPC_NCHANNELS,
+                                                               GFP_KERNEL);
+       if (part->channels == NULL) {
+               dev_err(xpc_chan, "can't get memory for channels\n");
+               return xpcNoMemory;
+       }
+       memset(part->channels, 0, sizeof(struct xpc_channel) * XPC_NCHANNELS);
+
+       part->nchannels = XPC_NCHANNELS;
+
+
+       /* allocate all the required GET/PUT values */
+
+       part->local_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE,
+                                       GFP_KERNEL, &part->local_GPs_base);
+       if (part->local_GPs == NULL) {
+               kfree(part->channels);
+               part->channels = NULL;
+               dev_err(xpc_chan, "can't get memory for local get/put "
+                       "values\n");
+               return xpcNoMemory;
+       }
+       memset(part->local_GPs, 0, XPC_GP_SIZE);
+
+       part->remote_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE,
+                                       GFP_KERNEL, &part->remote_GPs_base);
+       if (part->remote_GPs == NULL) {
+               kfree(part->channels);
+               part->channels = NULL;
+               kfree(part->local_GPs_base);
+               part->local_GPs = NULL;
+               dev_err(xpc_chan, "can't get memory for remote get/put "
+                       "values\n");
+               return xpcNoMemory;
+       }
+       memset(part->remote_GPs, 0, XPC_GP_SIZE);
+
+
+       /* allocate all the required open and close args */
+
+       part->local_openclose_args = xpc_kmalloc_cacheline_aligned(
+                                       XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL,
+                                       &part->local_openclose_args_base);
+       if (part->local_openclose_args == NULL) {
+               kfree(part->channels);
+               part->channels = NULL;
+               kfree(part->local_GPs_base);
+               part->local_GPs = NULL;
+               kfree(part->remote_GPs_base);
+               part->remote_GPs = NULL;
+               dev_err(xpc_chan, "can't get memory for local connect args\n");
+               return xpcNoMemory;
+       }
+       memset(part->local_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE);
+
+       part->remote_openclose_args = xpc_kmalloc_cacheline_aligned(
+                                       XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL,
+                                       &part->remote_openclose_args_base);
+       if (part->remote_openclose_args == NULL) {
+               kfree(part->channels);
+               part->channels = NULL;
+               kfree(part->local_GPs_base);
+               part->local_GPs = NULL;
+               kfree(part->remote_GPs_base);
+               part->remote_GPs = NULL;
+               kfree(part->local_openclose_args_base);
+               part->local_openclose_args = NULL;
+               dev_err(xpc_chan, "can't get memory for remote connect args\n");
+               return xpcNoMemory;
+       }
+       memset(part->remote_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE);
+
+
+       xpc_initialize_channels(part, partid);
+
+       atomic_set(&part->nchannels_active, 0);
+
+
+       /* local_IPI_amo were set to 0 by an earlier memset() */
+
+       /* Initialize this partitions AMO_t structure */
+       part->local_IPI_amo_va = xpc_IPI_init(partid);
+
+       spin_lock_init(&part->IPI_lock);
+
+       atomic_set(&part->channel_mgr_requests, 1);
+       init_waitqueue_head(&part->channel_mgr_wq);
+
+       sprintf(part->IPI_owner, "xpc%02d", partid);
+       ret = request_irq(SGI_XPC_NOTIFY, xpc_notify_IRQ_handler, SA_SHIRQ,
+                               part->IPI_owner, (void *) (u64) partid);
+       if (ret != 0) {
+               kfree(part->channels);
+               part->channels = NULL;
+               kfree(part->local_GPs_base);
+               part->local_GPs = NULL;
+               kfree(part->remote_GPs_base);
+               part->remote_GPs = NULL;
+               kfree(part->local_openclose_args_base);
+               part->local_openclose_args = NULL;
+               kfree(part->remote_openclose_args_base);
+               part->remote_openclose_args = NULL;
+               dev_err(xpc_chan, "can't register NOTIFY IRQ handler, "
+                       "errno=%d\n", -ret);
+               return xpcLackOfResources;
+       }
+
+       /* Setup a timer to check for dropped IPIs */
+       timer = &part->dropped_IPI_timer;
+       init_timer(timer);
+       timer->function = (void (*)(unsigned long)) xpc_dropped_IPI_check;
+       timer->data = (unsigned long) part;
+       timer->expires = jiffies + XPC_P_DROPPED_IPI_WAIT;
+       add_timer(timer);
+
+       /*
+        * With the setting of the partition setup_state to XPC_P_SETUP, we're
+        * declaring that this partition is ready to go.
+        */
+       (volatile u8) part->setup_state = XPC_P_SETUP;
+
+
+       /*
+        * Setup the per partition specific variables required by the
+        * remote partition to establish channel connections with us.
+        *
+        * The setting of the magic # indicates that these per partition
+        * specific variables are ready to be used.
+        */
+       xpc_vars_part[partid].GPs_pa = __pa(part->local_GPs);
+       xpc_vars_part[partid].openclose_args_pa =
+                                       __pa(part->local_openclose_args);
+       xpc_vars_part[partid].IPI_amo_pa = __pa(part->local_IPI_amo_va);
+       xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(smp_processor_id());
+       xpc_vars_part[partid].IPI_phys_cpuid =
+                                       cpu_physical_id(smp_processor_id());
+       xpc_vars_part[partid].nchannels = part->nchannels;
+       (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
+
+       return xpcSuccess;
+}
+
+
+/*
+ * Create a wrapper that hides the underlying mechanism for pulling a cacheline
+ * (or multiple cachelines) from a remote partition.
+ *
+ * src must be a cacheline aligned physical address on the remote partition.
+ * dst must be a cacheline aligned virtual address on this partition.
+ * cnt must be an cacheline sized
+ */
+static enum xpc_retval
+xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
+                               const void *src, size_t cnt)
+{
+       bte_result_t bte_ret;
+
+
+       DBUG_ON((u64) src != L1_CACHE_ALIGN((u64) src));
+       DBUG_ON((u64) dst != L1_CACHE_ALIGN((u64) dst));
+       DBUG_ON(cnt != L1_CACHE_ALIGN(cnt));
+
+       if (part->act_state == XPC_P_DEACTIVATING) {
+               return part->reason;
+       }
+
+       bte_ret = xp_bte_copy((u64) src, (u64) ia64_tpa((u64) dst),
+                               (u64) cnt, (BTE_NORMAL | BTE_WACQUIRE), NULL);
+       if (bte_ret == BTE_SUCCESS) {
+               return xpcSuccess;
+       }
+
+       dev_dbg(xpc_chan, "xp_bte_copy() from partition %d failed, ret=%d\n",
+               XPC_PARTID(part), bte_ret);
+
+       return xpc_map_bte_errors(bte_ret);
+}
+
+
+/*
+ * Pull the remote per partititon specific variables from the specified
+ * partition.
+ */
+enum xpc_retval
+xpc_pull_remote_vars_part(struct xpc_partition *part)
+{
+       u8 buffer[L1_CACHE_BYTES * 2];
+       struct xpc_vars_part *pulled_entry_cacheline =
+                       (struct xpc_vars_part *) L1_CACHE_ALIGN((u64) buffer);
+       struct xpc_vars_part *pulled_entry;
+       u64 remote_entry_cacheline_pa, remote_entry_pa;
+       partid_t partid = XPC_PARTID(part);
+       enum xpc_retval ret;
+
+
+       /* pull the cacheline that contains the variables we're interested in */
+
+       DBUG_ON(part->remote_vars_part_pa !=
+                               L1_CACHE_ALIGN(part->remote_vars_part_pa));
+       DBUG_ON(sizeof(struct xpc_vars_part) != L1_CACHE_BYTES / 2);
+
+       remote_entry_pa = part->remote_vars_part_pa +
+                       sn_partition_id * sizeof(struct xpc_vars_part);
+
+       remote_entry_cacheline_pa = (remote_entry_pa & ~(L1_CACHE_BYTES - 1));
+
+       pulled_entry = (struct xpc_vars_part *) ((u64) pulled_entry_cacheline +
+                               (remote_entry_pa & (L1_CACHE_BYTES - 1)));
+
+       ret = xpc_pull_remote_cachelines(part, pulled_entry_cacheline,
+                                       (void *) remote_entry_cacheline_pa,
+                                       L1_CACHE_BYTES);
+       if (ret != xpcSuccess) {
+               dev_dbg(xpc_chan, "failed to pull XPC vars_part from "
+                       "partition %d, ret=%d\n", partid, ret);
+               return ret;
+       }
+
+
+       /* see if they've been set up yet */
+
+       if (pulled_entry->magic != XPC_VP_MAGIC1 &&
+                               pulled_entry->magic != XPC_VP_MAGIC2) {
+
+               if (pulled_entry->magic != 0) {
+                       dev_dbg(xpc_chan, "partition %d's XPC vars_part for "
+                               "partition %d has bad magic value (=0x%lx)\n",
+                               partid, sn_partition_id, pulled_entry->magic);
+                       return xpcBadMagic;
+               }
+
+               /* they've not been initialized yet */
+               return xpcRetry;
+       }
+
+       if (xpc_vars_part[partid].magic == XPC_VP_MAGIC1) {
+
+               /* validate the variables */
+
+               if (pulled_entry->GPs_pa == 0 ||
+                               pulled_entry->openclose_args_pa == 0 ||
+                                       pulled_entry->IPI_amo_pa == 0) {
+
+                       dev_err(xpc_chan, "partition %d's XPC vars_part for "
+                               "partition %d are not valid\n", partid,
+                               sn_partition_id);
+                       return xpcInvalidAddress;
+               }
+
+               /* the variables we imported look to be valid */
+
+               part->remote_GPs_pa = pulled_entry->GPs_pa;
+               part->remote_openclose_args_pa =
+                                       pulled_entry->openclose_args_pa;
+               part->remote_IPI_amo_va =
+                                     (AMO_t *) __va(pulled_entry->IPI_amo_pa);
+               part->remote_IPI_nasid = pulled_entry->IPI_nasid;
+               part->remote_IPI_phys_cpuid = pulled_entry->IPI_phys_cpuid;
+
+               if (part->nchannels > pulled_entry->nchannels) {
+                       part->nchannels = pulled_entry->nchannels;
+               }
+
+               /* let the other side know that we've pulled their variables */
+
+               (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC2;
+       }
+
+       if (pulled_entry->magic == XPC_VP_MAGIC1) {
+               return xpcRetry;
+       }
+
+       return xpcSuccess;
+}
+
+
+/*
+ * Get the IPI flags and pull the openclose args and/or remote GPs as needed.
+ */
+static u64
+xpc_get_IPI_flags(struct xpc_partition *part)
+{
+       unsigned long irq_flags;
+       u64 IPI_amo;
+       enum xpc_retval ret;
+
+
+       /*
+        * See if there are any IPI flags to be handled.
+        */
+
+       spin_lock_irqsave(&part->IPI_lock, irq_flags);
+       if ((IPI_amo = part->local_IPI_amo) != 0) {
+               part->local_IPI_amo = 0;
+       }
+       spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
+
+
+       if (XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(IPI_amo)) {
+               ret = xpc_pull_remote_cachelines(part,
+                                       part->remote_openclose_args,
+                                       (void *) part->remote_openclose_args_pa,
+                                       XPC_OPENCLOSE_ARGS_SIZE);
+               if (ret != xpcSuccess) {
+                       XPC_DEACTIVATE_PARTITION(part, ret);
+
+                       dev_dbg(xpc_chan, "failed to pull openclose args from "
+                               "partition %d, ret=%d\n", XPC_PARTID(part),
+                               ret);
+
+                       /* don't bother processing IPIs anymore */
+                       IPI_amo = 0;
+               }
+       }
+
+       if (XPC_ANY_MSG_IPI_FLAGS_SET(IPI_amo)) {
+               ret = xpc_pull_remote_cachelines(part, part->remote_GPs,
+                                               (void *) part->remote_GPs_pa,
+                                               XPC_GP_SIZE);
+               if (ret != xpcSuccess) {
+                       XPC_DEACTIVATE_PARTITION(part, ret);
+
+                       dev_dbg(xpc_chan, "failed to pull GPs from partition "
+                               "%d, ret=%d\n", XPC_PARTID(part), ret);
+
+                       /* don't bother processing IPIs anymore */
+                       IPI_amo = 0;
+               }
+       }
+
+       return IPI_amo;
+}
+
+
+/*
+ * Allocate the local message queue and the notify queue.
+ */
+static enum xpc_retval
+xpc_allocate_local_msgqueue(struct xpc_channel *ch)
+{
+       unsigned long irq_flags;
+       int nentries;
+       size_t nbytes;
+
+
+       // >>> may want to check for ch->flags & XPC_C_DISCONNECTING between
+       // >>> iterations of the for-loop, bail if set?
+
+       // >>> should we impose a minumum #of entries? like 4 or 8?
+       for (nentries = ch->local_nentries; nentries > 0; nentries--) {
+
+               nbytes = nentries * ch->msg_size;
+               ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes,
+                                               (GFP_KERNEL | GFP_DMA),
+                                               &ch->local_msgqueue_base);
+               if (ch->local_msgqueue == NULL) {
+                       continue;
+               }
+               memset(ch->local_msgqueue, 0, nbytes);
+
+               nbytes = nentries * sizeof(struct xpc_notify);
+               ch->notify_queue = kmalloc(nbytes, (GFP_KERNEL | GFP_DMA));
+               if (ch->notify_queue == NULL) {
+                       kfree(ch->local_msgqueue_base);
+                       ch->local_msgqueue = NULL;
+                       continue;
+               }
+               memset(ch->notify_queue, 0, nbytes);
+
+               spin_lock_irqsave(&ch->lock, irq_flags);
+               if (nentries < ch->local_nentries) {
+                       dev_dbg(xpc_chan, "nentries=%d local_nentries=%d, "
+                               "partid=%d, channel=%d\n", nentries,
+                               ch->local_nentries, ch->partid, ch->number);
+
+                       ch->local_nentries = nentries;
+               }
+               spin_unlock_irqrestore(&ch->lock, irq_flags);
+               return xpcSuccess;
+       }
+
+       dev_dbg(xpc_chan, "can't get memory for local message queue and notify "
+               "queue, partid=%d, channel=%d\n", ch->partid, ch->number);
+       return xpcNoMemory;
+}
+
+
+/*
+ * Allocate the cached remote message queue.
+ */
+static enum xpc_retval
+xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
+{
+       unsigned long irq_flags;
+       int nentries;
+       size_t nbytes;
+
+
+       DBUG_ON(ch->remote_nentries <= 0);
+
+       // >>> may want to check for ch->flags & XPC_C_DISCONNECTING between
+       // >>> iterations of the for-loop, bail if set?
+
+       // >>> should we impose a minumum #of entries? like 4 or 8?
+       for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
+
+               nbytes = nentries * ch->msg_size;
+               ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes,
+                                               (GFP_KERNEL | GFP_DMA),
+                                               &ch->remote_msgqueue_base);
+               if (ch->remote_msgqueue == NULL) {
+                       continue;
+               }
+               memset(ch->remote_msgqueue, 0, nbytes);
+
+               spin_lock_irqsave(&ch->lock, irq_flags);
+               if (nentries < ch->remote_nentries) {
+                       dev_dbg(xpc_chan, "nentries=%d remote_nentries=%d, "
+                               "partid=%d, channel=%d\n", nentries,
+                               ch->remote_nentries, ch->partid, ch->number);
+
+                       ch->remote_nentries = nentries;
+               }
+               spin_unlock_irqrestore(&ch->lock, irq_flags);
+               return xpcSuccess;
+       }
+
+       dev_dbg(xpc_chan, "can't get memory for cached remote message queue, "
+               "partid=%d, channel=%d\n", ch->partid, ch->number);
+       return xpcNoMemory;
+}
+
+
+/*
+ * Allocate message queues and other stuff associated with a channel.
+ *
+ * Note: Assumes all of the channel sizes are filled in.
+ */
+static enum xpc_retval
+xpc_allocate_msgqueues(struct xpc_channel *ch)
+{
+       unsigned long irq_flags;
+       int i;
+       enum xpc_retval ret;
+
+
+       DBUG_ON(ch->flags & XPC_C_SETUP);
+
+       if ((ret = xpc_allocate_local_msgqueue(ch)) != xpcSuccess) {
+               return ret;
+       }
+
+       if ((ret = xpc_allocate_remote_msgqueue(ch)) != xpcSuccess) {
+               kfree(ch->local_msgqueue_base);
+               ch->local_msgqueue = NULL;
+               kfree(ch->notify_queue);
+               ch->notify_queue = NULL;
+               return ret;
+       }
+
+       for (i = 0; i < ch->local_nentries; i++) {
+               /* use a semaphore as an event wait queue */
+               sema_init(&ch->notify_queue[i].sema, 0);
+       }
+
+       sema_init(&ch->teardown_sema, 0);       /* event wait */
+
+       spin_lock_irqsave(&ch->lock, irq_flags);
+       ch->flags |= XPC_C_SETUP;
+       spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+       return xpcSuccess;
+}
+
+
+/*
+ * Process a connect message from a remote partition.
+ *
+ * Note: xpc_process_connect() is expecting to be called with the
+ * spin_lock_irqsave held and will leave it locked upon return.
+ */
+static void
+xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
+{
+       enum xpc_retval ret;
+
+
+       DBUG_ON(!spin_is_locked(&ch->lock));
+
+       if (!(ch->flags & XPC_C_OPENREQUEST) ||
+                               !(ch->flags & XPC_C_ROPENREQUEST)) {
+               /* nothing more to do for now */
+               return;
+       }
+       DBUG_ON(!(ch->flags & XPC_C_CONNECTING));
+
+       if (!(ch->flags & XPC_C_SETUP)) {
+               spin_unlock_irqrestore(&ch->lock, *irq_flags);
+               ret = xpc_allocate_msgqueues(ch);
+               spin_lock_irqsave(&ch->lock, *irq_flags);
+
+               if (ret != xpcSuccess) {
+                       XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
+               }
+               if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING)) {
+                       return;
+               }
+
+               DBUG_ON(!(ch->flags & XPC_C_SETUP));
+               DBUG_ON(ch->local_msgqueue == NULL);
+               DBUG_ON(ch->remote_msgqueue == NULL);
+       }
+
+       if (!(ch->flags & XPC_C_OPENREPLY)) {
+               ch->flags |= XPC_C_OPENREPLY;
+               xpc_IPI_send_openreply(ch, irq_flags);
+       }
+
+       if (!(ch->flags & XPC_C_ROPENREPLY)) {
+               return;
+       }
+
+       DBUG_ON(ch->remote_msgqueue_pa == 0);
+
+       ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP);    /* clear all else */
+
+       dev_info(xpc_chan, "channel %d to partition %d connected\n",
+               ch->number, ch->partid);
+
+       spin_unlock_irqrestore(&ch->lock, *irq_flags);
+       xpc_create_kthreads(ch, 1);
+       spin_lock_irqsave(&ch->lock, *irq_flags);
+}
+
+
+/*
+ * Free up message queues and other stuff that were allocated for the specified
+ * channel.
+ *
+ * Note: ch->reason and ch->reason_line are left set for debugging purposes,
+ * they're cleared when XPC_C_DISCONNECTED is cleared.
+ */
+static void
+xpc_free_msgqueues(struct xpc_channel *ch)
+{
+       DBUG_ON(!spin_is_locked(&ch->lock));
+       DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
+
+       ch->remote_msgqueue_pa = 0;
+       ch->func = NULL;
+       ch->key = NULL;
+       ch->msg_size = 0;
+       ch->local_nentries = 0;
+       ch->remote_nentries = 0;
+       ch->kthreads_assigned_limit = 0;
+       ch->kthreads_idle_limit = 0;
+
+       ch->local_GP->get = 0;
+       ch->local_GP->put = 0;
+       ch->remote_GP.get = 0;
+       ch->remote_GP.put = 0;
+       ch->w_local_GP.get = 0;
+       ch->w_local_GP.put = 0;
+       ch->w_remote_GP.get = 0;
+       ch->w_remote_GP.put = 0;
+       ch->next_msg_to_pull = 0;
+
+       if (ch->flags & XPC_C_SETUP) {
+               ch->flags &= ~XPC_C_SETUP;
+
+               dev_dbg(xpc_chan, "ch->flags=0x%x, partid=%d, channel=%d\n",
+                       ch->flags, ch->partid, ch->number);
+
+               kfree(ch->local_msgqueue_base);
+               ch->local_msgqueue = NULL;
+               kfree(ch->remote_msgqueue_base);
+               ch->remote_msgqueue = NULL;
+               kfree(ch->notify_queue);
+               ch->notify_queue = NULL;
+
+               /* in case someone is waiting for the teardown to complete */
+               up(&ch->teardown_sema);
+       }
+}
+
+
+/*
+ * spin_lock_irqsave() is expected to be held on entry.
+ */
+static void
+xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
+{
+       struct xpc_partition *part = &xpc_partitions[ch->partid];
+       u32 ch_flags = ch->flags;
+
+
+       DBUG_ON(!spin_is_locked(&ch->lock));
+
+       if (!(ch->flags & XPC_C_DISCONNECTING)) {
+               return;
+       }
+
+       DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
+
+       /* make sure all activity has settled down first */
+
+       if (atomic_read(&ch->references) > 0) {
+               return;
+       }
+       DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
+
+       /* it's now safe to free the channel's message queues */
+
+       xpc_free_msgqueues(ch);
+       DBUG_ON(ch->flags & XPC_C_SETUP);
+
+       if (part->act_state != XPC_P_DEACTIVATING) {
+
+               /* as long as the other side is up do the full protocol */
+
+               if (!(ch->flags & XPC_C_RCLOSEREQUEST)) {
+                       return;
+               }
+
+               if (!(ch->flags & XPC_C_CLOSEREPLY)) {
+                       ch->flags |= XPC_C_CLOSEREPLY;
+                       xpc_IPI_send_closereply(ch, irq_flags);
+               }
+
+               if (!(ch->flags & XPC_C_RCLOSEREPLY)) {
+                       return;
+               }
+       }
+
+       /* both sides are disconnected now */
+
+       ch->flags = XPC_C_DISCONNECTED; /* clear all flags, but this one */
+
+       atomic_dec(&part->nchannels_active);
+
+       if (ch_flags & XPC_C_WASCONNECTED) {
+               dev_info(xpc_chan, "channel %d to partition %d disconnected, "
+                       "reason=%d\n", ch->number, ch->partid, ch->reason);
+       }
+}
+
+
+/*
+ * Process a change in the channel's remote connection state.
+ */
+static void
+xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
+                               u8 IPI_flags)
+{
+       unsigned long irq_flags;
+       struct xpc_openclose_args *args =
+                               &part->remote_openclose_args[ch_number];
+       struct xpc_channel *ch = &part->channels[ch_number];
+       enum xpc_retval reason;
+
+
+
+       spin_lock_irqsave(&ch->lock, irq_flags);
+
+
+       if (IPI_flags & XPC_IPI_CLOSEREQUEST) {
+
+               dev_dbg(xpc_chan, "XPC_IPI_CLOSEREQUEST (reason=%d) received "
+                       "from partid=%d, channel=%d\n", args->reason,
+                       ch->partid, ch->number);
+
+               /*
+                * If RCLOSEREQUEST is set, we're probably waiting for
+                * RCLOSEREPLY. We should find it and a ROPENREQUEST packed
+                * with this RCLOSEQREUQEST in the IPI_flags.
+                */
+
+               if (ch->flags & XPC_C_RCLOSEREQUEST) {
+                       DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING));
+                       DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
+                       DBUG_ON(!(ch->flags & XPC_C_CLOSEREPLY));
+                       DBUG_ON(ch->flags & XPC_C_RCLOSEREPLY);
+
+                       DBUG_ON(!(IPI_flags & XPC_IPI_CLOSEREPLY));
+                       IPI_flags &= ~XPC_IPI_CLOSEREPLY;
+                       ch->flags |= XPC_C_RCLOSEREPLY;
+
+                       /* both sides have finished disconnecting */
+                       xpc_process_disconnect(ch, &irq_flags);
+               }
+
+               if (ch->flags & XPC_C_DISCONNECTED) {
+                       // >>> explain this section
+
+                       if (!(IPI_flags & XPC_IPI_OPENREQUEST)) {
+                               DBUG_ON(part->act_state !=
+                                                       XPC_P_DEACTIVATING);
+                               spin_unlock_irqrestore(&ch->lock, irq_flags);
+                               return;
+                       }
+
+                       XPC_SET_REASON(ch, 0, 0);
+                       ch->flags &= ~XPC_C_DISCONNECTED;
+
+                       atomic_inc(&part->nchannels_active);
+                       ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST);
+               }
+
+               IPI_flags &= ~(XPC_IPI_OPENREQUEST | XPC_IPI_OPENREPLY);
+
+               /*
+                * The meaningful CLOSEREQUEST connection state fields are:
+                *      reason = reason connection is to be closed
+                */
+
+               ch->flags |= XPC_C_RCLOSEREQUEST;
+
+               if (!(ch->flags & XPC_C_DISCONNECTING)) {
+                       reason = args->reason;
+                       if (reason <= xpcSuccess || reason > xpcUnknownReason) {
+                               reason = xpcUnknownReason;
+                       } else if (reason == xpcUnregistering) {
+                               reason = xpcOtherUnregistering;
+                       }
+
+                       XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
+               } else {
+                       xpc_process_disconnect(ch, &irq_flags);
+               }
+       }
+
+
+       if (IPI_flags & XPC_IPI_CLOSEREPLY) {
+
+               dev_dbg(xpc_chan, "XPC_IPI_CLOSEREPLY received from partid=%d,"
+                       " channel=%d\n", ch->partid, ch->number);
+
+               if (ch->flags & XPC_C_DISCONNECTED) {
+                       DBUG_ON(part->act_state != XPC_P_DEACTIVATING);
+                       spin_unlock_irqrestore(&ch->lock, irq_flags);
+                       return;
+               }
+
+               DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
+               DBUG_ON(!(ch->flags & XPC_C_RCLOSEREQUEST));
+
+               ch->flags |= XPC_C_RCLOSEREPLY;
+
+               if (ch->flags & XPC_C_CLOSEREPLY) {
+                       /* both sides have finished disconnecting */
+                       xpc_process_disconnect(ch, &irq_flags);
+               }
+       }
+
+
+       if (IPI_flags & XPC_IPI_OPENREQUEST) {
+
+               dev_dbg(xpc_chan, "XPC_IPI_OPENREQUEST (msg_size=%d, "
+                       "local_nentries=%d) received from partid=%d, "
+                       "channel=%d\n", args->msg_size, args->local_nentries,
+                       ch->partid, ch->number);
+
+               if ((ch->flags & XPC_C_DISCONNECTING) ||
+                                       part->act_state == XPC_P_DEACTIVATING) {
+                       spin_unlock_irqrestore(&ch->lock, irq_flags);
+                       return;
+               }
+               DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED |
+                                                       XPC_C_OPENREQUEST)));
+               DBUG_ON(ch->flags & (XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
+                                       XPC_C_OPENREPLY | XPC_C_CONNECTED));
+
+               /*
+                * The meaningful OPENREQUEST connection state fields are:
+                *      msg_size = size of channel's messages in bytes
+                *      local_nentries = remote partition's local_nentries
+                */
+               DBUG_ON(args->msg_size == 0);
+               DBUG_ON(args->local_nentries == 0);
+
+               ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING);
+               ch->remote_nentries = args->local_nentries;
+
+
+               if (ch->flags & XPC_C_OPENREQUEST) {
+                       if (args->msg_size != ch->msg_size) {
+                               XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
+                                                               &irq_flags);
+                               spin_unlock_irqrestore(&ch->lock, irq_flags);
+                               return;
+                       }
+               } else {
+                       ch->msg_size = args->msg_size;
+
+                       XPC_SET_REASON(ch, 0, 0);
+                       ch->flags &= ~XPC_C_DISCONNECTED;
+
+                       atomic_inc(&part->nchannels_active);
+               }
+
+               xpc_process_connect(ch, &irq_flags);
+       }
+
+
+       if (IPI_flags & XPC_IPI_OPENREPLY) {
+
+               dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY (local_msgqueue_pa=0x%lx, "
+                       "local_nentries=%d, remote_nentries=%d) received from "
+                       "partid=%d, channel=%d\n", args->local_msgqueue_pa,
+                       args->local_nentries, args->remote_nentries,
+                       ch->partid, ch->number);
+
+               if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
+                       spin_unlock_irqrestore(&ch->lock, irq_flags);
+                       return;
+               }
+               DBUG_ON(!(ch->flags & XPC_C_OPENREQUEST));
+               DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
+               DBUG_ON(ch->flags & XPC_C_CONNECTED);
+
+               /*
+                * The meaningful OPENREPLY connection state fields are:
+                *      local_msgqueue_pa = physical address of remote
+                *                          partition's local_msgqueue
+                *      local_nentries = remote partition's local_nentries
+                *      remote_nentries = remote partition's remote_nentries
+                */
+               DBUG_ON(args->local_msgqueue_pa == 0);
+               DBUG_ON(args->local_nentries == 0);
+               DBUG_ON(args->remote_nentries == 0);
+
+               ch->flags |= XPC_C_ROPENREPLY;
+               ch->remote_msgqueue_pa = args->local_msgqueue_pa;
+
+               if (args->local_nentries < ch->remote_nentries) {
+                       dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY: new "
+                               "remote_nentries=%d, old remote_nentries=%d, "
+                               "partid=%d, channel=%d\n",
+                               args->local_nentries, ch->remote_nentries,
+                               ch->partid, ch->number);
+
+                       ch->remote_nentries = args->local_nentries;
+               }
+               if (args->remote_nentries < ch->local_nentries) {
+                       dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY: new "
+                               "local_nentries=%d, old local_nentries=%d, "
+                               "partid=%d, channel=%d\n",
+                               args->remote_nentries, ch->local_nentries,
+                               ch->partid, ch->number);
+
+                       ch->local_nentries = args->remote_nentries;
+               }
+
+               xpc_process_connect(ch, &irq_flags);
+       }
+
+       spin_unlock_irqrestore(&ch->lock, irq_flags);
+}
+
+
+/*
+ * Attempt to establish a channel connection to a remote partition.
+ */
+static enum xpc_retval
+xpc_connect_channel(struct xpc_channel *ch)
+{
+       unsigned long irq_flags;
+       struct xpc_registration *registration = &xpc_registrations[ch->number];
+
+
+       if (down_interruptible(&registration->sema) != 0) {
+               return xpcInterrupted;
+       }
+
+       if (!XPC_CHANNEL_REGISTERED(ch->number)) {
+               up(&registration->sema);
+               return xpcUnregistered;
+       }
+
+       spin_lock_irqsave(&ch->lock, irq_flags);
+
+       DBUG_ON(ch->flags & XPC_C_CONNECTED);
+       DBUG_ON(ch->flags & XPC_C_OPENREQUEST);
+
+       if (ch->flags & XPC_C_DISCONNECTING) {
+               spin_unlock_irqrestore(&ch->lock, irq_flags);
+               up(&registration->sema);
+               return ch->reason;
+       }
+
+
+       /* add info from the channel connect registration to the channel */
+
+       ch->kthreads_assigned_limit = registration->assigned_limit;
+       ch->kthreads_idle_limit = registration->idle_limit;
+       DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
+       DBUG_ON(atomic_read(&ch->kthreads_idle) != 0);
+       DBUG_ON(atomic_read(&ch->kthreads_active) != 0);
+
+       ch->func = registration->func;
+       DBUG_ON(registration->func == NULL);
+       ch->key = registration->key;
+
+       ch->local_nentries = registration->nentries;
+
+       if (ch->flags & XPC_C_ROPENREQUEST) {
+               if (registration->msg_size != ch->msg_size) {
+                       /* the local and remote sides aren't the same */
+
+                       /*
+                        * Because XPC_DISCONNECT_CHANNEL() can block we're
+                        * forced to up the registration sema before we unlock
+                        * the channel lock. But that's okay here because we're
+                        * done with the part that required the registration
+                        * sema. XPC_DISCONNECT_CHANNEL() requires that the
+                        * channel lock be locked and will unlock and relock
+                        * the channel lock as needed.
+                        */
+                       up(&registration->sema);
+                       XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
+                                                               &irq_flags);
+                       spin_unlock_irqrestore(&ch->lock, irq_flags);
+                       return xpcUnequalMsgSizes;
+               }
+       } else {
+               ch->msg_size = registration->msg_size;
+
+               XPC_SET_REASON(ch, 0, 0);
+               ch->flags &= ~XPC_C_DISCONNECTED;
+
+               atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
+       }
+
+       up(&registration->sema);
+
+
+       /* initiate the connection */
+
+       ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
+       xpc_IPI_send_openrequest(ch, &irq_flags);
+
+       xpc_process_connect(ch, &irq_flags);
+
+       spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+       return xpcSuccess;
+}
+
+
+/*
+ * Notify those who wanted to be notified upon delivery of their message.
+ */
+static void
+xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put)
+{
+       struct xpc_notify *notify;
+       u8 notify_type;
+       s64 get = ch->w_remote_GP.get - 1;
+
+
+       while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
+
+               notify = &ch->notify_queue[get % ch->local_nentries];
+
+               /*
+                * See if the notify entry indicates it was associated with
+                * a message who's sender wants to be notified. It is possible
+                * that it is, but someone else is doing or has done the
+                * notification.
+                */
+               notify_type = notify->type;
+               if (notify_type == 0 ||
+                               cmpxchg(&notify->type, notify_type, 0) !=
+                                                               notify_type) {
+                       continue;
+               }
+
+               DBUG_ON(notify_type != XPC_N_CALL);
+
+               atomic_dec(&ch->n_to_notify);
+
+               if (notify->func != NULL) {
+                       dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, "
+                               "msg_number=%ld, partid=%d, channel=%d\n",
+                               (void *) notify, get, ch->partid, ch->number);
+
+                       notify->func(reason, ch->partid, ch->number,
+                                                               notify->key);
+
+                       dev_dbg(xpc_chan, "notify->func() returned, "
+                               "notify=0x%p, msg_number=%ld, partid=%d, "
+                               "channel=%d\n", (void *) notify, get,
+                               ch->partid, ch->number);
+               }
+       }
+}
+
+
+/*
+ * Clear some of the msg flags in the local message queue.
+ */
+static inline void
+xpc_clear_local_msgqueue_flags(struct xpc_channel *ch)
+{
+       struct xpc_msg *msg;
+       s64 get;
+
+
+       get = ch->w_remote_GP.get;
+       do {
+               msg = (struct xpc_msg *) ((u64) ch->local_msgqueue +
+                               (get % ch->local_nentries) * ch->msg_size);
+               msg->flags = 0;
+       } while (++get < (volatile s64) ch->remote_GP.get);
+}
+
+
+/*
+ * Clear some of the msg flags in the remote message queue.
+ */
+static inline void
+xpc_clear_remote_msgqueue_flags(struct xpc_channel *ch)
+{
+       struct xpc_msg *msg;
+       s64 put;
+
+
+       put = ch->w_remote_GP.put;
+       do {
+               msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue +
+                               (put % ch->remote_nentries) * ch->msg_size);
+               msg->flags = 0;
+       } while (++put < (volatile s64) ch->remote_GP.put);
+}
+
+
+static void
+xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
+{
+       struct xpc_channel *ch = &part->channels[ch_number];
+       int nmsgs_sent;
+
+
+       ch->remote_GP = part->remote_GPs[ch_number];
+
+
+       /* See what, if anything, has changed for each connected channel */
+
+       xpc_msgqueue_ref(ch);
+
+       if (ch->w_remote_GP.get == ch->remote_GP.get &&
+                               ch->w_remote_GP.put == ch->remote_GP.put) {
+               /* nothing changed since GPs were last pulled */
+               xpc_msgqueue_deref(ch);
+               return;
+       }
+
+       if (!(ch->flags & XPC_C_CONNECTED)){
+               xpc_msgqueue_deref(ch);
+               return;
+       }
+
+
+       /*
+        * First check to see if messages recently sent by us have been
+        * received by the other side. (The remote GET value will have
+        * changed since we last looked at it.)
+        */
+
+       if (ch->w_remote_GP.get != ch->remote_GP.get) {
+
+               /*
+                * We need to notify any senders that want to be notified
+                * that their sent messages have been received by their
+                * intended recipients. We need to do this before updating
+                * w_remote_GP.get so that we don't allocate the same message
+                * queue entries prematurely (see xpc_allocate_msg()).
+                */
+               if (atomic_read(&ch->n_to_notify) > 0) {
+                       /*
+                        * Notify senders that messages sent have been
+                        * received and delivered by the other side.
+                        */
+                       xpc_notify_senders(ch, xpcMsgDelivered,
+                                                       ch->remote_GP.get);
+               }
+
+               /*
+                * Clear msg->flags in previously sent messages, so that
+                * they're ready for xpc_allocate_msg().
+                */
+               xpc_clear_local_msgqueue_flags(ch);
+
+               (volatile s64) ch->w_remote_GP.get = ch->remote_GP.get;
+
+               dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, "
+                       "channel=%d\n", ch->w_remote_GP.get, ch->partid,
+                       ch->number);
+
+               /*
+                * If anyone was waiting for message queue entries to become
+                * available, wake them up.
+                */
+               if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) {
+                       wake_up(&ch->msg_allocate_wq);
+               }
+       }
+
+
+       /*
+        * Now check for newly sent messages by the other side. (The remote
+        * PUT value will have changed since we last looked at it.)
+        */
+
+       if (ch->w_remote_GP.put != ch->remote_GP.put) {
+               /*
+                * Clear msg->flags in previously received messages, so that
+                * they're ready for xpc_get_deliverable_msg().
+                */
+               xpc_clear_remote_msgqueue_flags(ch);
+
+               (volatile s64) ch->w_remote_GP.put = ch->remote_GP.put;
+
+               dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
+                       "channel=%d\n", ch->w_remote_GP.put, ch->partid,
+                       ch->number);
+
+               nmsgs_sent = ch->w_remote_GP.put - ch->w_local_GP.get;
+               if (nmsgs_sent > 0) {
+                       dev_dbg(xpc_chan, "msgs waiting to be copied and "
+                               "delivered=%d, partid=%d, channel=%d\n",
+                               nmsgs_sent, ch->partid, ch->number);
+
+                       if (ch->flags & XPC_C_CONNECTCALLOUT) {
+                               xpc_activate_kthreads(ch, nmsgs_sent);
+                       }
+               }
+       }
+
+       xpc_msgqueue_deref(ch);
+}
+
+
+void
+xpc_process_channel_activity(struct xpc_partition *part)
+{
+       unsigned long irq_flags;
+       u64 IPI_amo, IPI_flags;
+       struct xpc_channel *ch;
+       int ch_number;
+
+
+       IPI_amo = xpc_get_IPI_flags(part);
+
+       /*
+        * Initiate channel connections for registered channels.
+        *
+        * For each connected channel that has pending messages activate idle
+        * kthreads and/or create new kthreads as needed.
+        */
+
+       for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
+               ch = &part->channels[ch_number];
+
+
+               /*
+                * Process any open or close related IPI flags, and then deal
+                * with connecting or disconnecting the channel as required.
+                */
+
+               IPI_flags = XPC_GET_IPI_FLAGS(IPI_amo, ch_number);
+
+               if (XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(IPI_flags)) {
+                       xpc_process_openclose_IPI(part, ch_number, IPI_flags);
+               }
+
+
+               if (ch->flags & XPC_C_DISCONNECTING) {
+                       spin_lock_irqsave(&ch->lock, irq_flags);
+                       xpc_process_disconnect(ch, &irq_flags);
+                       spin_unlock_irqrestore(&ch->lock, irq_flags);
+                       continue;
+               }
+
+               if (part->act_state == XPC_P_DEACTIVATING) {
+                       continue;
+               }
+
+               if (!(ch->flags & XPC_C_CONNECTED)) {
+                       if (!(ch->flags & XPC_C_OPENREQUEST)) {
+                               DBUG_ON(ch->flags & XPC_C_SETUP);
+                               (void) xpc_connect_channel(ch);
+                       } else {
+                               spin_lock_irqsave(&ch->lock, irq_flags);
+                               xpc_process_connect(ch, &irq_flags);
+                               spin_unlock_irqrestore(&ch->lock, irq_flags);
+                       }
+                       continue;
+               }
+
+
+               /*
+                * Process any message related IPI flags, this may involve the
+                * activation of kthreads to deliver any pending messages sent
+                * from the other partition.
+                */
+
+               if (XPC_ANY_MSG_IPI_FLAGS_SET(IPI_flags)) {
+                       xpc_process_msg_IPI(part, ch_number);
+               }
+       }
+}
+
+
+/*
+ * XPC's heartbeat code calls this function to inform XPC that a partition has
+ * gone down.  XPC responds by tearing down the XPartition Communication
+ * infrastructure used for the just downed partition.
+ *
+ * XPC's heartbeat code will never call this function and xpc_partition_up()
+ * at the same time. Nor will it ever make multiple calls to either function
+ * at the same time.
+ */
+void
+xpc_partition_down(struct xpc_partition *part, enum xpc_retval reason)
+{
+       unsigned long irq_flags;
+       int ch_number;
+       struct xpc_channel *ch;
+
+
+       dev_dbg(xpc_chan, "deactivating partition %d, reason=%d\n",
+               XPC_PARTID(part), reason);
+
+       if (!xpc_part_ref(part)) {
+               /* infrastructure for this partition isn't currently set up */
+               return;
+       }
+
+
+       /* disconnect all channels associated with the downed partition */
+
+       for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
+               ch = &part->channels[ch_number];
+
+
+               xpc_msgqueue_ref(ch);
+               spin_lock_irqsave(&ch->lock, irq_flags);
+
+               XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
+
+               spin_unlock_irqrestore(&ch->lock, irq_flags);
+               xpc_msgqueue_deref(ch);
+       }
+
+       xpc_wakeup_channel_mgr(part);
+
+       xpc_part_deref(part);
+}
+
+
+/*
+ * Teardown the infrastructure necessary to support XPartition Communication
+ * between the specified remote partition and the local one.
+ */
+void
+xpc_teardown_infrastructure(struct xpc_partition *part)
+{
+       partid_t partid = XPC_PARTID(part);
+
+
+       /*
+        * We start off by making this partition inaccessible to local
+        * processes by marking it as no longer setup. Then we make it
+        * inaccessible to remote processes by clearing the XPC per partition
+        * specific variable's magic # (which indicates that these variables
+        * are no longer valid) and by ignoring all XPC notify IPIs sent to
+        * this partition.
+        */
+
+       DBUG_ON(atomic_read(&part->nchannels_active) != 0);
+       DBUG_ON(part->setup_state != XPC_P_SETUP);
+       part->setup_state = XPC_P_WTEARDOWN;
+
+       xpc_vars_part[partid].magic = 0;
+
+
+       free_irq(SGI_XPC_NOTIFY, (void *) (u64) partid);
+
+
+       /*
+        * Before proceding with the teardown we have to wait until all
+        * existing references cease.
+        */
+       wait_event(part->teardown_wq, (atomic_read(&part->references) == 0));
+
+
+       /* now we can begin tearing down the infrastructure */
+
+       part->setup_state = XPC_P_TORNDOWN;
+
+       /* in case we've still got outstanding timers registered... */
+       del_timer_sync(&part->dropped_IPI_timer);
+
+       kfree(part->remote_openclose_args_base);
+       part->remote_openclose_args = NULL;
+       kfree(part->local_openclose_args_base);
+       part->local_openclose_args = NULL;
+       kfree(part->remote_GPs_base);
+       part->remote_GPs = NULL;
+       kfree(part->local_GPs_base);
+       part->local_GPs = NULL;
+       kfree(part->channels);
+       part->channels = NULL;
+       part->local_IPI_amo_va = NULL;
+}
+
+
+/*
+ * Called by XP at the time of channel connection registration to cause
+ * XPC to establish connections to all currently active partitions.
+ */
+void
+xpc_initiate_connect(int ch_number)
+{
+       partid_t partid;
+       struct xpc_partition *part;
+       struct xpc_channel *ch;
+
+
+       DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
+
+       for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+               part = &xpc_partitions[partid];
+
+               if (xpc_part_ref(part)) {
+                       ch = &part->channels[ch_number];
+
+                       if (!(ch->flags & XPC_C_DISCONNECTING)) {
+                               DBUG_ON(ch->flags & XPC_C_OPENREQUEST);
+                               DBUG_ON(ch->flags & XPC_C_CONNECTED);
+                               DBUG_ON(ch->flags & XPC_C_SETUP);
+
+                               /*
+                                * Initiate the establishment of a connection
+                                * on the newly registered channel to the
+                                * remote partition.
+                                */
+                               xpc_wakeup_channel_mgr(part);
+                       }
+
+                       xpc_part_deref(part);
+               }
+       }
+}
+
+
+void
+xpc_connected_callout(struct xpc_channel *ch)
+{
+       unsigned long irq_flags;
+
+
+       /* let the registerer know that a connection has been established */
+
+       if (ch->func != NULL) {
+               dev_dbg(xpc_chan, "ch->func() called, reason=xpcConnected, "
+                       "partid=%d, channel=%d\n", ch->partid, ch->number);
+
+               ch->func(xpcConnected, ch->partid, ch->number,
+                               (void *) (u64) ch->local_nentries, ch->key);
+
+               dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, "
+                       "partid=%d, channel=%d\n", ch->partid, ch->number);
+       }
+
+       spin_lock_irqsave(&ch->lock, irq_flags);
+       ch->flags |= XPC_C_CONNECTCALLOUT;
+       spin_unlock_irqrestore(&ch->lock, irq_flags);
+}
+
+
+/*
+ * Called by XP at the time of channel connection unregistration to cause
+ * XPC to teardown all current connections for the specified channel.
+ *
+ * Before returning xpc_initiate_disconnect() will wait until all connections
+ * on the specified channel have been closed/torndown. So the caller can be
+ * assured that they will not be receiving any more callouts from XPC to the
+ * function they registered via xpc_connect().
+ *
+ * Arguments:
+ *
+ *     ch_number - channel # to unregister.
+ */
+void
+xpc_initiate_disconnect(int ch_number)
+{
+       unsigned long irq_flags;
+       partid_t partid;
+       struct xpc_partition *part;
+       struct xpc_channel *ch;
+
+
+       DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
+
+       /* initiate the channel disconnect for every active partition */
+       for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+               part = &xpc_partitions[partid];
+
+               if (xpc_part_ref(part)) {
+                       ch = &part->channels[ch_number];
+                       xpc_msgqueue_ref(ch);
+
+                       spin_lock_irqsave(&ch->lock, irq_flags);
+
+                       XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering,
+                                                               &irq_flags);
+
+                       spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+                       xpc_msgqueue_deref(ch);
+                       xpc_part_deref(part);
+               }
+       }
+
+       xpc_disconnect_wait(ch_number);
+}
+
+
+/*
+ * To disconnect a channel, and reflect it back to all who may be waiting.
+ *
+ * >>> An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by
+ * >>> xpc_free_msgqueues().
+ *
+ * THE CHANNEL IS TO BE LOCKED BY THE CALLER AND WILL REMAIN LOCKED UPON RETURN.
+ */
+void
+xpc_disconnect_channel(const int line, struct xpc_channel *ch,
+                       enum xpc_retval reason, unsigned long *irq_flags)
+{
+       u32 flags;
+
+
+       DBUG_ON(!spin_is_locked(&ch->lock));
+
+       if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
+               return;
+       }
+       DBUG_ON(!(ch->flags & (XPC_C_CONNECTING | XPC_C_CONNECTED)));
+
+       dev_dbg(xpc_chan, "reason=%d, line=%d, partid=%d, channel=%d\n",
+               reason, line, ch->partid, ch->number);
+
+       XPC_SET_REASON(ch, reason, line);
+
+       flags = ch->flags;
+       /* some of these may not have been set */
+       ch->flags &= ~(XPC_C_OPENREQUEST | XPC_C_OPENREPLY |
+                       XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
+                       XPC_C_CONNECTING | XPC_C_CONNECTED);
+
+       ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING);
+       xpc_IPI_send_closerequest(ch, irq_flags);
+
+       if (flags & XPC_C_CONNECTED) {
+               ch->flags |= XPC_C_WASCONNECTED;
+       }
+
+       if (atomic_read(&ch->kthreads_idle) > 0) {
+               /* wake all idle kthreads so they can exit */
+               wake_up_all(&ch->idle_wq);
+       }
+
+       spin_unlock_irqrestore(&ch->lock, *irq_flags);
+
+
+       /* wake those waiting to allocate an entry from the local msg queue */
+
+       if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) {
+               wake_up(&ch->msg_allocate_wq);
+       }
+
+       /* wake those waiting for notify completion */
+
+       if (atomic_read(&ch->n_to_notify) > 0) {
+               xpc_notify_senders(ch, reason, ch->w_local_GP.put);
+       }
+
+       spin_lock_irqsave(&ch->lock, *irq_flags);
+}
+
+
+void
+xpc_disconnected_callout(struct xpc_channel *ch)
+{
+       /*
+        * Let the channel's registerer know that the channel is now
+        * disconnected. We don't want to do this if the registerer was never
+        * informed of a connection being made, unless the disconnect was for
+        * abnormal reasons.
+        */
+
+       if (ch->func != NULL) {
+               dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, "
+                       "channel=%d\n", ch->reason, ch->partid, ch->number);
+
+               ch->func(ch->reason, ch->partid, ch->number, NULL, ch->key);
+
+               dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, "
+                       "channel=%d\n", ch->reason, ch->partid, ch->number);
+       }
+}
+
+
+/*
+ * Wait for a message entry to become available for the specified channel,
+ * but don't wait any longer than 1 jiffy.
+ */
+static enum xpc_retval
+xpc_allocate_msg_wait(struct xpc_channel *ch)
+{
+       enum xpc_retval ret;
+
+
+       if (ch->flags & XPC_C_DISCONNECTING) {
+               DBUG_ON(ch->reason == xpcInterrupted);  // >>> Is this true?
+               return ch->reason;
+       }
+
+       atomic_inc(&ch->n_on_msg_allocate_wq);
+       ret = interruptible_sleep_on_timeout(&ch->msg_allocate_wq, 1);
+       atomic_dec(&ch->n_on_msg_allocate_wq);
+
+       if (ch->flags & XPC_C_DISCONNECTING) {
+               ret = ch->reason;
+               DBUG_ON(ch->reason == xpcInterrupted);  // >>> Is this true?
+       } else if (ret == 0) {
+               ret = xpcTimeout;
+       } else {
+               ret = xpcInterrupted;
+       }
+
+       return ret;
+}
+
+
+/*
+ * Allocate an entry for a message from the message queue associated with the
+ * specified channel.
+ */
+static enum xpc_retval
+xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
+                       struct xpc_msg **address_of_msg)
+{
+       struct xpc_msg *msg;
+       enum xpc_retval ret;
+       s64 put;
+
+
+       /* this reference will be dropped in xpc_send_msg() */
+       xpc_msgqueue_ref(ch);
+
+       if (ch->flags & XPC_C_DISCONNECTING) {
+               xpc_msgqueue_deref(ch);
+               return ch->reason;
+       }
+       if (!(ch->flags & XPC_C_CONNECTED)) {
+               xpc_msgqueue_deref(ch);
+               return xpcNotConnected;
+       }
+
+
+       /*
+        * Get the next available message entry from the local message queue.
+        * If none are available, we'll make sure that we grab the latest
+        * GP values.
+        */
+       ret = xpcTimeout;
+
+       while (1) {
+
+               put = (volatile s64) ch->w_local_GP.put;
+               if (put - (volatile s64) ch->w_remote_GP.get <
+                                                       ch->local_nentries) {
+
+                       /* There are available message entries. We need to try
+                        * to secure one for ourselves. We'll do this by trying
+                        * to increment w_local_GP.put as long as someone else
+                        * doesn't beat us to it. If they do, we'll have to
+                        * try again.
+                        */
+                       if (cmpxchg(&ch->w_local_GP.put, put, put + 1) ==
+                                                                       put) {
+                               /* we got the entry referenced by put */
+                               break;
+                       }
+                       continue;       /* try again */
+               }
+
+
+               /*
+                * There aren't any available msg entries at this time.
+                *
+                * In waiting for a message entry to become available,
+                * we set a timeout in case the other side is not
+                * sending completion IPIs. This lets us fake an IPI
+                * that will cause the IPI handler to fetch the latest
+                * GP values as if an IPI was sent by the other side.
+                */
+               if (ret == xpcTimeout) {
+                       xpc_IPI_send_local_msgrequest(ch);
+               }
+
+               if (flags & XPC_NOWAIT) {
+                       xpc_msgqueue_deref(ch);
+                       return xpcNoWait;
+               }
+
+               ret = xpc_allocate_msg_wait(ch);
+               if (ret != xpcInterrupted && ret != xpcTimeout) {
+                       xpc_msgqueue_deref(ch);
+                       return ret;
+               }
+       }
+
+
+       /* get the message's address and initialize it */
+       msg = (struct xpc_msg *) ((u64) ch->local_msgqueue +
+                               (put % ch->local_nentries) * ch->msg_size);
+
+
+       DBUG_ON(msg->flags != 0);
+       msg->number = put;
+
+       dev_dbg(xpc_chan, "w_local_GP.put changed to %ld; msg=0x%p, "
+               "msg_number=%ld, partid=%d, channel=%d\n", put + 1,
+               (void *) msg, msg->number, ch->partid, ch->number);
+
+       *address_of_msg = msg;
+
+       return xpcSuccess;
+}
+
+
+/*
+ * Allocate an entry for a message from the message queue associated with the
+ * specified channel. NOTE that this routine can sleep waiting for a message
+ * entry to become available. To not sleep, pass in the XPC_NOWAIT flag.
+ *
+ * Arguments:
+ *
+ *     partid - ID of partition to which the channel is connected.
+ *     ch_number - channel #.
+ *     flags - see xpc.h for valid flags.
+ *     payload - address of the allocated payload area pointer (filled in on
+ *               return) in which the user-defined message is constructed.
+ */
+enum xpc_retval
+xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
+{
+       struct xpc_partition *part = &xpc_partitions[partid];
+       enum xpc_retval ret = xpcUnknownReason;
+       struct xpc_msg *msg;
+
+
+       DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+       DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
+
+       *payload = NULL;
+
+       if (xpc_part_ref(part)) {
+               ret = xpc_allocate_msg(&part->channels[ch_number], flags, &msg);
+               xpc_part_deref(part);
+
+               if (msg != NULL) {
+                       *payload = &msg->payload;
+               }
+       }
+
+       return ret;
+}
+
+
+/*
+ * Now we actually send the messages that are ready to be sent by advancing
+ * the local message queue's Put value and then send an IPI to the recipient
+ * partition.
+ */
+static void
+xpc_send_msgs(struct xpc_channel *ch, s64 initial_put)
+{
+       struct xpc_msg *msg;
+       s64 put = initial_put + 1;
+       int send_IPI = 0;
+
+
+       while (1) {
+
+               while (1) {
+                       if (put == (volatile s64) ch->w_local_GP.put) {
+                               break;
+                       }
+
+                       msg = (struct xpc_msg *) ((u64) ch->local_msgqueue +
+                              (put % ch->local_nentries) * ch->msg_size);
+
+                       if (!(msg->flags & XPC_M_READY)) {
+                               break;
+                       }
+
+                       put++;
+               }
+
+               if (put == initial_put) {
+                       /* nothing's changed */
+                       break;
+               }
+
+               if (cmpxchg_rel(&ch->local_GP->put, initial_put, put) !=
+                                                               initial_put) {
+                       /* someone else beat us to it */
+                       DBUG_ON((volatile s64) ch->local_GP->put < initial_put);
+                       break;
+               }
+
+               /* we just set the new value of local_GP->put */
+
+               dev_dbg(xpc_chan, "local_GP->put changed to %ld, partid=%d, "
+                       "channel=%d\n", put, ch->partid, ch->number);
+
+               send_IPI = 1;
+
+               /*
+                * We need to ensure that the message referenced by
+                * local_GP->put is not XPC_M_READY or that local_GP->put
+                * equals w_local_GP.put, so we'll go have a look.
+                */
+               initial_put = put;
+       }
+
+       if (send_IPI) {
+               xpc_IPI_send_msgrequest(ch);
+       }
+}
+
+
+/*
+ * Common code that does the actual sending of the message by advancing the
+ * local message queue's Put value and sends an IPI to the partition the
+ * message is being sent to.
+ */
+static enum xpc_retval
+xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
+                       xpc_notify_func func, void *key)
+{
+       enum xpc_retval ret = xpcSuccess;
+       struct xpc_notify *notify = NULL;   // >>> to keep the compiler happy!!
+       s64 put, msg_number = msg->number;
+
+
+       DBUG_ON(notify_type == XPC_N_CALL && func == NULL);
+       DBUG_ON((((u64) msg - (u64) ch->local_msgqueue) / ch->msg_size) !=
+                                       msg_number % ch->local_nentries);
+       DBUG_ON(msg->flags & XPC_M_READY);
+
+       if (ch->flags & XPC_C_DISCONNECTING) {
+               /* drop the reference grabbed in xpc_allocate_msg() */
+               xpc_msgqueue_deref(ch);
+               return ch->reason;
+       }
+
+       if (notify_type != 0) {
+               /*
+                * Tell the remote side to send an ACK interrupt when the
+                * message has been delivered.
+                */
+               msg->flags |= XPC_M_INTERRUPT;
+
+               atomic_inc(&ch->n_to_notify);
+
+               notify = &ch->notify_queue[msg_number % ch->local_nentries];
+               notify->func = func;
+               notify->key = key;
+               (volatile u8) notify->type = notify_type;
+
+               // >>> is a mb() needed here?
+
+               if (ch->flags & XPC_C_DISCONNECTING) {
+                       /*
+                        * An error occurred between our last error check and
+                        * this one. We will try to clear the type field from
+                        * the notify entry. If we succeed then
+                        * xpc_disconnect_channel() didn't already process
+                        * the notify entry.
+                        */
+                       if (cmpxchg(&notify->type, notify_type, 0) ==
+                                                               notify_type) {
+                               atomic_dec(&ch->n_to_notify);
+                               ret = ch->reason;
+                       }
+
+                       /* drop the reference grabbed in xpc_allocate_msg() */
+                       xpc_msgqueue_deref(ch);
+                       return ret;
+               }
+       }
+
+       msg->flags |= XPC_M_READY;
+
+       /*
+        * The preceding store of msg->flags must occur before the following
+        * load of ch->local_GP->put.
+        */
+       mb();
+
+       /* see if the message is next in line to be sent, if so send it */
+
+       put = ch->local_GP->put;
+       if (put == msg_number) {
+               xpc_send_msgs(ch, put);
+       }
+
+       /* drop the reference grabbed in xpc_allocate_msg() */
+       xpc_msgqueue_deref(ch);
+       return ret;
+}
+
+
+/*
+ * Send a message previously allocated using xpc_initiate_allocate() on the
+ * specified channel connected to the specified partition.
+ *
+ * This routine will not wait for the message to be received, nor will
+ * notification be given when it does happen. Once this routine has returned
+ * the message entry allocated via xpc_initiate_allocate() is no longer
+ * accessable to the caller.
+ *
+ * This routine, although called by users, does not call xpc_part_ref() to
+ * ensure that the partition infrastructure is in place. It relies on the
+ * fact that we called xpc_msgqueue_ref() in xpc_allocate_msg().
+ *
+ * Arguments:
+ *
+ *     partid - ID of partition to which the channel is connected.
+ *     ch_number - channel # to send message on.
+ *     payload - pointer to the payload area allocated via
+ *                     xpc_initiate_allocate().
+ */
+enum xpc_retval
+xpc_initiate_send(partid_t partid, int ch_number, void *payload)
+{
+       struct xpc_partition *part = &xpc_partitions[partid];
+       struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
+       enum xpc_retval ret;
+
+
+       dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *) msg,
+               partid, ch_number);
+
+       DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+       DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
+       DBUG_ON(msg == NULL);
+
+       ret = xpc_send_msg(&part->channels[ch_number], msg, 0, NULL, NULL);
+
+       return ret;
+}
+
+
+/*
+ * Send a message previously allocated using xpc_initiate_allocate on the
+ * specified channel connected to the specified partition.
+ *
+ * This routine will not wait for the message to be sent. Once this routine
+ * has returned the message entry allocated via xpc_initiate_allocate() is no
+ * longer accessable to the caller.
+ *
+ * Once the remote end of the channel has received the message, the function
+ * passed as an argument to xpc_initiate_send_notify() will be called. This
+ * allows the sender to free up or re-use any buffers referenced by the
+ * message, but does NOT mean the message has been processed at the remote
+ * end by a receiver.
+ *
+ * If this routine returns an error, the caller's function will NOT be called.
+ *
+ * This routine, although called by users, does not call xpc_part_ref() to
+ * ensure that the partition infrastructure is in place. It relies on the
+ * fact that we called xpc_msgqueue_ref() in xpc_allocate_msg().
+ *
+ * Arguments:
+ *
+ *     partid - ID of partition to which the channel is connected.
+ *     ch_number - channel # to send message on.
+ *     payload - pointer to the payload area allocated via
+ *                     xpc_initiate_allocate().
+ *     func - function to call with asynchronous notification of message
+ *               receipt. THIS FUNCTION MUST BE NON-BLOCKING.
+ *     key - user-defined key to be passed to the function when it's called.
+ */
+enum xpc_retval
+xpc_initiate_send_notify(partid_t partid, int ch_number, void *payload,
+                               xpc_notify_func func, void *key)
+{
+       struct xpc_partition *part = &xpc_partitions[partid];
+       struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
+       enum xpc_retval ret;
+
+
+       dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *) msg,
+               partid, ch_number);
+
+       DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+       DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
+       DBUG_ON(msg == NULL);
+       DBUG_ON(func == NULL);
+
+       ret = xpc_send_msg(&part->channels[ch_number], msg, XPC_N_CALL,
+                                                               func, key);
+       return ret;
+}
+
+
+static struct xpc_msg *
+xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
+{
+       struct xpc_partition *part = &xpc_partitions[ch->partid];
+       struct xpc_msg *remote_msg, *msg;
+       u32 msg_index, nmsgs;
+       u64 msg_offset;
+       enum xpc_retval ret;
+
+
+       if (down_interruptible(&ch->msg_to_pull_sema) != 0) {
+               /* we were interrupted by a signal */
+               return NULL;
+       }
+
+       while (get >= ch->next_msg_to_pull) {
+
+               /* pull as many messages as are ready and able to be pulled */
+
+               msg_index = ch->next_msg_to_pull % ch->remote_nentries;
+
+               DBUG_ON(ch->next_msg_to_pull >=
+                                       (volatile s64) ch->w_remote_GP.put);
+               nmsgs =  (volatile s64) ch->w_remote_GP.put -
+                                               ch->next_msg_to_pull;
+               if (msg_index + nmsgs > ch->remote_nentries) {
+                       /* ignore the ones that wrap the msg queue for now */
+                       nmsgs = ch->remote_nentries - msg_index;
+               }
+
+               msg_offset = msg_index * ch->msg_size;
+               msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue +
+                                                               msg_offset);
+               remote_msg = (struct xpc_msg *) (ch->remote_msgqueue_pa +
+                                                               msg_offset);
+
+               if ((ret = xpc_pull_remote_cachelines(part, msg, remote_msg,
+                               nmsgs * ch->msg_size)) != xpcSuccess) {
+
+                       dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
+                               " msg %ld from partition %d, channel=%d, "
+                               "ret=%d\n", nmsgs, ch->next_msg_to_pull,
+                               ch->partid, ch->number, ret);
+
+                       XPC_DEACTIVATE_PARTITION(part, ret);
+
+                       up(&ch->msg_to_pull_sema);
+                       return NULL;
+               }
+
+               mb();   /* >>> this may not be needed, we're not sure */
+
+               ch->next_msg_to_pull += nmsgs;
+       }
+
+       up(&ch->msg_to_pull_sema);
+
+       /* return the message we were looking for */
+       msg_offset = (get % ch->remote_nentries) * ch->msg_size;
+       msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue + msg_offset);
+
+       return msg;
+}
+
+
+/*
+ * Get a message to be delivered.
+ */
+static struct xpc_msg *
+xpc_get_deliverable_msg(struct xpc_channel *ch)
+{
+       struct xpc_msg *msg = NULL;
+       s64 get;
+
+
+       do {
+               if ((volatile u32) ch->flags & XPC_C_DISCONNECTING) {
+                       break;
+               }
+
+               get = (volatile s64) ch->w_local_GP.get;
+               if (get == (volatile s64) ch->w_remote_GP.put) {
+                       break;
+               }
+
+               /* There are messages waiting to be pulled and delivered.
+                * We need to try to secure one for ourselves. We'll do this
+                * by trying to increment w_local_GP.get and hope that no one
+                * else beats us to it. If they do, we'll we'll simply have
+                * to try again for the next one.
+                */
+
+               if (cmpxchg(&ch->w_local_GP.get, get, get + 1) == get) {
+                       /* we got the entry referenced by get */
+
+                       dev_dbg(xpc_chan, "w_local_GP.get changed to %ld, "
+                               "partid=%d, channel=%d\n", get + 1,
+                               ch->partid, ch->number);
+
+                       /* pull the message from the remote partition */
+
+                       msg = xpc_pull_remote_msg(ch, get);
+
+                       DBUG_ON(msg != NULL && msg->number != get);
+                       DBUG_ON(msg != NULL && (msg->flags & XPC_M_DONE));
+                       DBUG_ON(msg != NULL && !(msg->flags & XPC_M_READY));
+
+                       break;
+               }
+
+       } while (1);
+
+       return msg;
+}
+
+
+/*
+ * Deliver a message to its intended recipient.
+ */
+void
+xpc_deliver_msg(struct xpc_channel *ch)
+{
+       struct xpc_msg *msg;
+
+
+       if ((msg = xpc_get_deliverable_msg(ch)) != NULL) {
+
+               /*
+                * This ref is taken to protect the payload itself from being
+                * freed before the user is finished with it, which the user
+                * indicates by calling xpc_initiate_received().
+                */
+               xpc_msgqueue_ref(ch);
+
+               atomic_inc(&ch->kthreads_active);
+
+               if (ch->func != NULL) {
+                       dev_dbg(xpc_chan, "ch->func() called, msg=0x%p, "
+                               "msg_number=%ld, partid=%d, channel=%d\n",
+                               (void *) msg, msg->number, ch->partid,
+                               ch->number);
+
+                       /* deliver the message to its intended recipient */
+                       ch->func(xpcMsgReceived, ch->partid, ch->number,
+                                       &msg->payload, ch->key);
+
+                       dev_dbg(xpc_chan, "ch->func() returned, msg=0x%p, "
+                               "msg_number=%ld, partid=%d, channel=%d\n",
+                               (void *) msg, msg->number, ch->partid,
+                               ch->number);
+               }
+
+               atomic_dec(&ch->kthreads_active);
+       }
+}
+
+
+/*
+ * Now we actually acknowledge the messages that have been delivered and ack'd
+ * by advancing the cached remote message queue's Get value and if requested
+ * send an IPI to the message sender's partition.
+ */
+static void
+xpc_acknowledge_msgs(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
+{
+       struct xpc_msg *msg;
+       s64 get = initial_get + 1;
+       int send_IPI = 0;
+
+
+       while (1) {
+
+               while (1) {
+                       if (get == (volatile s64) ch->w_local_GP.get) {
+                               break;
+                       }
+
+                       msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue +
+                              (get % ch->remote_nentries) * ch->msg_size);
+
+                       if (!(msg->flags & XPC_M_DONE)) {
+                               break;
+                       }
+
+                       msg_flags |= msg->flags;
+                       get++;
+               }
+
+               if (get == initial_get) {
+                       /* nothing's changed */
+                       break;
+               }
+
+               if (cmpxchg_rel(&ch->local_GP->get, initial_get, get) !=
+                                                               initial_get) {
+                       /* someone else beat us to it */
+                       DBUG_ON((volatile s64) ch->local_GP->get <=
+                                                               initial_get);
+                       break;
+               }
+
+               /* we just set the new value of local_GP->get */
+
+               dev_dbg(xpc_chan, "local_GP->get changed to %ld, partid=%d, "
+                       "channel=%d\n", get, ch->partid, ch->number);
+
+               send_IPI = (msg_flags & XPC_M_INTERRUPT);
+
+               /*
+                * We need to ensure that the message referenced by
+                * local_GP->get is not XPC_M_DONE or that local_GP->get
+                * equals w_local_GP.get, so we'll go have a look.
+                */
+               initial_get = get;
+       }
+
+       if (send_IPI) {
+               xpc_IPI_send_msgrequest(ch);
+       }
+}
+
+
+/*
+ * Acknowledge receipt of a delivered message.
+ *
+ * If a message has XPC_M_INTERRUPT set, send an interrupt to the partition
+ * that sent the message.
+ *
+ * This function, although called by users, does not call xpc_part_ref() to
+ * ensure that the partition infrastructure is in place. It relies on the
+ * fact that we called xpc_msgqueue_ref() in xpc_deliver_msg().
+ *
+ * Arguments:
+ *
+ *     partid - ID of partition to which the channel is connected.
+ *     ch_number - channel # message received on.
+ *     payload - pointer to the payload area allocated via
+ *                     xpc_initiate_allocate().
+ */
+void
+xpc_initiate_received(partid_t partid, int ch_number, void *payload)
+{
+       struct xpc_partition *part = &xpc_partitions[partid];
+       struct xpc_channel *ch;
+       struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
+       s64 get, msg_number = msg->number;
+
+
+       DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+       DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
+
+       ch = &part->channels[ch_number];
+
+       dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n",
+               (void *) msg, msg_number, ch->partid, ch->number);
+
+       DBUG_ON((((u64) msg - (u64) ch->remote_msgqueue) / ch->msg_size) !=
+                                       msg_number % ch->remote_nentries);
+       DBUG_ON(msg->flags & XPC_M_DONE);
+
+       msg->flags |= XPC_M_DONE;
+
+       /*
+        * The preceding store of msg->flags must occur before the following
+        * load of ch->local_GP->get.
+        */
+       mb();
+
+       /*
+        * See if this message is next in line to be acknowledged as having
+        * been delivered.
+        */
+       get = ch->local_GP->get;
+       if (get == msg_number) {
+               xpc_acknowledge_msgs(ch, get, msg->flags);
+       }
+
+       /* the call to xpc_msgqueue_ref() was done by xpc_deliver_msg()  */
+       xpc_msgqueue_deref(ch);
+}
+
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
new file mode 100644 (file)
index 0000000..177ddb7
--- /dev/null
@@ -0,0 +1,1064 @@
+/*
+ * 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-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+
+/*
+ * Cross Partition Communication (XPC) support - standard version.
+ *
+ *     XPC provides a message passing capability that crosses partition
+ *     boundaries. This module is made up of two parts:
+ *
+ *         partition   This part detects the presence/absence of other
+ *                     partitions. It provides a heartbeat and monitors
+ *                     the heartbeats of other partitions.
+ *
+ *         channel     This part manages the channels and sends/receives
+ *                     messages across them to/from other partitions.
+ *
+ *     There are a couple of additional functions residing in XP, which
+ *     provide an interface to XPC for its users.
+ *
+ *
+ *     Caveats:
+ *
+ *       . We currently have no way to determine which nasid an IPI came
+ *         from. Thus, xpc_IPI_send() does a remote AMO write followed by
+ *         an IPI. The AMO indicates where data is to be pulled from, so
+ *         after the IPI arrives, the remote partition checks the AMO word.
+ *         The IPI can actually arrive before the AMO however, so other code
+ *         must periodically check for this case. Also, remote AMO operations
+ *         do not reliably time out. Thus we do a remote PIO read solely to
+ *         know whether the remote partition is down and whether we should
+ *         stop sending IPIs to it. This remote PIO read operation is set up
+ *         in a special nofault region so SAL knows to ignore (and cleanup)
+ *         any errors due to the remote AMO write, PIO read, and/or PIO
+ *         write operations.
+ *
+ *         If/when new hardware solves this IPI problem, we should abandon
+ *         the current approach.
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/cache.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/uaccess.h>
+#include "xpc.h"
+
+
+/* define two XPC debug device structures to be used with dev_dbg() et al */
+
+struct device_driver xpc_dbg_name = {
+       .name = "xpc"
+};
+
+struct device xpc_part_dbg_subname = {
+       .bus_id = {0},          /* set to "part" at xpc_init() time */
+       .driver = &xpc_dbg_name
+};
+
+struct device xpc_chan_dbg_subname = {
+       .bus_id = {0},          /* set to "chan" at xpc_init() time */
+       .driver = &xpc_dbg_name
+};
+
+struct device *xpc_part = &xpc_part_dbg_subname;
+struct device *xpc_chan = &xpc_chan_dbg_subname;
+
+
+/* systune related variables for /proc/sys directories */
+
+static int xpc_hb_min = 1;
+static int xpc_hb_max = 10;
+
+static int xpc_hb_check_min = 10;
+static int xpc_hb_check_max = 120;
+
+static ctl_table xpc_sys_xpc_hb_dir[] = {
+       {
+               1,
+               "hb_interval",
+               &xpc_hb_interval,
+               sizeof(int),
+               0644,
+               NULL,
+               &proc_dointvec_minmax,
+               &sysctl_intvec,
+               NULL,
+               &xpc_hb_min, &xpc_hb_max
+       },
+       {
+               2,
+               "hb_check_interval",
+               &xpc_hb_check_interval,
+               sizeof(int),
+               0644,
+               NULL,
+               &proc_dointvec_minmax,
+               &sysctl_intvec,
+               NULL,
+               &xpc_hb_check_min, &xpc_hb_check_max
+       },
+       {0}
+};
+static ctl_table xpc_sys_xpc_dir[] = {
+       {
+               1,
+               "hb",
+               NULL,
+               0,
+               0555,
+               xpc_sys_xpc_hb_dir
+       },
+       {0}
+};
+static ctl_table xpc_sys_dir[] = {
+       {
+               1,
+               "xpc",
+               NULL,
+               0,
+               0555,
+               xpc_sys_xpc_dir
+       },
+       {0}
+};
+static struct ctl_table_header *xpc_sysctl;
+
+
+/* #of IRQs received */
+static atomic_t xpc_act_IRQ_rcvd;
+
+/* IRQ handler notifies this wait queue on receipt of an IRQ */
+static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
+
+static unsigned long xpc_hb_check_timeout;
+
+/* xpc_hb_checker thread exited notification */
+static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited);
+
+/* xpc_discovery thread exited notification */
+static DECLARE_MUTEX_LOCKED(xpc_discovery_exited);
+
+
+static struct timer_list xpc_hb_timer;
+
+
+static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *);
+
+
+/*
+ * Notify the heartbeat check thread that an IRQ has been received.
+ */
+static irqreturn_t
+xpc_act_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+       atomic_inc(&xpc_act_IRQ_rcvd);
+       wake_up_interruptible(&xpc_act_IRQ_wq);
+       return IRQ_HANDLED;
+}
+
+
+/*
+ * Timer to produce the heartbeat.  The timer structures function is
+ * already set when this is initially called.  A tunable is used to
+ * specify when the next timeout should occur.
+ */
+static void
+xpc_hb_beater(unsigned long dummy)
+{
+       xpc_vars->heartbeat++;
+
+       if (jiffies >= xpc_hb_check_timeout) {
+               wake_up_interruptible(&xpc_act_IRQ_wq);
+       }
+
+       xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ);
+       add_timer(&xpc_hb_timer);
+}
+
+
+/*
+ * This thread is responsible for nearly all of the partition
+ * activation/deactivation.
+ */
+static int
+xpc_hb_checker(void *ignore)
+{
+       int last_IRQ_count = 0;
+       int new_IRQ_count;
+       int force_IRQ=0;
+
+
+       /* this thread was marked active by xpc_hb_init() */
+
+       daemonize(XPC_HB_CHECK_THREAD_NAME);
+
+       set_cpus_allowed(current, cpumask_of_cpu(XPC_HB_CHECK_CPU));
+
+       xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
+
+       while (!(volatile int) xpc_exiting) {
+
+               /* wait for IRQ or timeout */
+               (void) wait_event_interruptible(xpc_act_IRQ_wq,
+                           (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) ||
+                                       jiffies >= xpc_hb_check_timeout ||
+                                               (volatile int) xpc_exiting));
+
+               dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have "
+                       "been received\n",
+                       (int) (xpc_hb_check_timeout - jiffies),
+                       atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count);
+
+
+               /* checking of remote heartbeats is skewed by IRQ handling */
+               if (jiffies >= xpc_hb_check_timeout) {
+                       dev_dbg(xpc_part, "checking remote heartbeats\n");
+                       xpc_check_remote_hb();
+
+                       /*
+                        * We need to periodically recheck to ensure no
+                        * IPI/AMO pairs have been missed.  That check
+                        * must always reset xpc_hb_check_timeout.
+                        */
+                       force_IRQ = 1;
+               }
+
+
+               new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd);
+               if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) {
+                       force_IRQ = 0;
+
+                       dev_dbg(xpc_part, "found an IRQ to process; will be "
+                               "resetting xpc_hb_check_timeout\n");
+
+                       last_IRQ_count += xpc_identify_act_IRQ_sender();
+                       if (last_IRQ_count < new_IRQ_count) {
+                               /* retry once to help avoid missing AMO */
+                               (void) xpc_identify_act_IRQ_sender();
+                       }
+                       last_IRQ_count = new_IRQ_count;
+
+                       xpc_hb_check_timeout = jiffies +
+                                          (xpc_hb_check_interval * HZ);
+               }
+       }
+
+       dev_dbg(xpc_part, "heartbeat checker is exiting\n");
+
+
+       /* mark this thread as inactive */
+       up(&xpc_hb_checker_exited);
+       return 0;
+}
+
+
+/*
+ * This thread will attempt to discover other partitions to activate
+ * based on info provided by SAL. This new thread is short lived and
+ * will exit once discovery is complete.
+ */
+static int
+xpc_initiate_discovery(void *ignore)
+{
+       daemonize(XPC_DISCOVERY_THREAD_NAME);
+
+       xpc_discovery();
+
+       dev_dbg(xpc_part, "discovery thread is exiting\n");
+
+       /* mark this thread as inactive */
+       up(&xpc_discovery_exited);
+       return 0;
+}
+
+
+/*
+ * Establish first contact with the remote partititon. This involves pulling
+ * the XPC per partition variables from the remote partition and waiting for
+ * the remote partition to pull ours.
+ */
+static enum xpc_retval
+xpc_make_first_contact(struct xpc_partition *part)
+{
+       enum xpc_retval ret;
+
+
+       while ((ret = xpc_pull_remote_vars_part(part)) != xpcSuccess) {
+               if (ret != xpcRetry) {
+                       XPC_DEACTIVATE_PARTITION(part, ret);
+                       return ret;
+               }
+
+               dev_dbg(xpc_chan, "waiting to make first contact with "
+                       "partition %d\n", XPC_PARTID(part));
+
+               /* wait a 1/4 of a second or so */
+               set_current_state(TASK_INTERRUPTIBLE);
+               (void) schedule_timeout(0.25 * HZ);
+
+               if (part->act_state == XPC_P_DEACTIVATING) {
+                       return part->reason;
+               }
+       }
+
+       return xpc_mark_partition_active(part);
+}
+
+
+/*
+ * The first kthread assigned to a newly activated partition is the one
+ * created by XPC HB with which it calls xpc_partition_up(). XPC hangs on to
+ * that kthread until the partition is brought down, at which time that kthread
+ * returns back to XPC HB. (The return of that kthread will signify to XPC HB
+ * that XPC has dismantled all communication infrastructure for the associated
+ * partition.) This kthread becomes the channel manager for that partition.
+ *
+ * Each active partition has a channel manager, who, besides connecting and
+ * disconnecting channels, will ensure that each of the partition's connected
+ * channels has the required number of assigned kthreads to get the work done.
+ */
+static void
+xpc_channel_mgr(struct xpc_partition *part)
+{
+       while (part->act_state != XPC_P_DEACTIVATING ||
+                               atomic_read(&part->nchannels_active) > 0) {
+
+               xpc_process_channel_activity(part);
+
+
+               /*
+                * Wait until we've been requested to activate kthreads or
+                * all of the channel's message queues have been torn down or
+                * a signal is pending.
+                *
+                * The channel_mgr_requests is set to 1 after being awakened,
+                * This is done to prevent the channel mgr from making one pass
+                * through the loop for each request, since he will
+                * be servicing all the requests in one pass. The reason it's
+                * set to 1 instead of 0 is so that other kthreads will know
+                * that the channel mgr is running and won't bother trying to
+                * wake him up.
+                */
+               atomic_dec(&part->channel_mgr_requests);
+               (void) wait_event_interruptible(part->channel_mgr_wq,
+                               (atomic_read(&part->channel_mgr_requests) > 0 ||
+                               (volatile u64) part->local_IPI_amo != 0 ||
+                               ((volatile u8) part->act_state ==
+                                                       XPC_P_DEACTIVATING &&
+                               atomic_read(&part->nchannels_active) == 0)));
+               atomic_set(&part->channel_mgr_requests, 1);
+
+               // >>> Does it need to wakeup periodically as well? In case we
+               // >>> miscalculated the #of kthreads to wakeup or create?
+       }
+}
+
+
+/*
+ * When XPC HB determines that a partition has come up, it will create a new
+ * kthread and that kthread will call this function to attempt to set up the
+ * basic infrastructure used for Cross Partition Communication with the newly
+ * upped partition.
+ *
+ * The kthread that was created by XPC HB and which setup the XPC
+ * infrastructure will remain assigned to the partition until the partition
+ * goes down. At which time the kthread will teardown the XPC infrastructure
+ * and then exit.
+ *
+ * XPC HB will put the remote partition's XPC per partition specific variables
+ * physical address into xpc_partitions[partid].remote_vars_part_pa prior to
+ * calling xpc_partition_up().
+ */
+static void
+xpc_partition_up(struct xpc_partition *part)
+{
+       DBUG_ON(part->channels != NULL);
+
+       dev_dbg(xpc_chan, "activating partition %d\n", XPC_PARTID(part));
+
+       if (xpc_setup_infrastructure(part) != xpcSuccess) {
+               return;
+       }
+
+       /*
+        * The kthread that XPC HB called us with will become the
+        * channel manager for this partition. It will not return
+        * back to XPC HB until the partition's XPC infrastructure
+        * has been dismantled.
+        */
+
+       (void) xpc_part_ref(part);      /* this will always succeed */
+
+       if (xpc_make_first_contact(part) == xpcSuccess) {
+               xpc_channel_mgr(part);
+       }
+
+       xpc_part_deref(part);
+
+       xpc_teardown_infrastructure(part);
+}
+
+
+static int
+xpc_activating(void *__partid)
+{
+       partid_t partid = (u64) __partid;
+       struct xpc_partition *part = &xpc_partitions[partid];
+       unsigned long irq_flags;
+       struct sched_param param = { sched_priority: MAX_USER_RT_PRIO - 1 };
+       int ret;
+
+
+       DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+
+       spin_lock_irqsave(&part->act_lock, irq_flags);
+
+       if (part->act_state == XPC_P_DEACTIVATING) {
+               part->act_state = XPC_P_INACTIVE;
+               spin_unlock_irqrestore(&part->act_lock, irq_flags);
+               part->remote_rp_pa = 0;
+               return 0;
+       }
+
+       /* indicate the thread is activating */
+       DBUG_ON(part->act_state != XPC_P_ACTIVATION_REQ);
+       part->act_state = XPC_P_ACTIVATING;
+
+       XPC_SET_REASON(part, 0, 0);
+       spin_unlock_irqrestore(&part->act_lock, irq_flags);
+
+       dev_dbg(xpc_part, "bringing partition %d up\n", partid);
+
+       daemonize("xpc%02d", partid);
+
+       /*
+        * This thread needs to run at a realtime priority to prevent a
+        * significant performance degradation.
+        */
+       ret = sched_setscheduler(current, SCHED_FIFO, &param);
+       if (ret != 0) {
+               dev_warn(xpc_part, "unable to set pid %d to a realtime "
+                       "priority, ret=%d\n", current->pid, ret);
+       }
+
+       /* allow this thread and its children to run on any CPU */
+       set_cpus_allowed(current, CPU_MASK_ALL);
+
+       /*
+        * Register the remote partition's AMOs with SAL so it can handle
+        * and cleanup errors within that address range should the remote
+        * partition go down. We don't unregister this range because it is
+        * difficult to tell when outstanding writes to the remote partition
+        * are finished and thus when it is safe to unregister. This should
+        * not result in wasted space in the SAL xp_addr_region table because
+        * we should get the same page for remote_amos_page_pa after module
+        * reloads and system reboots.
+        */
+       if (sn_register_xp_addr_region(part->remote_amos_page_pa,
+                                                       PAGE_SIZE, 1) < 0) {
+               dev_warn(xpc_part, "xpc_partition_up(%d) failed to register "
+                       "xp_addr region\n", partid);
+
+               spin_lock_irqsave(&part->act_lock, irq_flags);
+               part->act_state = XPC_P_INACTIVE;
+               XPC_SET_REASON(part, xpcPhysAddrRegFailed, __LINE__);
+               spin_unlock_irqrestore(&part->act_lock, irq_flags);
+               part->remote_rp_pa = 0;
+               return 0;
+       }
+
+       XPC_ALLOW_HB(partid, xpc_vars);
+       xpc_IPI_send_activated(part);
+
+
+       /*
+        * xpc_partition_up() holds this thread and marks this partition as
+        * XPC_P_ACTIVE by calling xpc_hb_mark_active().
+        */
+       (void) xpc_partition_up(part);
+
+       xpc_mark_partition_inactive(part);
+
+       if (part->reason == xpcReactivating) {
+               /* interrupting ourselves results in activating partition */
+               xpc_IPI_send_reactivate(part);
+       }
+
+       return 0;
+}
+
+
+void
+xpc_activate_partition(struct xpc_partition *part)
+{
+       partid_t partid = XPC_PARTID(part);
+       unsigned long irq_flags;
+       pid_t pid;
+
+
+       spin_lock_irqsave(&part->act_lock, irq_flags);
+
+       pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
+
+       DBUG_ON(part->act_state != XPC_P_INACTIVE);
+
+       if (pid > 0) {
+               part->act_state = XPC_P_ACTIVATION_REQ;
+               XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
+       } else {
+               XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
+       }
+
+       spin_unlock_irqrestore(&part->act_lock, irq_flags);
+}
+
+
+/*
+ * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified
+ * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more
+ * than one partition, we use an AMO_t structure per partition to indicate
+ * whether a partition has sent an IPI or not.  >>> If it has, then wake up the
+ * associated kthread to handle it.
+ *
+ * All SGI_XPC_NOTIFY IRQs received by XPC are the result of IPIs sent by XPC
+ * running on other partitions.
+ *
+ * Noteworthy Arguments:
+ *
+ *     irq - Interrupt ReQuest number. NOT USED.
+ *
+ *     dev_id - partid of IPI's potential sender.
+ *
+ *     regs - processor's context before the processor entered
+ *            interrupt code. NOT USED.
+ */
+irqreturn_t
+xpc_notify_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+       partid_t partid = (partid_t) (u64) dev_id;
+       struct xpc_partition *part = &xpc_partitions[partid];
+
+
+       DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+
+       if (xpc_part_ref(part)) {
+               xpc_check_for_channel_activity(part);
+
+               xpc_part_deref(part);
+       }
+       return IRQ_HANDLED;
+}
+
+
+/*
+ * Check to see if xpc_notify_IRQ_handler() dropped any IPIs on the floor
+ * because the write to their associated IPI amo completed after the IRQ/IPI
+ * was received.
+ */
+void
+xpc_dropped_IPI_check(struct xpc_partition *part)
+{
+       if (xpc_part_ref(part)) {
+               xpc_check_for_channel_activity(part);
+
+               part->dropped_IPI_timer.expires = jiffies +
+                                                       XPC_P_DROPPED_IPI_WAIT;
+               add_timer(&part->dropped_IPI_timer);
+               xpc_part_deref(part);
+       }
+}
+
+
+void
+xpc_activate_kthreads(struct xpc_channel *ch, int needed)
+{
+       int idle = atomic_read(&ch->kthreads_idle);
+       int assigned = atomic_read(&ch->kthreads_assigned);
+       int wakeup;
+
+
+       DBUG_ON(needed <= 0);
+
+       if (idle > 0) {
+               wakeup = (needed > idle) ? idle : needed;
+               needed -= wakeup;
+
+               dev_dbg(xpc_chan, "wakeup %d idle kthreads, partid=%d, "
+                       "channel=%d\n", wakeup, ch->partid, ch->number);
+
+               /* only wakeup the requested number of kthreads */
+               wake_up_nr(&ch->idle_wq, wakeup);
+       }
+
+       if (needed <= 0) {
+               return;
+       }
+
+       if (needed + assigned > ch->kthreads_assigned_limit) {
+               needed = ch->kthreads_assigned_limit - assigned;
+               // >>>should never be less than 0
+               if (needed <= 0) {
+                       return;
+               }
+       }
+
+       dev_dbg(xpc_chan, "create %d new kthreads, partid=%d, channel=%d\n",
+               needed, ch->partid, ch->number);
+
+       xpc_create_kthreads(ch, needed);
+}
+
+
+/*
+ * This function is where XPC's kthreads wait for messages to deliver.
+ */
+static void
+xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
+{
+       do {
+               /* deliver messages to their intended recipients */
+
+               while ((volatile s64) ch->w_local_GP.get <
+                               (volatile s64) ch->w_remote_GP.put &&
+                                       !((volatile u32) ch->flags &
+                                               XPC_C_DISCONNECTING)) {
+                       xpc_deliver_msg(ch);
+               }
+
+               if (atomic_inc_return(&ch->kthreads_idle) >
+                                               ch->kthreads_idle_limit) {
+                       /* too many idle kthreads on this channel */
+                       atomic_dec(&ch->kthreads_idle);
+                       break;
+               }
+
+               dev_dbg(xpc_chan, "idle kthread calling "
+                       "wait_event_interruptible_exclusive()\n");
+
+               (void) wait_event_interruptible_exclusive(ch->idle_wq,
+                               ((volatile s64) ch->w_local_GP.get <
+                                       (volatile s64) ch->w_remote_GP.put ||
+                               ((volatile u32) ch->flags &
+                                               XPC_C_DISCONNECTING)));
+
+               atomic_dec(&ch->kthreads_idle);
+
+       } while (!((volatile u32) ch->flags & XPC_C_DISCONNECTING));
+}
+
+
+static int
+xpc_daemonize_kthread(void *args)
+{
+       partid_t partid = XPC_UNPACK_ARG1(args);
+       u16 ch_number = XPC_UNPACK_ARG2(args);
+       struct xpc_partition *part = &xpc_partitions[partid];
+       struct xpc_channel *ch;
+       int n_needed;
+
+
+       daemonize("xpc%02dc%d", partid, ch_number);
+
+       dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n",
+               partid, ch_number);
+
+       ch = &part->channels[ch_number];
+
+       if (!(ch->flags & XPC_C_DISCONNECTING)) {
+               DBUG_ON(!(ch->flags & XPC_C_CONNECTED));
+
+               /* let registerer know that connection has been established */
+
+               if (atomic_read(&ch->kthreads_assigned) == 1) {
+                       xpc_connected_callout(ch);
+
+                       /*
+                        * It is possible that while the callout was being
+                        * made that the remote partition sent some messages.
+                        * If that is the case, we may need to activate
+                        * additional kthreads to help deliver them. We only
+                        * need one less than total #of messages to deliver.
+                        */
+                       n_needed = ch->w_remote_GP.put - ch->w_local_GP.get - 1;
+                       if (n_needed > 0 &&
+                                       !(ch->flags & XPC_C_DISCONNECTING)) {
+                               xpc_activate_kthreads(ch, n_needed);
+                       }
+               }
+
+               xpc_kthread_waitmsgs(part, ch);
+       }
+
+       if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
+                       ((ch->flags & XPC_C_CONNECTCALLOUT) ||
+                               (ch->reason != xpcUnregistering &&
+                                       ch->reason != xpcOtherUnregistering))) {
+               xpc_disconnected_callout(ch);
+       }
+
+
+       xpc_msgqueue_deref(ch);
+
+       dev_dbg(xpc_chan, "kthread exiting, partid=%d, channel=%d\n",
+               partid, ch_number);
+
+       xpc_part_deref(part);
+       return 0;
+}
+
+
+/*
+ * For each partition that XPC has established communications with, there is
+ * a minimum of one kernel thread assigned to perform any operation that
+ * may potentially sleep or block (basically the callouts to the asynchronous
+ * functions registered via xpc_connect()).
+ *
+ * Additional kthreads are created and destroyed by XPC as the workload
+ * demands.
+ *
+ * A kthread is assigned to one of the active channels that exists for a given
+ * partition.
+ */
+void
+xpc_create_kthreads(struct xpc_channel *ch, int needed)
+{
+       unsigned long irq_flags;
+       pid_t pid;
+       u64 args = XPC_PACK_ARGS(ch->partid, ch->number);
+
+
+       while (needed-- > 0) {
+               pid = kernel_thread(xpc_daemonize_kthread, (void *) args, 0);
+               if (pid < 0) {
+                       /* the fork failed */
+
+                       if (atomic_read(&ch->kthreads_assigned) <
+                                               ch->kthreads_idle_limit) {
+                               /*
+                                * Flag this as an error only if we have an
+                                * insufficient #of kthreads for the channel
+                                * to function.
+                                *
+                                * No xpc_msgqueue_ref() is needed here since
+                                * the channel mgr is doing this.
+                                */
+                               spin_lock_irqsave(&ch->lock, irq_flags);
+                               XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources,
+                                                               &irq_flags);
+                               spin_unlock_irqrestore(&ch->lock, irq_flags);
+                       }
+                       break;
+               }
+
+               /*
+                * The following is done on behalf of the newly created
+                * kthread. That kthread is responsible for doing the
+                * counterpart to the following before it exits.
+                */
+               (void) xpc_part_ref(&xpc_partitions[ch->partid]);
+               xpc_msgqueue_ref(ch);
+               atomic_inc(&ch->kthreads_assigned);
+               ch->kthreads_created++; // >>> temporary debug only!!!
+       }
+}
+
+
+void
+xpc_disconnect_wait(int ch_number)
+{
+       partid_t partid;
+       struct xpc_partition *part;
+       struct xpc_channel *ch;
+
+
+       /* now wait for all callouts to the caller's function to cease */
+       for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+               part = &xpc_partitions[partid];
+
+               if (xpc_part_ref(part)) {
+                       ch = &part->channels[ch_number];
+
+// >>> how do we keep from falling into the window between our check and going
+// >>> down and coming back up where sema is re-inited?
+                       if (ch->flags & XPC_C_SETUP) {
+                               (void) down(&ch->teardown_sema);
+                       }
+
+                       xpc_part_deref(part);
+               }
+       }
+}
+
+
+static void
+xpc_do_exit(void)
+{
+       partid_t partid;
+       int active_part_count;
+       struct xpc_partition *part;
+
+
+       /* now it's time to eliminate our heartbeat */
+       del_timer_sync(&xpc_hb_timer);
+       xpc_vars->heartbeating_to_mask = 0;
+
+       /* indicate to others that our reserved page is uninitialized */
+       xpc_rsvd_page->vars_pa = 0;
+
+       /*
+        * Ignore all incoming interrupts. Without interupts the heartbeat
+        * checker won't activate any new partitions that may come up.
+        */
+       free_irq(SGI_XPC_ACTIVATE, NULL);
+
+       /*
+        * Cause the heartbeat checker and the discovery threads to exit.
+        * We don't want them attempting to activate new partitions as we
+        * try to deactivate the existing ones.
+        */
+       xpc_exiting = 1;
+       wake_up_interruptible(&xpc_act_IRQ_wq);
+
+       /* wait for the heartbeat checker thread to mark itself inactive */
+       down(&xpc_hb_checker_exited);
+
+       /* wait for the discovery thread to mark itself inactive */
+       down(&xpc_discovery_exited);
+
+
+       set_current_state(TASK_INTERRUPTIBLE);
+       schedule_timeout(0.3 * HZ);
+       set_current_state(TASK_RUNNING);
+
+
+       /* wait for all partitions to become inactive */
+
+       do {
+               active_part_count = 0;
+
+               for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+                       part = &xpc_partitions[partid];
+                       if (part->act_state != XPC_P_INACTIVE) {
+                               active_part_count++;
+
+                               XPC_DEACTIVATE_PARTITION(part, xpcUnloading);
+                       }
+               }
+
+               if (active_part_count) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(0.3 * HZ);
+                       set_current_state(TASK_RUNNING);
+               }
+
+       } while (active_part_count > 0);
+
+
+       /* close down protections for IPI operations */
+       xpc_restrict_IPI_ops();
+
+
+       /* clear the interface to XPC's functions */
+       xpc_clear_interface();
+
+       if (xpc_sysctl) {
+               unregister_sysctl_table(xpc_sysctl);
+       }
+}
+
+
+int __init
+xpc_init(void)
+{
+       int ret;
+       partid_t partid;
+       struct xpc_partition *part;
+       pid_t pid;
+
+
+       /*
+        * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
+        * both a partition's reserved page and its XPC variables. Its size was
+        * based on the size of a reserved page. So we need to ensure that the
+        * XPC variables will fit as well.
+        */
+       if (XPC_VARS_ALIGNED_SIZE > XPC_RSVD_PAGE_ALIGNED_SIZE) {
+               dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n");
+               return -EPERM;
+       }
+       DBUG_ON((u64) xpc_remote_copy_buffer !=
+                               L1_CACHE_ALIGN((u64) xpc_remote_copy_buffer));
+
+       snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
+       snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
+
+       xpc_sysctl = register_sysctl_table(xpc_sys_dir, 1);
+
+       /*
+        * The first few fields of each entry of xpc_partitions[] need to
+        * be initialized now so that calls to xpc_connect() and
+        * xpc_disconnect() can be made prior to the activation of any remote
+        * partition. NOTE THAT NONE OF THE OTHER FIELDS BELONGING TO THESE
+        * ENTRIES ARE MEANINGFUL UNTIL AFTER AN ENTRY'S CORRESPONDING
+        * PARTITION HAS BEEN ACTIVATED.
+        */
+       for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+               part = &xpc_partitions[partid];
+
+               DBUG_ON((u64) part != L1_CACHE_ALIGN((u64) part));
+
+               part->act_IRQ_rcvd = 0;
+               spin_lock_init(&part->act_lock);
+               part->act_state = XPC_P_INACTIVE;
+               XPC_SET_REASON(part, 0, 0);
+               part->setup_state = XPC_P_UNSET;
+               init_waitqueue_head(&part->teardown_wq);
+               atomic_set(&part->references, 0);
+       }
+
+       /*
+        * Open up protections for IPI operations (and AMO operations on
+        * Shub 1.1 systems).
+        */
+       xpc_allow_IPI_ops();
+
+       /*
+        * Interrupts being processed will increment this atomic variable and
+        * awaken the heartbeat thread which will process the interrupts.
+        */
+       atomic_set(&xpc_act_IRQ_rcvd, 0);
+
+       /*
+        * This is safe to do before the xpc_hb_checker thread has started
+        * because the handler releases a wait queue.  If an interrupt is
+        * received before the thread is waiting, it will not go to sleep,
+        * but rather immediately process the interrupt.
+        */
+       ret = request_irq(SGI_XPC_ACTIVATE, xpc_act_IRQ_handler, 0,
+                                                       "xpc hb", NULL);
+       if (ret != 0) {
+               dev_err(xpc_part, "can't register ACTIVATE IRQ handler, "
+                       "errno=%d\n", -ret);
+
+               xpc_restrict_IPI_ops();
+
+               if (xpc_sysctl) {
+                       unregister_sysctl_table(xpc_sysctl);
+               }
+               return -EBUSY;
+       }
+
+       /*
+        * Fill the partition reserved page with the information needed by
+        * other partitions to discover we are alive and establish initial
+        * communications.
+        */
+       xpc_rsvd_page = xpc_rsvd_page_init();
+       if (xpc_rsvd_page == NULL) {
+               dev_err(xpc_part, "could not setup our reserved page\n");
+
+               free_irq(SGI_XPC_ACTIVATE, NULL);
+               xpc_restrict_IPI_ops();
+
+               if (xpc_sysctl) {
+                       unregister_sysctl_table(xpc_sysctl);
+               }
+               return -EBUSY;
+       }
+
+
+       /*
+        * Set the beating to other partitions into motion.  This is
+        * the last requirement for other partitions' discovery to
+        * initiate communications with us.
+        */
+       init_timer(&xpc_hb_timer);
+       xpc_hb_timer.function = xpc_hb_beater;
+       xpc_hb_beater(0);
+
+
+       /*
+        * The real work-horse behind xpc.  This processes incoming
+        * interrupts and monitors remote heartbeats.
+        */
+       pid = kernel_thread(xpc_hb_checker, NULL, 0);
+       if (pid < 0) {
+               dev_err(xpc_part, "failed while forking hb check thread\n");
+
+               /* indicate to others that our reserved page is uninitialized */
+               xpc_rsvd_page->vars_pa = 0;
+
+               del_timer_sync(&xpc_hb_timer);
+               free_irq(SGI_XPC_ACTIVATE, NULL);
+               xpc_restrict_IPI_ops();
+
+               if (xpc_sysctl) {
+                       unregister_sysctl_table(xpc_sysctl);
+               }
+               return -EBUSY;
+       }
+
+
+       /*
+        * Startup a thread that will attempt to discover other partitions to
+        * activate based on info provided by SAL. This new thread is short
+        * lived and will exit once discovery is complete.
+        */
+       pid = kernel_thread(xpc_initiate_discovery, NULL, 0);
+       if (pid < 0) {
+               dev_err(xpc_part, "failed while forking discovery thread\n");
+
+               /* mark this new thread as a non-starter */
+               up(&xpc_discovery_exited);
+
+               xpc_do_exit();
+               return -EBUSY;
+       }
+
+
+       /* set the interface to point at XPC's functions */
+       xpc_set_interface(xpc_initiate_connect, xpc_initiate_disconnect,
+                         xpc_initiate_allocate, xpc_initiate_send,
+                         xpc_initiate_send_notify, xpc_initiate_received,
+                         xpc_initiate_partid_to_nasids);
+
+       return 0;
+}
+module_init(xpc_init);
+
+
+void __exit
+xpc_exit(void)
+{
+       xpc_do_exit();
+}
+module_exit(xpc_exit);
+
+
+MODULE_AUTHOR("Silicon Graphics, Inc.");
+MODULE_DESCRIPTION("Cross Partition Communication (XPC) support");
+MODULE_LICENSE("GPL");
+
+module_param(xpc_hb_interval, int, 0);
+MODULE_PARM_DESC(xpc_hb_interval, "Number of seconds between "
+               "heartbeat increments.");
+
+module_param(xpc_hb_check_interval, int, 0);
+MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between "
+               "heartbeat checks.");
+
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
new file mode 100644 (file)
index 0000000..2c3c4a8
--- /dev/null
@@ -0,0 +1,984 @@
+/*
+ * 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-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+
+/*
+ * Cross Partition Communication (XPC) partition support.
+ *
+ *     This is the part of XPC that detects the presence/absence of
+ *     other partitions. It provides a heartbeat and monitors the
+ *     heartbeats of other partitions.
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/sysctl.h>
+#include <linux/cache.h>
+#include <linux/mmzone.h>
+#include <linux/nodemask.h>
+#include <asm/sn/bte.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/nodepda.h>
+#include <asm/sn/addrs.h>
+#include "xpc.h"
+
+
+/* XPC is exiting flag */
+int xpc_exiting;
+
+
+/* SH_IPI_ACCESS shub register value on startup */
+static u64 xpc_sh1_IPI_access;
+static u64 xpc_sh2_IPI_access0;
+static u64 xpc_sh2_IPI_access1;
+static u64 xpc_sh2_IPI_access2;
+static u64 xpc_sh2_IPI_access3;
+
+
+/* original protection values for each node */
+u64 xpc_prot_vec[MAX_COMPACT_NODES];
+
+
+/* this partition's reserved page */
+struct xpc_rsvd_page *xpc_rsvd_page;
+
+/* this partition's XPC variables (within the reserved page) */
+struct xpc_vars *xpc_vars;
+struct xpc_vars_part *xpc_vars_part;
+
+
+/*
+ * For performance reasons, each entry of xpc_partitions[] is cacheline
+ * aligned. And xpc_partitions[] is padded with an additional entry at the
+ * end so that the last legitimate entry doesn't share its cacheline with
+ * another variable.
+ */
+struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
+
+
+/*
+ * Generic buffer used to store a local copy of the remote partitions
+ * reserved page or XPC variables.
+ *
+ * xpc_discovery runs only once and is a seperate thread that is
+ * very likely going to be processing in parallel with receiving
+ * interrupts.
+ */
+char ____cacheline_aligned
+               xpc_remote_copy_buffer[XPC_RSVD_PAGE_ALIGNED_SIZE];
+
+
+/* systune related variables */
+int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
+int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_TIMEOUT;
+
+
+/*
+ * Given a nasid, get the physical address of the  partition's reserved page
+ * for that nasid. This function returns 0 on any error.
+ */
+static u64
+xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size)
+{
+       bte_result_t bte_res;
+       s64 status;
+       u64 cookie = 0;
+       u64 rp_pa = nasid;      /* seed with nasid */
+       u64 len = 0;
+
+
+       while (1) {
+
+               status = sn_partition_reserved_page_pa(buf, &cookie, &rp_pa,
+                                                               &len);
+
+               dev_dbg(xpc_part, "SAL returned with status=%li, cookie="
+                       "0x%016lx, address=0x%016lx, len=0x%016lx\n",
+                       status, cookie, rp_pa, len);
+
+               if (status != SALRET_MORE_PASSES) {
+                       break;
+               }
+
+               if (len > buf_size) {
+                       dev_err(xpc_part, "len (=0x%016lx) > buf_size\n", len);
+                       status = SALRET_ERROR;
+                       break;
+               }
+
+               bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_size,
+                                       (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+               if (bte_res != BTE_SUCCESS) {
+                       dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res);
+                       status = SALRET_ERROR;
+                       break;
+               }
+       }
+
+       if (status != SALRET_OK) {
+               rp_pa = 0;
+       }
+       dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n", rp_pa);
+       return rp_pa;
+}
+
+
+/*
+ * Fill the partition reserved page with the information needed by
+ * other partitions to discover we are alive and establish initial
+ * communications.
+ */
+struct xpc_rsvd_page *
+xpc_rsvd_page_init(void)
+{
+       struct xpc_rsvd_page *rp;
+       AMO_t *amos_page;
+       u64 rp_pa, next_cl, nasid_array = 0;
+       int i, ret;
+
+
+       /* get the local reserved page's address */
+
+       rp_pa = xpc_get_rsvd_page_pa(cnodeid_to_nasid(0),
+                                       (u64) xpc_remote_copy_buffer,
+                                               XPC_RSVD_PAGE_ALIGNED_SIZE);
+       if (rp_pa == 0) {
+               dev_err(xpc_part, "SAL failed to locate the reserved page\n");
+               return NULL;
+       }
+       rp = (struct xpc_rsvd_page *) __va(rp_pa);
+
+       if (rp->partid != sn_partition_id) {
+               dev_err(xpc_part, "the reserved page's partid of %d should be "
+                       "%d\n", rp->partid, sn_partition_id);
+               return NULL;
+       }
+
+       rp->version = XPC_RP_VERSION;
+
+       /*
+        * Place the XPC variables on the cache line following the
+        * reserved page structure.
+        */
+       next_cl = (u64) rp + XPC_RSVD_PAGE_ALIGNED_SIZE;
+       xpc_vars = (struct xpc_vars *) next_cl;
+
+       /*
+        * Before clearing xpc_vars, see if a page of AMOs had been previously
+        * allocated. If not we'll need to allocate one and set permissions
+        * so that cross-partition AMOs are allowed.
+        *
+        * The allocated AMO page needs MCA reporting to remain disabled after
+        * XPC has unloaded.  To make this work, we keep a copy of the pointer
+        * to this page (i.e., amos_page) in the struct xpc_vars structure,
+        * which is pointed to by the reserved page, and re-use that saved copy
+        * on subsequent loads of XPC. This AMO page is never freed, and its
+        * memory protections are never restricted.
+        */
+       if ((amos_page = xpc_vars->amos_page) == NULL) {
+               amos_page = (AMO_t *) mspec_kalloc_page(0);
+               if (amos_page == NULL) {
+                       dev_err(xpc_part, "can't allocate page of AMOs\n");
+                       return NULL;
+               }
+
+               /*
+                * Open up AMO-R/W to cpu.  This is done for Shub 1.1 systems
+                * when xpc_allow_IPI_ops() is called via xpc_hb_init().
+                */
+               if (!enable_shub_wars_1_1()) {
+                       ret = sn_change_memprotect(ia64_tpa((u64) amos_page),
+                                       PAGE_SIZE, SN_MEMPROT_ACCESS_CLASS_1,
+                                       &nasid_array);
+                       if (ret != 0) {
+                               dev_err(xpc_part, "can't change memory "
+                                       "protections\n");
+                               mspec_kfree_page((unsigned long) amos_page);
+                               return NULL;
+                       }
+               }
+       } else if (!IS_AMO_ADDRESS((u64) amos_page)) {
+               /*
+                * EFI's XPBOOT can also set amos_page in the reserved page,
+                * but it happens to leave it as an uncached physical address
+                * and we need it to be an uncached virtual, so we'll have to
+                * convert it.
+                */
+               if (!IS_AMO_PHYS_ADDRESS((u64) amos_page)) {
+                       dev_err(xpc_part, "previously used amos_page address "
+                               "is bad = 0x%p\n", (void *) amos_page);
+                       return NULL;
+               }
+               amos_page = (AMO_t *) TO_AMO((u64) amos_page);
+       }
+
+       memset(xpc_vars, 0, sizeof(struct xpc_vars));
+
+       /*
+        * Place the XPC per partition specific variables on the cache line
+        * following the XPC variables structure.
+        */
+       next_cl += XPC_VARS_ALIGNED_SIZE;
+       memset((u64 *) next_cl, 0, sizeof(struct xpc_vars_part) *
+                                                       XP_MAX_PARTITIONS);
+       xpc_vars_part = (struct xpc_vars_part *) next_cl;
+       xpc_vars->vars_part_pa = __pa(next_cl);
+
+       xpc_vars->version = XPC_V_VERSION;
+       xpc_vars->act_nasid = cpuid_to_nasid(0);
+       xpc_vars->act_phys_cpuid = cpu_physical_id(0);
+       xpc_vars->amos_page = amos_page;  /* save for next load of XPC */
+
+
+       /*
+        * Initialize the activation related AMO variables.
+        */
+       xpc_vars->act_amos = xpc_IPI_init(XP_MAX_PARTITIONS);
+       for (i = 1; i < XP_NASID_MASK_WORDS; i++) {
+               xpc_IPI_init(i + XP_MAX_PARTITIONS);
+       }
+       /* export AMO page's physical address to other partitions */
+       xpc_vars->amos_page_pa = ia64_tpa((u64) xpc_vars->amos_page);
+
+       /*
+        * This signifies to the remote partition that our reserved
+        * page is initialized.
+        */
+       (volatile u64) rp->vars_pa = __pa(xpc_vars);
+
+       return rp;
+}
+
+
+/*
+ * Change protections to allow IPI operations (and AMO operations on
+ * Shub 1.1 systems).
+ */
+void
+xpc_allow_IPI_ops(void)
+{
+       int node;
+       int nasid;
+
+
+       // >>> Change SH_IPI_ACCESS code to use SAL call once it is available.
+
+       if (is_shub2()) {
+               xpc_sh2_IPI_access0 =
+                       (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS0));
+               xpc_sh2_IPI_access1 =
+                       (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS1));
+               xpc_sh2_IPI_access2 =
+                       (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS2));
+               xpc_sh2_IPI_access3 =
+                       (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS3));
+
+               for_each_online_node(node) {
+                       nasid = cnodeid_to_nasid(node);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
+                                                               -1UL);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
+                                                               -1UL);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
+                                                               -1UL);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
+                                                               -1UL);
+               }
+
+       } else {
+               xpc_sh1_IPI_access =
+                       (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH1_IPI_ACCESS));
+
+               for_each_online_node(node) {
+                       nasid = cnodeid_to_nasid(node);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
+                                                               -1UL);
+
+                       /*
+                        * Since the BIST collides with memory operations on
+                        * SHUB 1.1 sn_change_memprotect() cannot be used.
+                        */
+                       if (enable_shub_wars_1_1()) {
+                               /* open up everything */
+                               xpc_prot_vec[node] = (u64) HUB_L((u64 *)
+                                               GLOBAL_MMR_ADDR(nasid,
+                                               SH1_MD_DQLP_MMR_DIR_PRIVEC0));
+                               HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid,
+                                               SH1_MD_DQLP_MMR_DIR_PRIVEC0),
+                                                               -1UL);
+                               HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid,
+                                               SH1_MD_DQRP_MMR_DIR_PRIVEC0),
+                                                               -1UL);
+                       }
+               }
+       }
+}
+
+
+/*
+ * Restrict protections to disallow IPI operations (and AMO operations on
+ * Shub 1.1 systems).
+ */
+void
+xpc_restrict_IPI_ops(void)
+{
+       int node;
+       int nasid;
+
+
+       // >>> Change SH_IPI_ACCESS code to use SAL call once it is available.
+
+       if (is_shub2()) {
+
+               for_each_online_node(node) {
+                       nasid = cnodeid_to_nasid(node);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
+                                                       xpc_sh2_IPI_access0);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
+                                                       xpc_sh2_IPI_access1);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
+                                                       xpc_sh2_IPI_access2);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
+                                                       xpc_sh2_IPI_access3);
+               }
+
+       } else {
+
+               for_each_online_node(node) {
+                       nasid = cnodeid_to_nasid(node);
+                       HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
+                                                       xpc_sh1_IPI_access);
+
+                       if (enable_shub_wars_1_1()) {
+                               HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid,
+                                               SH1_MD_DQLP_MMR_DIR_PRIVEC0),
+                                                       xpc_prot_vec[node]);
+                               HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid,
+                                               SH1_MD_DQRP_MMR_DIR_PRIVEC0),
+                                                       xpc_prot_vec[node]);
+                       }
+               }
+       }
+}
+
+
+/*
+ * At periodic intervals, scan through all active partitions and ensure
+ * their heartbeat is still active.  If not, the partition is deactivated.
+ */
+void
+xpc_check_remote_hb(void)
+{
+       struct xpc_vars *remote_vars;
+       struct xpc_partition *part;
+       partid_t partid;
+       bte_result_t bres;
+
+
+       remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer;
+
+       for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+               if (partid == sn_partition_id) {
+                       continue;
+               }
+
+               part = &xpc_partitions[partid];
+
+               if (part->act_state == XPC_P_INACTIVE ||
+                               part->act_state == XPC_P_DEACTIVATING) {
+                       continue;
+               }
+
+               /* pull the remote_hb cache line */
+               bres = xp_bte_copy(part->remote_vars_pa,
+                                       ia64_tpa((u64) remote_vars),
+                                       XPC_VARS_ALIGNED_SIZE,
+                                       (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+               if (bres != BTE_SUCCESS) {
+                       XPC_DEACTIVATE_PARTITION(part,
+                                               xpc_map_bte_errors(bres));
+                       continue;
+               }
+
+               dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat"
+                       " = %ld, kdb_status = %ld, HB_mask = 0x%lx\n", partid,
+                       remote_vars->heartbeat, part->last_heartbeat,
+                       remote_vars->kdb_status,
+                       remote_vars->heartbeating_to_mask);
+
+               if (((remote_vars->heartbeat == part->last_heartbeat) &&
+                       (remote_vars->kdb_status == 0)) ||
+                            !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) {
+
+                       XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
+                       continue;
+               }
+
+               part->last_heartbeat = remote_vars->heartbeat;
+       }
+}
+
+
+/*
+ * Get a copy of the remote partition's rsvd page.
+ *
+ * remote_rp points to a buffer that is cacheline aligned for BTE copies and
+ * assumed to be of size XPC_RSVD_PAGE_ALIGNED_SIZE.
+ */
+static enum xpc_retval
+xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
+               struct xpc_rsvd_page *remote_rp, u64 *remote_rsvd_page_pa)
+{
+       int bres, i;
+
+
+       /* get the reserved page's physical address */
+
+       *remote_rsvd_page_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp,
+                                               XPC_RSVD_PAGE_ALIGNED_SIZE);
+       if (*remote_rsvd_page_pa == 0) {
+               return xpcNoRsvdPageAddr;
+       }
+
+
+       /* pull over the reserved page structure */
+
+       bres = xp_bte_copy(*remote_rsvd_page_pa, ia64_tpa((u64) remote_rp),
+                               XPC_RSVD_PAGE_ALIGNED_SIZE,
+                               (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+       if (bres != BTE_SUCCESS) {
+               return xpc_map_bte_errors(bres);
+       }
+
+
+       if (discovered_nasids != NULL) {
+               for (i = 0; i < XP_NASID_MASK_WORDS; i++) {
+                       discovered_nasids[i] |= remote_rp->part_nasids[i];
+               }
+       }
+
+
+       /* check that the partid is for another partition */
+
+       if (remote_rp->partid < 1 ||
+                               remote_rp->partid > (XP_MAX_PARTITIONS - 1)) {
+               return xpcInvalidPartid;
+       }
+
+       if (remote_rp->partid == sn_partition_id) {
+               return xpcLocalPartid;
+       }
+
+
+       if (XPC_VERSION_MAJOR(remote_rp->version) !=
+                                       XPC_VERSION_MAJOR(XPC_RP_VERSION)) {
+               return xpcBadVersion;
+       }
+
+       return xpcSuccess;
+}
+
+
+/*
+ * Get a copy of the remote partition's XPC variables.
+ *
+ * remote_vars points to a buffer that is cacheline aligned for BTE copies and
+ * assumed to be of size XPC_VARS_ALIGNED_SIZE.
+ */
+static enum xpc_retval
+xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
+{
+       int bres;
+
+
+       if (remote_vars_pa == 0) {
+               return xpcVarsNotSet;
+       }
+
+
+       /* pull over the cross partition variables */
+
+       bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars),
+                               XPC_VARS_ALIGNED_SIZE,
+                               (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+       if (bres != BTE_SUCCESS) {
+               return xpc_map_bte_errors(bres);
+       }
+
+       if (XPC_VERSION_MAJOR(remote_vars->version) !=
+                                       XPC_VERSION_MAJOR(XPC_V_VERSION)) {
+               return xpcBadVersion;
+       }
+
+       return xpcSuccess;
+}
+
+
+/*
+ * Prior code has determine the nasid which generated an IPI.  Inspect
+ * that nasid to determine if its partition needs to be activated or
+ * deactivated.
+ *
+ * A partition is consider "awaiting activation" if our partition
+ * flags indicate it is not active and it has a heartbeat.  A
+ * partition is considered "awaiting deactivation" if our partition
+ * flags indicate it is active but it has no heartbeat or it is not
+ * sending its heartbeat to us.
+ *
+ * To determine the heartbeat, the remote nasid must have a properly
+ * initialized reserved page.
+ */
+static void
+xpc_identify_act_IRQ_req(int nasid)
+{
+       struct xpc_rsvd_page *remote_rp;
+       struct xpc_vars *remote_vars;
+       u64 remote_rsvd_page_pa;
+       u64 remote_vars_pa;
+       partid_t partid;
+       struct xpc_partition *part;
+       enum xpc_retval ret;
+
+
+       /* pull over the reserved page structure */
+
+       remote_rp = (struct xpc_rsvd_page *) xpc_remote_copy_buffer;
+
+       ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rsvd_page_pa);
+       if (ret != xpcSuccess) {
+               dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
+                       "which sent interrupt, reason=%d\n", nasid, ret);
+               return;
+       }
+
+       remote_vars_pa = remote_rp->vars_pa;
+       partid = remote_rp->partid;
+       part = &xpc_partitions[partid];
+
+
+       /* pull over the cross partition variables */
+
+       remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer;
+
+       ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
+       if (ret != xpcSuccess) {
+
+               dev_warn(xpc_part, "unable to get XPC variables from nasid %d, "
+                       "which sent interrupt, reason=%d\n", nasid, ret);
+
+               XPC_DEACTIVATE_PARTITION(part, ret);
+               return;
+       }
+
+
+       part->act_IRQ_rcvd++;
+
+       dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = "
+               "%ld:0x%lx\n", (int) nasid, (int) partid, part->act_IRQ_rcvd,
+               remote_vars->heartbeat, remote_vars->heartbeating_to_mask);
+
+
+       if (part->act_state == XPC_P_INACTIVE) {
+
+               part->remote_rp_pa = remote_rsvd_page_pa;
+               dev_dbg(xpc_part, "  remote_rp_pa = 0x%016lx\n",
+                       part->remote_rp_pa);
+
+               part->remote_vars_pa = remote_vars_pa;
+               dev_dbg(xpc_part, "  remote_vars_pa = 0x%016lx\n",
+                       part->remote_vars_pa);
+
+               part->last_heartbeat = remote_vars->heartbeat;
+               dev_dbg(xpc_part, "  last_heartbeat = 0x%016lx\n",
+                       part->last_heartbeat);
+
+               part->remote_vars_part_pa = remote_vars->vars_part_pa;
+               dev_dbg(xpc_part, "  remote_vars_part_pa = 0x%016lx\n",
+                       part->remote_vars_part_pa);
+
+               part->remote_act_nasid = remote_vars->act_nasid;
+               dev_dbg(xpc_part, "  remote_act_nasid = 0x%x\n",
+                       part->remote_act_nasid);
+
+               part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid;
+               dev_dbg(xpc_part, "  remote_act_phys_cpuid = 0x%x\n",
+                       part->remote_act_phys_cpuid);
+
+               part->remote_amos_page_pa = remote_vars->amos_page_pa;
+               dev_dbg(xpc_part, "  remote_amos_page_pa = 0x%lx\n",
+                       part->remote_amos_page_pa);
+
+               xpc_activate_partition(part);
+
+       } else if (part->remote_amos_page_pa != remote_vars->amos_page_pa ||
+                       !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) {
+
+               part->reactivate_nasid = nasid;
+               XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
+       }
+}
+
+
+/*
+ * Loop through the activation AMO variables and process any bits
+ * which are set.  Each bit indicates a nasid sending a partition
+ * activation or deactivation request.
+ *
+ * Return #of IRQs detected.
+ */
+int
+xpc_identify_act_IRQ_sender(void)
+{
+       int word, bit;
+       u64 nasid_mask;
+       u64 nasid;                      /* remote nasid */
+       int n_IRQs_detected = 0;
+       AMO_t *act_amos;
+       struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
+
+
+       act_amos = xpc_vars->act_amos;
+
+
+       /* scan through act AMO variable looking for non-zero entries */
+       for (word = 0; word < XP_NASID_MASK_WORDS; word++) {
+
+               nasid_mask = xpc_IPI_receive(&act_amos[word]);
+               if (nasid_mask == 0) {
+                       /* no IRQs from nasids in this variable */
+                       continue;
+               }
+
+               dev_dbg(xpc_part, "AMO[%d] gave back 0x%lx\n", word,
+                       nasid_mask);
+
+
+               /*
+                * If this nasid has been added to the machine since
+                * our partition was reset, this will retain the
+                * remote nasid in our reserved pages machine mask.
+                * This is used in the event of module reload.
+                */
+               rp->mach_nasids[word] |= nasid_mask;
+
+
+               /* locate the nasid(s) which sent interrupts */
+
+               for (bit = 0; bit < (8 * sizeof(u64)); bit++) {
+                       if (nasid_mask & (1UL << bit)) {
+                               n_IRQs_detected++;
+                               nasid = XPC_NASID_FROM_W_B(word, bit);
+                               dev_dbg(xpc_part, "interrupt from nasid %ld\n",
+                                       nasid);
+                               xpc_identify_act_IRQ_req(nasid);
+                       }
+               }
+       }
+       return n_IRQs_detected;
+}
+
+
+/*
+ * Mark specified partition as active.
+ */
+enum xpc_retval
+xpc_mark_partition_active(struct xpc_partition *part)
+{
+       unsigned long irq_flags;
+       enum xpc_retval ret;
+
+
+       dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part));
+
+       spin_lock_irqsave(&part->act_lock, irq_flags);
+       if (part->act_state == XPC_P_ACTIVATING) {
+               part->act_state = XPC_P_ACTIVE;
+               ret = xpcSuccess;
+       } else {
+               DBUG_ON(part->reason == xpcSuccess);
+               ret = part->reason;
+       }
+       spin_unlock_irqrestore(&part->act_lock, irq_flags);
+
+       return ret;
+}
+
+
+/*
+ * Notify XPC that the partition is down.
+ */
+void
+xpc_deactivate_partition(const int line, struct xpc_partition *part,
+                               enum xpc_retval reason)
+{
+       unsigned long irq_flags;
+       partid_t partid = XPC_PARTID(part);
+
+
+       spin_lock_irqsave(&part->act_lock, irq_flags);
+
+       if (part->act_state == XPC_P_INACTIVE) {
+               XPC_SET_REASON(part, reason, line);
+               spin_unlock_irqrestore(&part->act_lock, irq_flags);
+               if (reason == xpcReactivating) {
+                       /* we interrupt ourselves to reactivate partition */
+                       xpc_IPI_send_reactivate(part);
+               }
+               return;
+       }
+       if (part->act_state == XPC_P_DEACTIVATING) {
+               if ((part->reason == xpcUnloading && reason != xpcUnloading) ||
+                                       reason == xpcReactivating) {
+                       XPC_SET_REASON(part, reason, line);
+               }
+               spin_unlock_irqrestore(&part->act_lock, irq_flags);
+               return;
+       }
+
+       part->act_state = XPC_P_DEACTIVATING;
+       XPC_SET_REASON(part, reason, line);
+
+       spin_unlock_irqrestore(&part->act_lock, irq_flags);
+
+       XPC_DISALLOW_HB(partid, xpc_vars);
+
+       dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", partid,
+               reason);
+
+       xpc_partition_down(part, reason);
+}
+
+
+/*
+ * Mark specified partition as active.
+ */
+void
+xpc_mark_partition_inactive(struct xpc_partition *part)
+{
+       unsigned long irq_flags;
+
+
+       dev_dbg(xpc_part, "setting partition %d to INACTIVE\n",
+               XPC_PARTID(part));
+
+       spin_lock_irqsave(&part->act_lock, irq_flags);
+       part->act_state = XPC_P_INACTIVE;
+       spin_unlock_irqrestore(&part->act_lock, irq_flags);
+       part->remote_rp_pa = 0;
+}
+
+
+/*
+ * SAL has provided a partition and machine mask.  The partition mask
+ * contains a bit for each even nasid in our partition.  The machine
+ * mask contains a bit for each even nasid in the entire machine.
+ *
+ * Using those two bit arrays, we can determine which nasids are
+ * known in the machine.  Each should also have a reserved page
+ * initialized if they are available for partitioning.
+ */
+void
+xpc_discovery(void)
+{
+       void *remote_rp_base;
+       struct xpc_rsvd_page *remote_rp;
+       struct xpc_vars *remote_vars;
+       u64 remote_rsvd_page_pa;
+       u64 remote_vars_pa;
+       int region;
+       int max_regions;
+       int nasid;
+       struct xpc_rsvd_page *rp;
+       partid_t partid;
+       struct xpc_partition *part;
+       u64 *discovered_nasids;
+       enum xpc_retval ret;
+
+
+       remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RSVD_PAGE_ALIGNED_SIZE,
+                                               GFP_KERNEL, &remote_rp_base);
+       if (remote_rp == NULL) {
+               return;
+       }
+       remote_vars = (struct xpc_vars *) remote_rp;
+
+
+       discovered_nasids = kmalloc(sizeof(u64) * XP_NASID_MASK_WORDS,
+                                                       GFP_KERNEL);
+       if (discovered_nasids == NULL) {
+               kfree(remote_rp_base);
+               return;
+       }
+       memset(discovered_nasids, 0, sizeof(u64) * XP_NASID_MASK_WORDS);
+
+       rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
+
+       /*
+        * The term 'region' in this context refers to the minimum number of
+        * nodes that can comprise an access protection grouping. The access
+        * protection is in regards to memory, IOI and IPI.
+        */
+//>>> move the next two #defines into either include/asm-ia64/sn/arch.h or
+//>>> include/asm-ia64/sn/addrs.h
+#define SH1_MAX_REGIONS                64
+#define SH2_MAX_REGIONS                256
+       max_regions = is_shub2() ? SH2_MAX_REGIONS : SH1_MAX_REGIONS;
+
+       for (region = 0; region < max_regions; region++) {
+
+               if ((volatile int) xpc_exiting) {
+                       break;
+               }
+
+               dev_dbg(xpc_part, "searching region %d\n", region);
+
+               for (nasid = (region * sn_region_size * 2);
+                    nasid < ((region + 1) * sn_region_size * 2);
+                    nasid += 2) {
+
+                       if ((volatile int) xpc_exiting) {
+                               break;
+                       }
+
+                       dev_dbg(xpc_part, "checking nasid %d\n", nasid);
+
+
+                       if (XPC_NASID_IN_ARRAY(nasid, rp->part_nasids)) {
+                               dev_dbg(xpc_part, "PROM indicates Nasid %d is "
+                                       "part of the local partition; skipping "
+                                       "region\n", nasid);
+                               break;
+                       }
+
+                       if (!(XPC_NASID_IN_ARRAY(nasid, rp->mach_nasids))) {
+                               dev_dbg(xpc_part, "PROM indicates Nasid %d was "
+                                       "not on Numa-Link network at reset\n",
+                                       nasid);
+                               continue;
+                       }
+
+                       if (XPC_NASID_IN_ARRAY(nasid, discovered_nasids)) {
+                               dev_dbg(xpc_part, "Nasid %d is part of a "
+                                       "partition which was previously "
+                                       "discovered\n", nasid);
+                               continue;
+                       }
+
+
+                       /* pull over the reserved page structure */
+
+                       ret = xpc_get_remote_rp(nasid, discovered_nasids,
+                                             remote_rp, &remote_rsvd_page_pa);
+                       if (ret != xpcSuccess) {
+                               dev_dbg(xpc_part, "unable to get reserved page "
+                                       "from nasid %d, reason=%d\n", nasid,
+                                       ret);
+
+                               if (ret == xpcLocalPartid) {
+                                       break;
+                               }
+                               continue;
+                       }
+
+                       remote_vars_pa = remote_rp->vars_pa;
+
+                       partid = remote_rp->partid;
+                       part = &xpc_partitions[partid];
+
+
+                       /* pull over the cross partition variables */
+
+                       ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
+                       if (ret != xpcSuccess) {
+                               dev_dbg(xpc_part, "unable to get XPC variables "
+                                       "from nasid %d, reason=%d\n", nasid,
+                                       ret);
+
+                               XPC_DEACTIVATE_PARTITION(part, ret);
+                               continue;
+                       }
+
+                       if (part->act_state != XPC_P_INACTIVE) {
+                               dev_dbg(xpc_part, "partition %d on nasid %d is "
+                                       "already activating\n", partid, nasid);
+                               break;
+                       }
+
+                       /*
+                        * Register the remote partition's AMOs with SAL so it
+                        * can handle and cleanup errors within that address
+                        * range should the remote partition go down. We don't
+                        * unregister this range because it is difficult to
+                        * tell when outstanding writes to the remote partition
+                        * are finished and thus when it is thus safe to
+                        * unregister. This should not result in wasted space
+                        * in the SAL xp_addr_region table because we should
+                        * get the same page for remote_act_amos_pa after
+                        * module reloads and system reboots.
+                        */
+                       if (sn_register_xp_addr_region(
+                                           remote_vars->amos_page_pa,
+                                                       PAGE_SIZE, 1) < 0) {
+                               dev_dbg(xpc_part, "partition %d failed to "
+                                       "register xp_addr region 0x%016lx\n",
+                                       partid, remote_vars->amos_page_pa);
+
+                               XPC_SET_REASON(part, xpcPhysAddrRegFailed,
+                                               __LINE__);
+                               break;
+                       }
+
+                       /*
+                        * The remote nasid is valid and available.
+                        * Send an interrupt to that nasid to notify
+                        * it that we are ready to begin activation.
+                        */
+                       dev_dbg(xpc_part, "sending an interrupt to AMO 0x%lx, "
+                               "nasid %d, phys_cpuid 0x%x\n",
+                               remote_vars->amos_page_pa,
+                               remote_vars->act_nasid,
+                               remote_vars->act_phys_cpuid);
+
+                       xpc_IPI_send_activate(remote_vars);
+               }
+       }
+
+       kfree(discovered_nasids);
+       kfree(remote_rp_base);
+}
+
+
+/*
+ * Given a partid, get the nasids owned by that partition from the
+ * remote partition's reserved page.
+ */
+enum xpc_retval
+xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
+{
+       struct xpc_partition *part;
+       u64 part_nasid_pa;
+       int bte_res;
+
+
+       part = &xpc_partitions[partid];
+       if (part->remote_rp_pa == 0) {
+               return xpcPartitionDown;
+       }
+
+       part_nasid_pa = part->remote_rp_pa +
+               (u64) &((struct xpc_rsvd_page *) 0)->part_nasids;
+
+       bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask),
+                               L1_CACHE_ALIGN(XP_NASID_MASK_BYTES),
+                               (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+
+       return xpc_map_bte_errors(bte_res);
+}
+
diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c
new file mode 100644 (file)
index 0000000..78c13d6
--- /dev/null
@@ -0,0 +1,715 @@
+/*
+ * 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) 1999,2001-2005 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+/*
+ * Cross Partition Network Interface (XPNET) support
+ *
+ *     XPNET provides a virtual network layered on top of the Cross
+ *     Partition communication layer.
+ *
+ *     XPNET provides direct point-to-point and broadcast-like support
+ *     for an ethernet-like device.  The ethernet broadcast medium is
+ *     replaced with a point-to-point message structure which passes
+ *     pointers to a DMA-capable block that a remote partition should
+ *     retrieve and pass to the upper level networking layer.
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/smp.h>
+#include <linux/string.h>
+#include <asm/sn/bte.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/types.h>
+#include <asm/atomic.h>
+#include <asm/sn/xp.h>
+
+
+/*
+ * The message payload transferred by XPC.
+ *
+ * buf_pa is the physical address where the DMA should pull from.
+ *
+ * NOTE: for performance reasons, buf_pa should _ALWAYS_ begin on a
+ * cacheline boundary.  To accomplish this, we record the number of
+ * bytes from the beginning of the first cacheline to the first useful
+ * byte of the skb (leadin_ignore) and the number of bytes from the
+ * last useful byte of the skb to the end of the last cacheline
+ * (tailout_ignore).
+ *
+ * size is the number of bytes to transfer which includes the skb->len
+ * (useful bytes of the senders skb) plus the leadin and tailout
+ */
+struct xpnet_message {
+       u16 version;            /* Version for this message */
+       u16 embedded_bytes;     /* #of bytes embedded in XPC message */
+       u32 magic;              /* Special number indicating this is xpnet */
+       u64 buf_pa;             /* phys address of buffer to retrieve */
+       u32 size;               /* #of bytes in buffer */
+       u8 leadin_ignore;       /* #of bytes to ignore at the beginning */
+       u8 tailout_ignore;      /* #of bytes to ignore at the end */
+       unsigned char data;     /* body of small packets */
+};
+
+/*
+ * Determine the size of our message, the cacheline aligned size,
+ * and then the number of message will request from XPC.
+ *
+ * XPC expects each message to exist in an individual cacheline.
+ */
+#define XPNET_MSG_SIZE         (L1_CACHE_BYTES - XPC_MSG_PAYLOAD_OFFSET)
+#define XPNET_MSG_DATA_MAX     \
+               (XPNET_MSG_SIZE - (u64)(&((struct xpnet_message *)0)->data))
+#define XPNET_MSG_ALIGNED_SIZE (L1_CACHE_ALIGN(XPNET_MSG_SIZE))
+#define XPNET_MSG_NENTRIES     (PAGE_SIZE / XPNET_MSG_ALIGNED_SIZE)
+
+
+#define XPNET_MAX_KTHREADS     (XPNET_MSG_NENTRIES + 1)
+#define XPNET_MAX_IDLE_KTHREADS        (XPNET_MSG_NENTRIES + 1)
+
+/*
+ * Version number of XPNET implementation. XPNET can always talk to versions
+ * with same major #, and never talk to versions with a different version.
+ */
+#define _XPNET_VERSION(_major, _minor) (((_major) << 4) | (_minor))
+#define XPNET_VERSION_MAJOR(_v)                ((_v) >> 4)
+#define XPNET_VERSION_MINOR(_v)                ((_v) & 0xf)
+
+#define        XPNET_VERSION _XPNET_VERSION(1,0)               /* version 1.0 */
+#define        XPNET_VERSION_EMBED _XPNET_VERSION(1,1)         /* version 1.1 */
+#define XPNET_MAGIC    0x88786984 /* "XNET" */
+
+#define XPNET_VALID_MSG(_m)                                                 \
+   ((XPNET_VERSION_MAJOR(_m->version) == XPNET_VERSION_MAJOR(XPNET_VERSION)) \
+    && (msg->magic == XPNET_MAGIC))
+
+#define XPNET_DEVICE_NAME              "xp0"
+
+
+/*
+ * When messages are queued with xpc_send_notify, a kmalloc'd buffer
+ * of the following type is passed as a notification cookie.  When the
+ * notification function is called, we use the cookie to decide
+ * whether all outstanding message sends have completed.  The skb can
+ * then be released.
+ */
+struct xpnet_pending_msg {
+       struct list_head free_list;
+       struct sk_buff *skb;
+       atomic_t use_count;
+};
+
+/* driver specific structure pointed to by the device structure */
+struct xpnet_dev_private {
+       struct net_device_stats stats;
+};
+
+struct net_device *xpnet_device;
+
+/*
+ * When we are notified of other partitions activating, we add them to
+ * our bitmask of partitions to which we broadcast.
+ */
+static u64 xpnet_broadcast_partitions;
+/* protect above */
+static spinlock_t xpnet_broadcast_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Since the Block Transfer Engine (BTE) is being used for the transfer
+ * and it relies upon cache-line size transfers, we need to reserve at
+ * least one cache-line for head and tail alignment.  The BTE is
+ * limited to 8MB transfers.
+ *
+ * Testing has shown that changing MTU to greater than 64KB has no effect
+ * on TCP as the two sides negotiate a Max Segment Size that is limited
+ * to 64K.  Other protocols May use packets greater than this, but for
+ * now, the default is 64KB.
+ */
+#define XPNET_MAX_MTU (0x800000UL - L1_CACHE_BYTES)
+/* 32KB has been determined to be the ideal */
+#define XPNET_DEF_MTU (0x8000UL)
+
+
+/*
+ * The partition id is encapsulated in the MAC address.  The following
+ * define locates the octet the partid is in.
+ */
+#define XPNET_PARTID_OCTET     1
+#define XPNET_LICENSE_OCTET    2
+
+
+/*
+ * Define the XPNET debug device structure that is to be used with dev_dbg(),
+ * dev_err(), dev_warn(), and dev_info().
+ */
+struct device_driver xpnet_dbg_name = {
+       .name = "xpnet"
+};
+
+struct device xpnet_dbg_subname = {
+       .bus_id = {0},                  /* set to "" */
+       .driver = &xpnet_dbg_name
+};
+
+struct device *xpnet = &xpnet_dbg_subname;
+
+/*
+ * Packet was recevied by XPC and forwarded to us.
+ */
+static void
+xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
+{
+       struct sk_buff *skb;
+       bte_result_t bret;
+       struct xpnet_dev_private *priv =
+               (struct xpnet_dev_private *) xpnet_device->priv;
+
+
+       if (!XPNET_VALID_MSG(msg)) {
+               /*
+                * Packet with a different XPC version.  Ignore.
+                */
+               xpc_received(partid, channel, (void *) msg);
+
+               priv->stats.rx_errors++;
+
+               return;
+       }
+       dev_dbg(xpnet, "received 0x%lx, %d, %d, %d\n", msg->buf_pa, msg->size,
+               msg->leadin_ignore, msg->tailout_ignore);
+
+
+       /* reserve an extra cache line */
+       skb = dev_alloc_skb(msg->size + L1_CACHE_BYTES);
+       if (!skb) {
+               dev_err(xpnet, "failed on dev_alloc_skb(%d)\n",
+                       msg->size + L1_CACHE_BYTES);
+
+               xpc_received(partid, channel, (void *) msg);
+
+               priv->stats.rx_errors++;
+
+               return;
+       }
+
+       /*
+        * The allocated skb has some reserved space.
+        * In order to use bte_copy, we need to get the
+        * skb->data pointer moved forward.
+        */
+       skb_reserve(skb, (L1_CACHE_BYTES - ((u64)skb->data &
+                                           (L1_CACHE_BYTES - 1)) +
+                         msg->leadin_ignore));
+
+       /*
+        * Update the tail pointer to indicate data actually
+        * transferred.
+        */
+       skb_put(skb, (msg->size - msg->leadin_ignore - msg->tailout_ignore));
+
+       /*
+        * Move the data over from the the other side.
+        */
+       if ((XPNET_VERSION_MINOR(msg->version) == 1) &&
+                                               (msg->embedded_bytes != 0)) {
+               dev_dbg(xpnet, "copying embedded message. memcpy(0x%p, 0x%p, "
+                       "%lu)\n", skb->data, &msg->data,
+                       (size_t) msg->embedded_bytes);
+
+               memcpy(skb->data, &msg->data, (size_t) msg->embedded_bytes);
+       } else {
+               dev_dbg(xpnet, "transferring buffer to the skb->data area;\n\t"
+                       "bte_copy(0x%p, 0x%p, %hu)\n", (void *)msg->buf_pa,
+                       (void *)__pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
+                       msg->size);
+
+               bret = bte_copy(msg->buf_pa,
+                               __pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
+                               msg->size, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+
+               if (bret != BTE_SUCCESS) {
+                       // >>> Need better way of cleaning skb.  Currently skb
+                       // >>> appears in_use and we can't just call
+                       // >>> dev_kfree_skb.
+                       dev_err(xpnet, "bte_copy(0x%p, 0x%p, 0x%hx) returned "
+                               "error=0x%x\n", (void *)msg->buf_pa,
+                               (void *)__pa((u64)skb->data &
+                                                       ~(L1_CACHE_BYTES - 1)),
+                               msg->size, bret);
+
+                       xpc_received(partid, channel, (void *) msg);
+
+                       priv->stats.rx_errors++;
+
+                       return;
+               }
+       }
+
+       dev_dbg(xpnet, "<skb->head=0x%p skb->data=0x%p skb->tail=0x%p "
+               "skb->end=0x%p skb->len=%d\n", (void *) skb->head,
+               (void *) skb->data, (void *) skb->tail, (void *) skb->end,
+               skb->len);
+
+       skb->dev = xpnet_device;
+       skb->protocol = eth_type_trans(skb, xpnet_device);
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+       dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p "
+               "skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n",
+               (void *) skb->head, (void *) skb->data, (void *) skb->tail,
+               (void *) skb->end, skb->len);
+
+
+       xpnet_device->last_rx = jiffies;
+       priv->stats.rx_packets++;
+       priv->stats.rx_bytes += skb->len + ETH_HLEN;
+
+       netif_rx_ni(skb);
+       xpc_received(partid, channel, (void *) msg);
+}
+
+
+/*
+ * This is the handler which XPC calls during any sort of change in
+ * state or message reception on a connection.
+ */
+static void
+xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel,
+                         void *data, void *key)
+{
+       long bp;
+
+
+       DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+       DBUG_ON(channel != XPC_NET_CHANNEL);
+
+       switch(reason) {
+       case xpcMsgReceived:    /* message received */
+               DBUG_ON(data == NULL);
+
+               xpnet_receive(partid, channel, (struct xpnet_message *) data);
+               break;
+
+       case xpcConnected:      /* connection completed to a partition */
+               spin_lock_bh(&xpnet_broadcast_lock);
+               xpnet_broadcast_partitions |= 1UL << (partid -1 );
+               bp = xpnet_broadcast_partitions;
+               spin_unlock_bh(&xpnet_broadcast_lock);
+
+               netif_carrier_on(xpnet_device);
+
+               dev_dbg(xpnet, "%s connection created to partition %d; "
+                       "xpnet_broadcast_partitions=0x%lx\n",
+                       xpnet_device->name, partid, bp);
+               break;
+
+       default:
+               spin_lock_bh(&xpnet_broadcast_lock);
+               xpnet_broadcast_partitions &= ~(1UL << (partid -1 ));
+               bp = xpnet_broadcast_partitions;
+               spin_unlock_bh(&xpnet_broadcast_lock);
+
+               if (bp == 0) {
+                       netif_carrier_off(xpnet_device);
+               }
+
+               dev_dbg(xpnet, "%s disconnected from partition %d; "
+                       "xpnet_broadcast_partitions=0x%lx\n",
+                       xpnet_device->name, partid, bp);
+               break;
+
+       }
+}
+
+
+static int
+xpnet_dev_open(struct net_device *dev)
+{
+       enum xpc_retval ret;
+
+
+       dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %d, "
+               "%d)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
+               XPNET_MSG_SIZE, XPNET_MSG_NENTRIES, XPNET_MAX_KTHREADS,
+               XPNET_MAX_IDLE_KTHREADS);
+
+       ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL,
+                         XPNET_MSG_SIZE, XPNET_MSG_NENTRIES,
+                         XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS);
+       if (ret != xpcSuccess) {
+               dev_err(xpnet, "ifconfig up of %s failed on XPC connect, "
+                       "ret=%d\n", dev->name, ret);
+
+               return -ENOMEM;
+       }
+
+       dev_dbg(xpnet, "ifconfig up of %s; XPC connected\n", dev->name);
+
+       return 0;
+}
+
+
+static int
+xpnet_dev_stop(struct net_device *dev)
+{
+       xpc_disconnect(XPC_NET_CHANNEL);
+
+       dev_dbg(xpnet, "ifconfig down of %s; XPC disconnected\n", dev->name);
+
+       return 0;
+}
+
+
+static int
+xpnet_dev_change_mtu(struct net_device *dev, int new_mtu)
+{
+       /* 68 comes from min TCP+IP+MAC header */
+       if ((new_mtu < 68) || (new_mtu > XPNET_MAX_MTU)) {
+               dev_err(xpnet, "ifconfig %s mtu %d failed; value must be "
+                       "between 68 and %ld\n", dev->name, new_mtu,
+                       XPNET_MAX_MTU);
+               return -EINVAL;
+       }
+
+       dev->mtu = new_mtu;
+       dev_dbg(xpnet, "ifconfig %s mtu set to %d\n", dev->name, new_mtu);
+       return 0;
+}
+
+
+/*
+ * Required for the net_device structure.
+ */
+static int
+xpnet_dev_set_config(struct net_device *dev, struct ifmap *new_map)
+{
+       return 0;
+}
+
+
+/*
+ * Return statistics to the caller.
+ */
+static struct net_device_stats *
+xpnet_dev_get_stats(struct net_device *dev)
+{
+       struct xpnet_dev_private *priv;
+
+
+       priv = (struct xpnet_dev_private *) dev->priv;
+
+       return &priv->stats;
+}
+
+
+/*
+ * Notification that the other end has received the message and
+ * DMA'd the skb information.  At this point, they are done with
+ * our side.  When all recipients are done processing, we
+ * release the skb and then release our pending message structure.
+ */
+static void
+xpnet_send_completed(enum xpc_retval reason, partid_t partid, int channel,
+                       void *__qm)
+{
+       struct xpnet_pending_msg *queued_msg =
+               (struct xpnet_pending_msg *) __qm;
+
+
+       DBUG_ON(queued_msg == NULL);
+
+       dev_dbg(xpnet, "message to %d notified with reason %d\n",
+               partid, reason);
+
+       if (atomic_dec_return(&queued_msg->use_count) == 0) {
+               dev_dbg(xpnet, "all acks for skb->head=-x%p\n",
+                       (void *) queued_msg->skb->head);
+
+               dev_kfree_skb_any(queued_msg->skb);
+               kfree(queued_msg);
+       }
+}
+
+
+/*
+ * Network layer has formatted a packet (skb) and is ready to place it
+ * "on the wire".  Prepare and send an xpnet_message to all partitions
+ * which have connected with us and are targets of this packet.
+ *
+ * MAC-NOTE:  For the XPNET driver, the MAC address contains the
+ * destination partition_id.  If the destination partition id word
+ * is 0xff, this packet is to broadcast to all partitions.
+ */
+static int
+xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct xpnet_pending_msg *queued_msg;
+       enum xpc_retval ret;
+       struct xpnet_message *msg;
+       u64 start_addr, end_addr;
+       long dp;
+       u8 second_mac_octet;
+       partid_t dest_partid;
+       struct xpnet_dev_private *priv;
+       u16 embedded_bytes;
+
+
+       priv = (struct xpnet_dev_private *) dev->priv;
+
+
+       dev_dbg(xpnet, ">skb->head=0x%p skb->data=0x%p skb->tail=0x%p "
+               "skb->end=0x%p skb->len=%d\n", (void *) skb->head,
+               (void *) skb->data, (void *) skb->tail, (void *) skb->end,
+               skb->len);
+
+
+       /*
+        * The xpnet_pending_msg tracks how many outstanding
+        * xpc_send_notifies are relying on this skb.  When none
+        * remain, release the skb.
+        */
+       queued_msg = kmalloc(sizeof(struct xpnet_pending_msg), GFP_ATOMIC);
+       if (queued_msg == NULL) {
+               dev_warn(xpnet, "failed to kmalloc %ld bytes; dropping "
+                       "packet\n", sizeof(struct xpnet_pending_msg));
+
+               priv->stats.tx_errors++;
+
+               return -ENOMEM;
+       }
+
+
+       /* get the beginning of the first cacheline and end of last */
+       start_addr = ((u64) skb->data & ~(L1_CACHE_BYTES - 1));
+       end_addr = L1_CACHE_ALIGN((u64) skb->tail);
+
+       /* calculate how many bytes to embed in the XPC message */
+       embedded_bytes = 0;
+       if (unlikely(skb->len <= XPNET_MSG_DATA_MAX)) {
+               /* skb->data does fit so embed */
+               embedded_bytes = skb->len;
+       }
+
+
+       /*
+        * Since the send occurs asynchronously, we set the count to one
+        * and begin sending.  Any sends that happen to complete before
+        * we are done sending will not free the skb.  We will be left
+        * with that task during exit.  This also handles the case of
+        * a packet destined for a partition which is no longer up.
+        */
+       atomic_set(&queued_msg->use_count, 1);
+       queued_msg->skb = skb;
+
+
+       second_mac_octet = skb->data[XPNET_PARTID_OCTET];
+       if (second_mac_octet == 0xff) {
+               /* we are being asked to broadcast to all partitions */
+               dp = xpnet_broadcast_partitions;
+       } else if (second_mac_octet != 0) {
+               dp = xpnet_broadcast_partitions &
+                                       (1UL << (second_mac_octet - 1));
+       } else {
+               /* 0 is an invalid partid.  Ignore */
+               dp = 0;
+       }
+       dev_dbg(xpnet, "destination Partitions mask (dp) = 0x%lx\n", dp);
+
+       /*
+        * If we wanted to allow promiscous mode to work like an
+        * unswitched network, this would be a good point to OR in a
+        * mask of partitions which should be receiving all packets.
+        */
+
+       /*
+        * Main send loop.
+        */
+       for (dest_partid = 1; dp && dest_partid < XP_MAX_PARTITIONS;
+            dest_partid++) {
+
+
+               if (!(dp & (1UL << (dest_partid - 1)))) {
+                       /* not destined for this partition */
+                       continue;
+               }
+
+               /* remove this partition from the destinations mask */
+               dp &= ~(1UL << (dest_partid - 1));
+
+
+               /* found a partition to send to */
+
+               ret = xpc_allocate(dest_partid, XPC_NET_CHANNEL,
+                                  XPC_NOWAIT, (void **)&msg);
+               if (unlikely(ret != xpcSuccess)) {
+                       continue;
+               }
+
+               msg->embedded_bytes = embedded_bytes;
+               if (unlikely(embedded_bytes != 0)) {
+                       msg->version = XPNET_VERSION_EMBED;
+                       dev_dbg(xpnet, "calling memcpy(0x%p, 0x%p, 0x%lx)\n",
+                               &msg->data, skb->data, (size_t) embedded_bytes);
+                       memcpy(&msg->data, skb->data, (size_t) embedded_bytes);
+               } else {
+                       msg->version = XPNET_VERSION;
+               }
+               msg->magic = XPNET_MAGIC;
+               msg->size = end_addr - start_addr;
+               msg->leadin_ignore = (u64) skb->data - start_addr;
+               msg->tailout_ignore = end_addr - (u64) skb->tail;
+               msg->buf_pa = __pa(start_addr);
+
+               dev_dbg(xpnet, "sending XPC message to %d:%d\nmsg->buf_pa="
+                       "0x%lx, msg->size=%u, msg->leadin_ignore=%u, "
+                       "msg->tailout_ignore=%u\n", dest_partid,
+                       XPC_NET_CHANNEL, msg->buf_pa, msg->size,
+                       msg->leadin_ignore, msg->tailout_ignore);
+
+
+               atomic_inc(&queued_msg->use_count);
+
+               ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, msg,
+                                     xpnet_send_completed, queued_msg);
+               if (unlikely(ret != xpcSuccess)) {
+                       atomic_dec(&queued_msg->use_count);
+                       continue;
+               }
+
+       }
+
+       if (atomic_dec_return(&queued_msg->use_count) == 0) {
+               dev_dbg(xpnet, "no partitions to receive packet destined for "
+                       "%d\n", dest_partid);
+
+
+               dev_kfree_skb(skb);
+               kfree(queued_msg);
+       }
+
+       priv->stats.tx_packets++;
+       priv->stats.tx_bytes += skb->len;
+
+       return 0;
+}
+
+
+/*
+ * Deal with transmit timeouts coming from the network layer.
+ */
+static void
+xpnet_dev_tx_timeout (struct net_device *dev)
+{
+       struct xpnet_dev_private *priv;
+
+
+       priv = (struct xpnet_dev_private *) dev->priv;
+
+       priv->stats.tx_errors++;
+       return;
+}
+
+
+static int __init
+xpnet_init(void)
+{
+       int i;
+       u32 license_num;
+       int result = -ENOMEM;
+
+
+       dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
+
+       /*
+        * use ether_setup() to init the majority of our device
+        * structure and then override the necessary pieces.
+        */
+       xpnet_device = alloc_netdev(sizeof(struct xpnet_dev_private),
+                                   XPNET_DEVICE_NAME, ether_setup);
+       if (xpnet_device == NULL) {
+               return -ENOMEM;
+       }
+
+       netif_carrier_off(xpnet_device);
+
+       xpnet_device->mtu = XPNET_DEF_MTU;
+       xpnet_device->change_mtu = xpnet_dev_change_mtu;
+       xpnet_device->open = xpnet_dev_open;
+       xpnet_device->get_stats = xpnet_dev_get_stats;
+       xpnet_device->stop = xpnet_dev_stop;
+       xpnet_device->hard_start_xmit = xpnet_dev_hard_start_xmit;
+       xpnet_device->tx_timeout = xpnet_dev_tx_timeout;
+       xpnet_device->set_config = xpnet_dev_set_config;
+
+       /*
+        * Multicast assumes the LSB of the first octet is set for multicast
+        * MAC addresses.  We chose the first octet of the MAC to be unlikely
+        * to collide with any vendor's officially issued MAC.
+        */
+       xpnet_device->dev_addr[0] = 0xfe;
+       xpnet_device->dev_addr[XPNET_PARTID_OCTET] = sn_partition_id;
+       license_num = sn_partition_serial_number_val();
+       for (i = 3; i >= 0; i--) {
+               xpnet_device->dev_addr[XPNET_LICENSE_OCTET + i] =
+                                                       license_num & 0xff;
+               license_num = license_num >> 8;
+       }
+
+       /*
+        * ether_setup() sets this to a multicast device.  We are
+        * really not supporting multicast at this time.
+        */
+       xpnet_device->flags &= ~IFF_MULTICAST;
+
+       /*
+        * No need to checksum as it is a DMA transfer.  The BTE will
+        * report an error if the data is not retrievable and the
+        * packet will be dropped.
+        */
+       xpnet_device->features = NETIF_F_NO_CSUM;
+
+       result = register_netdev(xpnet_device);
+       if (result != 0) {
+               free_netdev(xpnet_device);
+       }
+
+       return result;
+}
+module_init(xpnet_init);
+
+
+static void __exit
+xpnet_exit(void)
+{
+       dev_info(xpnet, "unregistering network device %s\n",
+               xpnet_device[0].name);
+
+       unregister_netdev(xpnet_device);
+
+       free_netdev(xpnet_device);
+}
+module_exit(xpnet_exit);
+
+
+MODULE_AUTHOR("Silicon Graphics, Inc.");
+MODULE_DESCRIPTION("Cross Partition Network adapter (XPNET)");
+MODULE_LICENSE("GPL");
+
index c90685985d815fc4225d384ee95c5a98d8aa65ec..64af2b2c17879181e0610cdaa7fb10dfdb8bf26e 100644 (file)
@@ -301,7 +301,7 @@ void sn_dma_flush(uint64_t addr)
                spin_lock_irqsave(&((struct sn_flush_device_list *)p)->
                                  sfdl_flush_lock, flags);
 
-               p->sfdl_flush_value = 0;
+               *p->sfdl_flush_addr = 0;
 
                /* force an interrupt. */
                *(volatile uint32_t *)(p->sfdl_force_int_addr) = 1;
index 54a0dd447e76afe378ed7c51676453046eb9ff8e..8dae9eb45456d97525a6745a766f903eee2323d6 100644 (file)
@@ -431,7 +431,7 @@ tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size)
        ca_dmamap->cad_dma_addr = bus_addr;
        ca_dmamap->cad_gart_size = entries;
        ca_dmamap->cad_gart_entry = entry;
-       list_add(&ca_dmamap->cad_list, &tioca_kern->ca_list);
+       list_add(&ca_dmamap->cad_list, &tioca_kern->ca_dmamaps);
 
        if (xio_addr % ps) {
                tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr);
index 7dbf997ff20525dd4ae6bf1ec2347a2a5c206b25..5649fbae430ebefeb525e529c5669bc45bfec929 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:05:59 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:23 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -135,7 +137,6 @@ CONFIG_PARPORT_1284=y
 #
 CONFIG_AMIGA_FLOPPY=y
 CONFIG_AMIGA_Z2RAM=y
-# CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -223,17 +224,12 @@ CONFIG_SCSI_CONSTANTS=y
 #
 # SCSI low-level drivers
 #
-# CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_PPA is not set
@@ -244,7 +240,6 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_A3000_SCSI=y
 CONFIG_A2091_SCSI=y
@@ -492,7 +487,6 @@ CONFIG_HYDRA=m
 CONFIG_ZORRO8390=m
 CONFIG_APNE=m
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
@@ -620,7 +614,6 @@ CONFIG_SERIO_SERPORT=m
 # CONFIG_SERIO_PARKBD is not set
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 505a2968e60446443cd9c0dc1b6240b4e29939e7..63024b0b7ac3a0d05c58f125602cf50653b1b7f8 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:00 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:27 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 617aa73c3250dee5c93bcb9e00e51d7e6e805524..6433da2d2ce2ab65fcac9130869d9a0da76511d6 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:18 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:32 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -531,7 +533,6 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index b501db51d9ec71c177fa994b9242019c19e6f820..da2a23a214632265c4b61c83c7c2f7ba2f474ece 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:19 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:37 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -496,7 +498,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 2bf6cef4f2b21e800c642ef5e5b442245ec133f3..51251883adf863c55442a268404748ccd1d1a0eb 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:21 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:41 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 7074f856820c3971a81ed6908a9b1678c3e6897d..15b80abfe94a53e2462926f26d2417bed1113ceb 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:24 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:45 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -540,7 +542,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 61f09bc4846a2d56a0d7f0e2636274a151b70708..f0d5534f683087c6771ad41cfc11b39ee648d5a0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:28 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:50 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 69c01004ec412d1ade4ddadaf08c5eef6175f85e..1d5c46ff3c819d425c3a98a6bb05f5402b4e12f4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:31 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:53 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 550ec26006c1cdbbd0b7706fb6778319e659bd76..856238634d424ad3c9f62d88282e5b74f08bf1f9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:34 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:58 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -125,7 +127,6 @@ CONFIG_FW_LOADER=m
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
@@ -210,17 +211,12 @@ CONFIG_SCSI_CONSTANTS=y
 #
 # SCSI low-level drivers
 #
-# CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_NCR53C406A is not set
@@ -229,7 +225,6 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -466,7 +461,6 @@ CONFIG_EQUALIZER=m
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
@@ -570,7 +564,6 @@ CONFIG_SERIO_Q40KBD=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 5b5a619645aad9abb69f1b203cf0677e09611dc1..af903b5c5708c8150ddba154ae96190eac314175 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:37 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:35:02 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -171,7 +173,6 @@ CONFIG_SCSI_CONSTANTS=y
 #
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
-CONFIG_SUN3_SCSI=y
 
 #
 # Multi-device support (RAID and LVM)
@@ -487,7 +488,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 704e42344cba19d47bb1e2a6752f6b2d4568b460..997143b7928adf71e6d3e4fc5e3559bdc8dd0045 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:40 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:35:06 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index 5b2296ecba8207db90c7ac996212763f1c3056af..7d935e48a9a88f8fc5d322bcebaf8b44cf837f0d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:05:31 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:17 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -33,6 +33,8 @@ CONFIG_KOBJECT_UEVENT=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -355,7 +357,6 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
index fc4615b6d3a960ecc055c43a0589741e9128d714..e729bd280623d4f6ac7fe4790fcbcfd61cf4f709 100644 (file)
@@ -534,6 +534,11 @@ endchoice
 
 endmenu
 
+config ISA_DMA_API
+       bool
+       depends on !M5272
+       default y
+
 menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
 
 config PCI
index 2b6c9d32b7a6267754ab11b202317755a825a0b5..c4a33f265dc07e53577350d5366b3a936c8bc665 100644 (file)
@@ -45,11 +45,13 @@ asmlinkage void ret_from_fork(void);
  */
 void default_idle(void)
 {
-       while(1) {
-               if (need_resched())
-                       __asm__("stop #0x2000" : : : "cc");
-               schedule();
+       local_irq_disable();
+       while (!need_resched()) {
+               /* This stop will re-enable interrupts */
+               __asm__("stop #0x2000" : : : "cc");
+               local_irq_disable();
        }
+       local_irq_enable();
 }
 
 void (*idle)(void) = default_idle;
@@ -63,7 +65,12 @@ void (*idle)(void) = default_idle;
 void cpu_idle(void)
 {
        /* endless idle loop with no priority at all */
-       idle();
+       while (1) {
+               idle();
+               preempt_enable_no_resched();
+               schedule();
+               preempt_disable();
+       }
 }
 
 void machine_restart(char * __unused)
index 5e666aad88152e0287dd4b628f92e2d5c6e87c91..ab9944693f1f38c40852d7dafa45e75b040e907a 100644 (file)
@@ -1656,3 +1656,7 @@ config GENERIC_HARDIRQS
 config GENERIC_IRQ_PROBE
        bool
        default y
+
+config ISA_DMA_API
+       bool
+       default y
index a2f899c2f4d495cd224b1e0966b3a201be987d87..92e70ca3bff9d60bb6bf51a660f75b09496d089c 100644 (file)
@@ -301,25 +301,38 @@ out:
        return ret;
 }
 
+static inline int audit_arch(void)
+{
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#ifdef CONFIG_MIPS64
+       if (!(current->thread.mflags & MF_32BIT_REGS))
+               return AUDIT_ARCH_MIPSEL64;
+#endif /* MIPS64 */
+       return AUDIT_ARCH_MIPSEL;
+
+#else /* big endian... */
+#ifdef CONFIG_MIPS64
+       if (!(current->thread.mflags & MF_32BIT_REGS))
+               return AUDIT_ARCH_MIPS64;
+#endif /* MIPS64 */
+       return AUDIT_ARCH_MIPS;
+
+#endif /* endian */
+}
+
 /*
  * Notification of system call entry/exit
  * - triggered by current->work.syscall_trace
  */
 asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
 {
-       if (unlikely(current->audit_context)) {
-               if (!entryexit)
-                       audit_syscall_entry(current, regs->regs[2],
-                                           regs->regs[4], regs->regs[5],
-                                           regs->regs[6], regs->regs[7]);
-               else
-                       audit_syscall_exit(current, regs->regs[2]);
-       }
+       if (unlikely(current->audit_context) && entryexit)
+               audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
 
        if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               return;
+               goto out;
        if (!(current->ptrace & PT_PTRACED))
-               return;
+               goto out;
 
        /* The 0x80 provides a way for the tracing parent to distinguish
           between a syscall stop and SIGTRAP delivery */
@@ -335,4 +348,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
                send_sig(current->exit_code, current, 1);
                current->exit_code = 0;
        }
+ out:
+       if (unlikely(current->audit_context) && !entryexit)
+               audit_syscall_entry(current, audit_arch(), regs->regs[2],
+                                   regs->regs[4], regs->regs[5],
+                                   regs->regs[6], regs->regs[7]);
 }
index c5f1043de9384c2f495705d0ff9c43fd670b8066..53166f3598b25fdd82cde85c1963fefa0e22c742 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  pmu.c, Power Management Unit routines for NEC VR4100 series.
  *
- *  Copyright (C) 2003-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  Copyright (C) 2003-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.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
@@ -17,7 +17,9 @@
  *  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/errno.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/types.h>
 #include <asm/reboot.h>
 #include <asm/system.h>
 
-#define PMUCNT2REG     KSEG1ADDR(0x0f0000c6)
+#define PMU_TYPE1_BASE 0x0b0000a0UL
+#define PMU_TYPE1_SIZE 0x0eUL
+
+#define PMU_TYPE2_BASE 0x0f0000c0UL
+#define PMU_TYPE2_SIZE 0x10UL
+
+#define PMUCNT2REG     0x06
  #define SOFTRST       0x0010
 
+static void __iomem *pmu_base;
+
+#define pmu_read(offset)               readw(pmu_base + (offset))
+#define pmu_write(offset, value)       writew((value), pmu_base + (offset))
+
 static inline void software_reset(void)
 {
-       uint16_t val;
+       uint16_t pmucnt2;
 
        switch (current_cpu_data.cputype) {
        case CPU_VR4122:
        case CPU_VR4131:
        case CPU_VR4133:
-               val = readw(PMUCNT2REG);
-               val |= SOFTRST;
-               writew(val, PMUCNT2REG);
+               pmucnt2 = pmu_read(PMUCNT2REG);
+               pmucnt2 |= SOFTRST;
+               pmu_write(PMUCNT2REG, pmucnt2);
                break;
        default:
                break;
@@ -71,6 +84,34 @@ static void vr41xx_power_off(void)
 
 static int __init vr41xx_pmu_init(void)
 {
+       unsigned long start, size;
+
+       switch (current_cpu_data.cputype) {
+       case CPU_VR4111:
+       case CPU_VR4121:
+               start = PMU_TYPE1_BASE;
+               size = PMU_TYPE1_SIZE;
+               break;
+       case CPU_VR4122:
+       case CPU_VR4131:
+       case CPU_VR4133:
+               start = PMU_TYPE2_BASE;
+               size = PMU_TYPE2_SIZE;
+               break;
+       default:
+               printk("Unexpected CPU of NEC VR4100 series\n");
+               return -ENODEV;
+       }
+
+       if (request_mem_region(start, size, "PMU") == NULL)
+               return -EBUSY;
+
+       pmu_base = ioremap(start, size);
+       if (pmu_base == NULL) {
+               release_mem_region(start, size);
+               return -EBUSY;
+       }
+
        _machine_restart = vr41xx_restart;
        _machine_halt = vr41xx_halt;
        _machine_power_off = vr41xx_power_off;
@@ -78,4 +119,4 @@ static int __init vr41xx_pmu_init(void)
        return 0;
 }
 
-early_initcall(vr41xx_pmu_init);
+core_initcall(vr41xx_pmu_init);
index 5b5cd00d98ca11650140e79625dd4626cf5e77cc..e7e7c56fc212bd3a5099ca06b75c8f0867101db3 100644 (file)
@@ -45,6 +45,10 @@ config GENERIC_IRQ_PROBE
 config PM
        bool
 
+config ISA_DMA_API
+       bool
+       default y
+
 source "init/Kconfig"
 
 
index c3d941345e3dc427f07b1613713618e66424b00c..6e6377a69d5bc58c16de9f12013b377b3af7d17e 100644 (file)
@@ -43,6 +43,10 @@ config GENERIC_NVRAM
        bool
        default y
 
+config SCHED_NO_NO_OMIT_FRAME_POINTER
+       bool
+       default y
+
 source "init/Kconfig"
 
 menu "Processor"
@@ -73,9 +77,11 @@ config 44x
        bool "44x"
 
 config POWER3
+       select PPC_FPU
        bool "POWER3"
 
 config POWER4
+       select PPC_FPU
        bool "POWER4 and 970 (G5)"
 
 config 8xx
@@ -1079,6 +1085,10 @@ source kernel/power/Kconfig
 
 endmenu
 
+config ISA_DMA_API
+       bool
+       default y
+
 menu "Bus options"
 
 config ISA
@@ -1133,12 +1143,12 @@ config PCI_QSPAN
 
 config PCI_8260
        bool
-       depends on PCI && 8260 && !8272
+       depends on PCI && 8260
        default y
 
 config 8260_PCI9
        bool "  Enable workaround for MPC826x erratum PCI 9"
-       depends on PCI_8260
+       depends on PCI_8260 && !ADS8272
        default y
 
 choice
index f850fb0fb5118be47d976291ee028697fbdeb688..c9ac5f5fa9e483d205172b4835c7a361ade172a1 100644 (file)
@@ -22,7 +22,8 @@ targets += uImage
 $(obj)/uImage: $(obj)/vmlinux.gz
        $(Q)rm -f $@
        $(call if_changed,uimage)
-       @echo '  Image: $@' $(if $(wildcard $@),'is ready','not made')
+       @echo -n '  Image: $@ '
+       @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
 
 # Files generated that shall be removed upon make clean
 clean-files    := sImage vmapus vmlinux* miboot* zImage* uImage
index 728bd9e1a8fabf3982d5bc52b0147cd5637e9219..15abebf46b96f8344c634831099794f4e429305e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc1
-# Thu Jan 20 01:25:35 2005
+# Linux kernel version: 2.6.12-rc4
+# Tue May 17 11:56:01 2005
 #
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 
 #
 # Code maturity level options
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -29,12 +31,14 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -62,10 +67,12 @@ CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_E500=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_MATH_EMULATION=y
 # CONFIG_CPU_FREQ is not set
 CONFIG_PPC_GEN550=y
+# CONFIG_PM is not set
 CONFIG_85xx=y
 CONFIG_PPC_INDIRECT_PCI_BE=y
 
@@ -76,6 +83,7 @@ CONFIG_PPC_INDIRECT_PCI_BE=y
 CONFIG_MPC8555_CDS=y
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_STX_GP3 is not set
 CONFIG_MPC8555=y
 CONFIG_85xx_PCI2=y
 
@@ -90,6 +98,7 @@ CONFIG_CPM2=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
 
 #
 # Bus options
@@ -104,10 +113,6 @@ CONFIG_PCI_NAMES=y
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # Advanced setup
 #
@@ -180,7 +185,59 @@ CONFIG_IOSCHED_CFQ=y
 #
 # ATA/ATAPI/MFM/RLL support
 #
-# CONFIG_IDE is not set
+CONFIG_IDE=y
+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=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 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 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_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX 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_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
@@ -220,7 +277,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -369,14 +425,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
 #
 # Input Device Drivers
 #
@@ -386,6 +434,13 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
 #
 # Character devices
 #
@@ -406,6 +461,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_CPM is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -433,6 +489,11 @@ CONFIG_GEN_RTC=y
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
 #
 # I2C support
 #
@@ -456,11 +517,11 @@ CONFIG_I2C_CHARDEV=y
 # 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_ISA is not set
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
@@ -483,7 +544,9 @@ CONFIG_I2C_MPC=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 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
@@ -494,9 +557,11 @@ CONFIG_I2C_MPC=y
 # 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_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -506,10 +571,12 @@ CONFIG_I2C_MPC=y
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -538,7 +605,6 @@ CONFIG_I2C_MPC=y
 # Graphics support
 #
 # CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -548,13 +614,9 @@ CONFIG_I2C_MPC=y
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
 
 #
 # USB Gadget Support
@@ -585,6 +647,10 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -646,7 +712,6 @@ CONFIG_NFS_FS=y
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -698,7 +763,9 @@ CONFIG_CRC32=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_KGDB_CONSOLE is not set
 # CONFIG_SERIAL_TEXT_DEBUG is not set
 
index 8aa5e8c69009b43c89415b3ec643ad808ea41596..d44b7dc5390a0d64e7f58e3b71d70969de57c922 100644 (file)
@@ -838,6 +838,17 @@ struct cpu_spec    cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
        },
+       {       /* 405EP */
+               .pvr_mask               = 0xffff0000,
+               .pvr_value              = 0x51210000,
+               .cpu_name               = "405EP",
+               .cpu_features           = CPU_FTR_SPLIT_ID_CACHE |
+                       CPU_FTR_USE_TB,
+               .cpu_user_features      = PPC_FEATURE_32 |
+                       PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 32,
+       },
 
 #endif /* CONFIG_40x */
 #ifdef CONFIG_44x
index 9b6a8e5136570537adca7dc8ddf244a8fac19cfd..6c7ae6052464f3d28f7cc754487e8aaa6fba1361 100644 (file)
@@ -330,8 +330,9 @@ interrupt_base:
        /* If we are faulting a kernel address, we have to use the
         * kernel page tables.
         */
-       andis.  r11, r10, 0x8000
-       beq     3f
+       lis     r11, TASK_SIZE@h
+       cmplw   r10, r11
+       blt+    3f
        lis     r11, swapper_pg_dir@h
        ori     r11, r11, swapper_pg_dir@l
 
@@ -464,8 +465,9 @@ interrupt_base:
        /* If we are faulting a kernel address, we have to use the
         * kernel page tables.
         */
-       andis.  r11, r10, 0x8000
-       beq     3f
+       lis     r11, TASK_SIZE@h
+       cmplw   r10, r11
+       blt+    3f
        lis     r11, swapper_pg_dir@h
        ori     r11, r11, swapper_pg_dir@l
 
@@ -533,8 +535,9 @@ interrupt_base:
        /* If we are faulting a kernel address, we have to use the
         * kernel page tables.
         */
-       andis.  r11, r10, 0x8000
-       beq     3f
+       lis     r11, TASK_SIZE@h
+       cmplw   r10, r11
+       blt+    3f
        lis     r11, swapper_pg_dir@h
        ori     r11, r11, swapper_pg_dir@l
 
index f22ddce36135fddce922d21e2b033d642f5fe946..ce36e88ba6277ea68631ddd0fc8fb13623e94fe6 100644 (file)
@@ -232,7 +232,8 @@ skpinv:     addi    r6,r6,1                         /* Increment */
        tlbwe
 
 /* 7. Jump to KERNELBASE mapping */
-       li      r7,0
+       lis     r7,MSR_KERNEL@h
+       ori     r7,r7,MSR_KERNEL@l
        bl      1f                      /* Find our address */
 1:     mflr    r9
        rlwimi  r6,r9,0,20,31
@@ -293,6 +294,18 @@ skpinv:    addi    r6,r6,1                         /* Increment */
        mtspr   SPRN_HID0, r2
 #endif
 
+#if !defined(CONFIG_BDI_SWITCH)
+       /*
+        * The Abatron BDI JTAG debugger does not tolerate others
+        * mucking with the debug registers.
+        */
+       lis     r2,DBCR0_IDM@h
+       mtspr   SPRN_DBCR0,r2
+       /* clear any residual debug events */
+       li      r2,-1
+       mtspr   SPRN_DBSR,r2
+#endif
+
        /*
         * This is where the main kernel code starts.
         */
index e4f1615ec13f42eb034426443d881e2db0534d47..7329ef177a18c36c4f068d2a09dad48d34fce92e 100644 (file)
@@ -619,7 +619,7 @@ _GLOBAL(flush_instruction_cache)
 _GLOBAL(flush_icache_range)
 BEGIN_FTR_SECTION
        blr                             /* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
        li      r5,L1_CACHE_LINE_SIZE-1
        andc    r3,r3,r5
        subf    r4,r3,r4
@@ -736,7 +736,7 @@ _GLOBAL(flush_dcache_all)
 _GLOBAL(__flush_dcache_icache)
 BEGIN_FTR_SECTION
        blr                                     /* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
        rlwinm  r3,r3,0,0,19                    /* Get page base address */
        li      r4,4096/L1_CACHE_LINE_SIZE      /* Number of lines in a page */
        mtctr   r4
@@ -764,7 +764,7 @@ END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
 _GLOBAL(__flush_dcache_icache_phys)
 BEGIN_FTR_SECTION
        blr                                     /* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
        mfmsr   r10
        rlwinm  r0,r10,0,28,26                  /* clear DR */
        mtmsr   r0
index e97ce635b99e6d84640457c775c77d7eb49f4efb..5c20266e3b1fd80c45f88af83d0a3b3b475d5bd4 100644 (file)
@@ -221,27 +221,26 @@ int show_cpuinfo(struct seq_file *m, void *v)
                        return err;
        }
 
-       switch (PVR_VER(pvr)) {
-       case 0x0020:    /* 403 family */
-               maj = PVR_MAJ(pvr) + 1;
-               min = PVR_MIN(pvr);
-               break;
-       case 0x1008:    /* 740P/750P ?? */
-               maj = ((pvr >> 8) & 0xFF) - 1;
-               min = pvr & 0xFF;
-               break;
-       case 0x8083:    /* e300 */
-               maj = PVR_MAJ(pvr);
-               min = PVR_MIN(pvr);
-               break;
-       case 0x8020:    /* e500 */
+       /* If we are a Freescale core do a simple check so
+        * we dont have to keep adding cases in the future */
+       if ((PVR_VER(pvr) & 0x8000) == 0x8000) {
                maj = PVR_MAJ(pvr);
                min = PVR_MIN(pvr);
-               break;
-       default:
-               maj = (pvr >> 8) & 0xFF;
-               min = pvr & 0xFF;
-               break;
+       } else {
+               switch (PVR_VER(pvr)) {
+                       case 0x0020:    /* 403 family */
+                               maj = PVR_MAJ(pvr) + 1;
+                               min = PVR_MIN(pvr);
+                               break;
+                       case 0x1008:    /* 740P/750P ?? */
+                               maj = ((pvr >> 8) & 0xFF) - 1;
+                               min = pvr & 0xFF;
+                               break;
+                       default:
+                               maj = (pvr >> 8) & 0xFF;
+                               min = pvr & 0xFF;
+                               break;
+               }
        }
 
        seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
@@ -500,7 +499,7 @@ static int __init set_preferred_console(void)
 {
        struct device_node *prom_stdout;
        char *name;
-       int offset;
+       int offset = 0;
 
        if (of_stdout_device == NULL)
                return -ENODEV;
@@ -754,6 +753,8 @@ void __init setup_arch(char **cmdline_p)
        strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
        *cmdline_p = cmd_line;
 
+       parse_early_param();
+
        /* set up the bootmem stuff with available memory */
        do_init_bootmem();
        if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
index f8e7e324a17396fc81e64a3afbcc2cb77eaa6702..c65731e8bc657cb2edbcec90b8050ef813846803 100644 (file)
@@ -408,12 +408,7 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
 
        /* Early out if we are an invalid form of lswx */
        if ((instword & INST_STRING_MASK) == INST_LSWX)
-               if ((rA >= rT) || (NB_RB >= rT) || (rT == rA) || (rT == NB_RB))
-                       return -EINVAL;
-
-       /* Early out if we are an invalid form of lswi */
-       if ((instword & INST_STRING_MASK) == INST_LSWI)
-               if ((rA >= rT) || (rT == rA))
+               if ((rT == rA) || (rT == NB_RB))
                        return -EINVAL;
 
        EA = (rA == 0) ? 0 : regs->gpr[rA];
index 0c0e714b84de74febf1f4dcb59eb1a859902deac..9353584fb7103c77cc866b417eecb12fa729c968 100644 (file)
@@ -145,6 +145,7 @@ SECTIONS
   __init_end = .;
 
   . = ALIGN(4096);
+  _sextratext = .;
   __pmac_begin = .;
   .pmac.text : { *(.pmac.text) }
   .pmac.data : { *(.pmac.data) }
@@ -171,6 +172,7 @@ SECTIONS
   .openfirmware.data : { *(.openfirmware.data) }
   . = ALIGN(4096);
   __openfirmware_end = .;
+  _eextratext = .;
 
   __bss_start = .;
   .bss       :
index 8d08a2eb225e8608310c205033a34db857eb5ebf..36c9b97fd92abf9c6728f425e73d9d88fa0d8a84 100644 (file)
@@ -446,6 +446,7 @@ _GLOBAL(__copy_tofrom_user)
 #ifdef CONFIG_8xx
        /* Don't use prefetch on 8xx */
        mtctr   r0
+       li      r0,0
 53:    COPY_16_BYTES_WITHEX(0)
        bdnz    53b
 
@@ -564,7 +565,9 @@ _GLOBAL(__copy_tofrom_user)
 /* or write fault in cacheline loop */
 105:   li      r9,1
 92:    li      r3,LG_CACHELINE_BYTES
-       b       99f
+       mfctr   r8
+       add     r0,r0,r8
+       b       106f
 /* read fault in final word loop */
 108:   li      r9,0
        b       93f
@@ -585,7 +588,7 @@ _GLOBAL(__copy_tofrom_user)
  * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
  */
 99:    mfctr   r0
-       slw     r3,r0,r3
+106:   slw     r3,r0,r3
        add.    r3,r3,r5
        beq     120f                    /* shouldn't happen */
        cmpwi   0,r9,0
index be02a7fec2b73ceb42675c54e747eafea7ac55c2..363c157e3617e8f375b0bbae6f31fd499f59cbff 100644 (file)
@@ -179,6 +179,7 @@ void free_initmem(void)
        if (!have_of)
                FREESEC(openfirmware);
        printk("\n");
+       ppc_md.progress = NULL;
 #undef FREESEC
 }
 
index b3b0f51979d2b2c6ef6b316c392567e8d4a67765..e6348b5a1ddc6a56e81908fbd8a8e8434f471e44 100644 (file)
@@ -127,7 +127,6 @@ mpc834x_sys_map_io(void)
 {
        /* we steal the lowest ioremap addr for virt space */
        io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO);
-       io_block_mapping(BCSR_VIRT_ADDR, BCSR_PHYS_ADDR, BCSR_SIZE, _PAGE_IO);
 }
 
 int
index f4d055ae19c14b6eecf94e6be35bd05d6afc3f19..a2f6e49d71512946ca5e89e2b7d7ca80fec0f8de 100644 (file)
 #define VIRT_IMMRBAR           ((uint)0xfe000000)
 
 #define BCSR_PHYS_ADDR         ((uint)0xf8000000)
-#define BCSR_VIRT_ADDR         ((uint)0xfe100000)
 #define BCSR_SIZE              ((uint)(32 * 1024))
 
+#define BCSR_MISC_REG2_OFF     0x07
+#define BCSR_MISC_REG2_PORESET 0x01
+
+#define BCSR_MISC_REG3_OFF     0x08
+#define BCSR_MISC_REG3_CNFLOCK 0x80
+
 #ifdef CONFIG_PCI
 /* PCI interrupt controller */
 #define PIRQA        MPC83xx_IRQ_IRQ4
index 4d857d6d633d757c7818356c24a12219f99c341d..583838ab02d8370a97d22640915a3fed84d1eaf6 100644 (file)
@@ -210,6 +210,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
        ppc_md.progress = gen550_progress;
 #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
+       ppc_md.early_serial_map = mpc85xx_early_serial_map;
+#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
 
        if (ppc_md.progress)
                ppc_md.progress("mpc8540ads_init(): exit", 0);
index 6c020d67ad704457a1341d2295907d5c52733928..e7cfa498568c25b03f891bd809a3342010c32f58 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/machdep.h>
 #include <asm/prom.h>
 #include <asm/open_pic.h>
+#include <asm/i8259.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
 #include <asm/mpc85xx.h>
@@ -181,6 +182,7 @@ void __init
 mpc85xx_cds_init_IRQ(void)
 {
        bd_t *binfo = (bd_t *) __res;
+       int i;
 
        /* Determine the Physical Address of the OpenPIC regs */
        phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
@@ -198,6 +200,15 @@ mpc85xx_cds_init_IRQ(void)
         */
        openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
 
+#ifdef CONFIG_PCI
+       openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
+
+       for (i = 0; i < NUM_8259_INTERRUPTS; i++)
+               irq_desc[i].handler = &i8259_pic;
+
+       i8259_init(0);
+#endif
+
 #ifdef CONFIG_CPM2
        /* Setup CPM2 PIC */
         cpm2_init_IRQ();
@@ -231,7 +242,7 @@ mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
                         * interrupt on slot */
                {
                        { 0, 1, 2, 3 }, /* 16 - PMC */
-                       { 3, 0, 0, 0 }, /* 17 P2P (Tsi320) */
+                       { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */
                        { 0, 1, 2, 3 }, /* 18 - Slot 1 */
                        { 1, 2, 3, 0 }, /* 19 - Slot 2 */
                        { 2, 3, 0, 1 }, /* 20 - Slot 3 */
@@ -280,13 +291,135 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
                        return PCIBIOS_DEVICE_NOT_FOUND;
 #endif
        /* We explicitly do not go past the Tundra 320 Bridge */
-       if (bus == 1)
+       if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
                return PCIBIOS_DEVICE_NOT_FOUND;
        if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
                return PCIBIOS_DEVICE_NOT_FOUND;
        else
                return PCIBIOS_SUCCESSFUL;
 }
+
+void __init
+mpc85xx_cds_enable_via(struct pci_controller *hose)
+{
+       u32 pci_class;
+       u16 vid, did;
+
+       early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
+       if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
+               return;
+
+       /* Configure P2P so that we can reach bus 1 */
+       early_write_config_byte(hose, 0, 0x88, PCI_PRIMARY_BUS, 0);
+       early_write_config_byte(hose, 0, 0x88, PCI_SECONDARY_BUS, 1);
+       early_write_config_byte(hose, 0, 0x88, PCI_SUBORDINATE_BUS, 0xff);
+
+       early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
+       early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
+
+       if ((vid != PCI_VENDOR_ID_VIA) ||
+                       (did != PCI_DEVICE_ID_VIA_82C686))
+               return;
+
+       /* Enable USB and IDE functions */
+       early_write_config_byte(hose, 1, 0x10, 0x48, 0x08);
+}
+
+void __init
+mpc85xx_cds_fixup_via(struct pci_controller *hose)
+{
+       u32 pci_class;
+       u16 vid, did;
+
+       early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
+       if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
+               return;
+
+       /*
+        * Force the backplane P2P bridge to have a window
+        * open from 0x00000000-0x00001fff in PCI I/O space.
+        * This allows legacy I/O (i8259, etc) on the VIA
+        * southbridge to be accessed.
+        */
+       early_write_config_byte(hose, 0, 0x88, PCI_IO_BASE, 0x00);
+       early_write_config_word(hose, 0, 0x88, PCI_IO_BASE_UPPER16, 0x0000);
+       early_write_config_byte(hose, 0, 0x88, PCI_IO_LIMIT, 0x10);
+       early_write_config_word(hose, 0, 0x88, PCI_IO_LIMIT_UPPER16, 0x0000);
+
+       early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
+       early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
+       if ((vid != PCI_VENDOR_ID_VIA) ||
+                       (did != PCI_DEVICE_ID_VIA_82C686))
+               return;
+
+       /*
+        * Since the P2P window was forced to cover the fixed
+        * legacy I/O addresses, it is necessary to manually
+        * place the base addresses for the IDE and USB functions
+        * within this window.
+        */
+       /* Function 1, IDE */
+       early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_0, 0x1ff8);
+       early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_1, 0x1ff4);
+       early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_2, 0x1fe8);
+       early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_3, 0x1fe4);
+       early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_4, 0x1fd0);
+
+       /* Function 2, USB ports 0-1 */
+       early_write_config_dword(hose, 1, 0x12, PCI_BASE_ADDRESS_4, 0x1fa0);
+
+       /* Function 3, USB ports 2-3 */
+       early_write_config_dword(hose, 1, 0x13, PCI_BASE_ADDRESS_4, 0x1f80);
+
+       /* Function 5, Power Management */
+       early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_0, 0x1e00);
+       early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_1, 0x1dfc);
+       early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_2, 0x1df8);
+
+       /* Function 6, AC97 Interface */
+       early_write_config_dword(hose, 1, 0x16, PCI_BASE_ADDRESS_0, 0x1c00);
+}
+
+void __init
+mpc85xx_cds_pcibios_fixup(void)
+{
+        struct pci_dev *dev = NULL;
+       u_char          c;
+
+        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+                                        PCI_DEVICE_ID_VIA_82C586_1, NULL))) {
+                /*
+                 * U-Boot does not set the enable bits
+                 * for the IDE device. Force them on here.
+                 */
+                pci_read_config_byte(dev, 0x40, &c);
+                c |= 0x03; /* IDE: Chip Enable Bits */
+                pci_write_config_byte(dev, 0x40, c);
+
+               /*
+                * Since only primary interface works, force the
+                * IDE function to standard primary IDE interrupt
+                * w/ 8259 offset
+                */
+                dev->irq = 14;
+                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+        }
+
+       /*
+        * Force legacy USB interrupt routing
+        */
+        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+                                        PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
+                dev->irq = 10;
+                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
+        }
+
+        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+                                        PCI_DEVICE_ID_VIA_82C586_2, dev))) {
+                dev->irq = 11;
+                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+        }
+}
 #endif /* CONFIG_PCI */
 
 TODC_ALLOC();
@@ -328,6 +461,9 @@ mpc85xx_cds_setup_arch(void)
        loops_per_jiffy = freq / HZ;
 
 #ifdef CONFIG_PCI
+       /* VIA IDE configuration */
+        ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
+
        /* setup PCI host bridges */
        mpc85xx_setup_hose();
 #endif
@@ -459,6 +595,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
        ppc_md.progress = gen550_progress;
 #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
+       ppc_md.early_serial_map = mpc85xx_early_serial_map;
+#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
 
        if (ppc_md.progress)
                ppc_md.progress("mpc85xx_cds_init(): exit", 0);
index 7627d77504bd07a8da615ccff57662ca44f4421e..12b292c6ae3225bb41eeea720de35a8770bdca0a 100644 (file)
@@ -77,4 +77,7 @@
 
 #define MPC85XX_PCI2_IO_SIZE         0x01000000
 
+#define NR_8259_INTS                16
+#define CPM_IRQ_OFFSET              NR_8259_INTS
+
 #endif /* __MACH_MPC85XX_CDS_H__ */
index 9ab05e590c3e0a60537052f7880fc5f8e4033aba..7b9e1543e17524e6301e4c45cd9d77b4a6b8967e 100644 (file)
@@ -221,6 +221,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
        ppc_md.progress = gen550_progress;
 #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
+       ppc_md.early_serial_map = sbc8560_early_serial_map;
+#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
 
        if (ppc_md.progress)
                ppc_md.progress("sbc8560_init(): exit", 0);
index f7fb2786cd505a7701fe2322c73b169af4ff2133..5fdd4f607a40f23b25e441a9b9140c22364fa323 100644 (file)
@@ -83,16 +83,13 @@ static u32 frequency_gpio;
 static u32 slew_done_gpio;
 static int no_schedule;
 static int has_cpu_l2lve;
-
-
-#define PMAC_CPU_LOW_SPEED     1
-#define PMAC_CPU_HIGH_SPEED    0
+static int is_pmu_based;
 
 /* There are only two frequency states for each processor. Values
  * are in kHz for the time being.
  */
-#define CPUFREQ_HIGH                  PMAC_CPU_HIGH_SPEED
-#define CPUFREQ_LOW                   PMAC_CPU_LOW_SPEED
+#define CPUFREQ_HIGH                  0
+#define CPUFREQ_LOW                   1
 
 static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
        {CPUFREQ_HIGH,          0},
@@ -100,6 +97,11 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
        {0,                     CPUFREQ_TABLE_END},
 };
 
+static struct freq_attr* pmac_cpu_freqs_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
+       NULL,
+};
+
 static inline void local_delay(unsigned long ms)
 {
        if (no_schedule)
@@ -269,6 +271,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
 #ifdef DEBUG_FREQ
        printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
 #endif
+       pmu_suspend();
+
        /* Disable all interrupt sources on openpic */
        pic_prio = openpic_get_priority();
        openpic_set_priority(0xf);
@@ -343,6 +347,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
        debug_calc_bogomips();
 #endif
 
+       pmu_resume();
+
        preempt_enable();
 
        return 0;
@@ -355,7 +361,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
        static unsigned long prev_l3cr;
 
        freqs.old = cur_freq;
-       freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
+       freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
        freqs.cpu = smp_processor_id();
 
        if (freqs.old == freqs.new)
@@ -363,7 +369,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 
        if (notify)
                cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-       if (speed_mode == PMAC_CPU_LOW_SPEED &&
+       if (speed_mode == CPUFREQ_LOW &&
            cpu_has_feature(CPU_FTR_L3CR)) {
                l3cr = _get_L3CR();
                if (l3cr & L3CR_L3E) {
@@ -371,8 +377,8 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
                        _set_L3CR(0);
                }
        }
-       set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED);
-       if (speed_mode == PMAC_CPU_HIGH_SPEED &&
+       set_speed_proc(speed_mode == CPUFREQ_LOW);
+       if (speed_mode == CPUFREQ_HIGH &&
            cpu_has_feature(CPU_FTR_L3CR)) {
                l3cr = _get_L3CR();
                if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
@@ -380,7 +386,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
        }
        if (notify)
                cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-       cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
+       cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
 
        return 0;
 }
@@ -423,7 +429,8 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
        policy->cpuinfo.transition_latency      = CPUFREQ_ETERNAL;
        policy->cur = cur_freq;
 
-       return cpufreq_frequency_table_cpuinfo(policy, &pmac_cpu_freqs[0]);
+       cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
+       return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
 }
 
 static u32 __pmac read_gpio(struct device_node *np)
@@ -456,8 +463,8 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state)
         */
        no_schedule = 1;
        sleep_freq = cur_freq;
-       if (cur_freq == low_freq)
-               do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0);
+       if (cur_freq == low_freq && !is_pmu_based)
+               do_set_cpu_speed(CPUFREQ_HIGH, 0);
        return 0;
 }
 
@@ -473,8 +480,8 @@ static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy)
         * is that we force a switch to whatever it was, which is
         * probably high speed due to our suspend() routine
         */
-       do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED
-                        : PMAC_CPU_HIGH_SPEED, 0);
+       do_set_cpu_speed(sleep_freq == low_freq ?
+                        CPUFREQ_LOW : CPUFREQ_HIGH, 0);
 
        no_schedule = 0;
        return 0;
@@ -488,6 +495,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = {
        .suspend        = pmac_cpufreq_suspend,
        .resume         = pmac_cpufreq_resume,
        .flags          = CPUFREQ_PM_NO_WARN,
+       .attr           = pmac_cpu_freqs_attr,
        .name           = "powermac",
        .owner          = THIS_MODULE,
 };
@@ -580,6 +588,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
                return 1;
        hi_freq = (*value) / 1000;
        set_speed_proc = pmu_set_cpu_speed;
+       is_pmu_based = 1;
 
        return 0;
 }
@@ -684,6 +693,7 @@ static int __init pmac_cpufreq_setup(void)
                hi_freq = cur_freq;
                low_freq = 400000;
                set_speed_proc = pmu_set_cpu_speed;
+               is_pmu_based = 1;
        }
        /* Else check for TiPb 400 & 500 */
        else if (machine_is_compatible("PowerBook3,2")) {
@@ -695,6 +705,7 @@ static int __init pmac_cpufreq_setup(void)
                hi_freq = cur_freq;
                low_freq = 300000;
                set_speed_proc = pmu_set_cpu_speed;
+               is_pmu_based = 1;
        }
        /* Else check for 750FX */
        else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
index cf5e5dd06d6300d7733b20f4e5b21c31a1bdda48..067d9a5aebc108f7301913e74d3d218161c23ea7 100644 (file)
 /* PCI interrupt controller */
 #define PCI_INT_STAT_REG       0xF8200000
 #define PCI_INT_MASK_REG       0xF8200004
-#define PIRQA                  (NR_SIU_INTS + 0)
-#define PIRQB                  (NR_SIU_INTS + 1)
-#define PIRQC                  (NR_SIU_INTS + 2)
-#define PIRQD                  (NR_SIU_INTS + 3)
+#define PIRQA                  (NR_CPM_INTS + 0)
+#define PIRQB                  (NR_CPM_INTS + 1)
+#define PIRQC                  (NR_CPM_INTS + 2)
+#define PIRQD                  (NR_CPM_INTS + 3)
 
 /*
  * PCI memory map definitions for MPC8266ADS-PCI.
  *     0x00000000-0x1FFFFFFF   0x00000000-0x1FFFFFFF   MPC8266 local memory
  */
 
-/* window for a PCI master to access MPC8266 memory */
-#define PCI_SLV_MEM_LOCAL      0x00000000      /* Local base */
-#define PCI_SLV_MEM_BUS                0x00000000      /* PCI base */
+/* All the other PCI memory map definitions reside at syslib/m82xx_pci.h
+   Here we should redefine what is unique for this board */
+#define M82xx_PCI_SLAVE_MEM_LOCAL      0x00000000      /* Local base */
+#define M82xx_PCI_SLAVE_MEM_BUS                0x00000000      /* PCI base */
+#define M82xx_PCI_SLAVE_MEM_SIZE       0x10000000      /* 256 Mb */
 
-/* window for the processor to access PCI memory with prefetching */
-#define PCI_MSTR_MEM_LOCAL     0x80000000      /* Local base */
-#define PCI_MSTR_MEM_BUS       0x80000000      /* PCI base   */
-#define PCI_MSTR_MEM_SIZE      0x20000000      /* 512MB */
+#define M82xx_PCI_SLAVE_SEC_WND_SIZE   ~(0x40000000 - 1U)      /* 2 x 512Mb  */
+#define M82xx_PCI_SLAVE_SEC_WND_BASE   0x80000000              /* PCI Memory base */
 
-/* window for the processor to access PCI memory without prefetching */
-#define PCI_MSTR_MEMIO_LOCAL   0xA0000000      /* Local base */
-#define PCI_MSTR_MEMIO_BUS     0xA0000000      /* PCI base   */
-#define PCI_MSTR_MEMIO_SIZE    0x20000000      /* 512MB */
+#if defined(CONFIG_ADS8272)
+#define PCI_INT_TO_SIU         SIU_INT_IRQ2
+#elif defined(CONFIG_PQ2FADS)
+#define PCI_INT_TO_SIU         SIU_INT_IRQ6
+#else
+#warning PCI Bridge will be without interrupts support
+#endif
 
-/* window for the processor to access PCI I/O */
-#define PCI_MSTR_IO_LOCAL      0xF4000000      /* Local base */
-#define PCI_MSTR_IO_BUS         0x00000000     /* PCI base   */
-#define PCI_MSTR_IO_SIZE        0x04000000     /* 64MB */
-
-#define _IO_BASE               PCI_MSTR_IO_LOCAL
-#define _ISA_MEM_BASE          PCI_MSTR_MEMIO_LOCAL
-#define PCI_DRAM_OFFSET                PCI_SLV_MEM_BUS
 #endif /* CONFIG_PCI */
 
 #endif /* __MACH_ADS8260_DEFS */
index dd418ea3426c70a4ed065986e464967fce8122fb..96acf85800d47a493ca924ded205dcfb70af8779 100644 (file)
@@ -81,7 +81,7 @@ obj-$(CONFIG_SBC82xx)         += todc_time.o
 obj-$(CONFIG_SPRUCE)           += cpc700_pic.o indirect_pci.o pci_auto.o \
                                   todc_time.o
 obj-$(CONFIG_8260)             += m8260_setup.o
-obj-$(CONFIG_PCI_8260)         += m8260_pci.o indirect_pci.o
+obj-$(CONFIG_PCI_8260)         += m82xx_pci.o indirect_pci.o pci_auto.o
 obj-$(CONFIG_8260_PCI9)                += m8260_pci_erratum9.o
 obj-$(CONFIG_CPM2)             += cpm2_common.o cpm2_pic.o
 ifeq ($(CONFIG_PPC_GEN550),y)
@@ -97,7 +97,7 @@ obj-$(CONFIG_MPC10X_OPENPIC)  += open_pic.o
 obj-$(CONFIG_40x)              += dcr.o
 obj-$(CONFIG_BOOKE)            += dcr.o
 obj-$(CONFIG_85xx)             += open_pic.o ppc85xx_common.o ppc85xx_setup.o \
-                                       ppc_sys.o mpc85xx_sys.o \
+                                       ppc_sys.o i8259.o mpc85xx_sys.o \
                                        mpc85xx_devices.o
 ifeq ($(CONFIG_85xx),y)
 obj-$(CONFIG_PCI)              += indirect_pci.o pci_auto.o
index acb2cde3171f8d141b7f38f95e9def9a62210851..580ed658e87253b51873b624ed5b8f0d228f1ba5 100644 (file)
@@ -479,7 +479,7 @@ void __init ipic_init(phys_addr_t phys_addr,
        temp = 0;
        for (i = 0 ; i < senses_count ; i++) {
                if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
-                       temp |= 1 << (16 - i);
+                       temp |= 1 << (15 - i);
                        if (i != 0)
                                irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
                        else
diff --git a/arch/ppc/syslib/m8260_pci.c b/arch/ppc/syslib/m8260_pci.c
deleted file mode 100644 (file)
index 057cc3f..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2004 Red Hat, Inc.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You 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/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/immap_cpm2.h>
-#include <asm/mpc8260.h>
-
-#include "m8260_pci.h"
-
-
-/* PCI bus configuration registers.
- */
-
-static void __init m8260_setup_pci(struct pci_controller *hose)
-{
-       volatile cpm2_map_t *immap = cpm2_immr;
-       unsigned long pocmr;
-       u16 tempShort;
-
-#ifndef CONFIG_ATC     /* already done in U-Boot */
-       /* 
-        * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), 
-        * and local bus for PCI (SIUMCR [LBPC]).
-        */
-       immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000;
-#endif
-
-       /* Make PCI lowest priority */
-       /* Each 4 bits is a device bus request  and the MS 4bits 
-          is highest priority */
-       /* Bus               4bit value 
-          ---               ----------
-          CPM high          0b0000
-          CPM middle        0b0001
-          CPM low           0b0010
-          PCI reguest       0b0011
-          Reserved          0b0100
-          Reserved          0b0101
-          Internal Core     0b0110
-          External Master 1 0b0111
-          External Master 2 0b1000
-          External Master 3 0b1001
-          The rest are reserved */
-       immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
-
-       /* Park bus on core while modifying PCI Bus accesses */
-       immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6;
-
-       /* 
-        * Set up master window that allows the CPU to access PCI space. This 
-        * window is set up using the first SIU PCIBR registers.
-        */
-       immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK;
-       immap->im_memctl.memc_pcibr0 =  MPC826x_PCI_BASE | PCIBR_ENABLE;
-
-       /* Disable machine check on no response or target abort */
-       immap->im_pci.pci_emr = cpu_to_le32(0x1fe7);
-       /* Release PCI RST (by default the PCI RST signal is held low)  */
-       immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
-
-       /* give it some time */
-       mdelay(1);
-
-       /* 
-        * Set up master window that allows the CPU to access PCI Memory (prefetch) 
-        * space. This window is set up using the first set of Outbound ATU registers.
-        */
-       immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12);
-       immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12);
-       pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff;
-       immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN);
-
-       /* 
-        * Set up master window that allows the CPU to access PCI Memory (non-prefetch) 
-        * space. This window is set up using the second set of Outbound ATU registers.
-        */
-       immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12);
-       immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12);
-       pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff;
-       immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE);
-
-       /* 
-        * Set up master window that allows the CPU to access PCI IO space. This window
-        * is set up using the third set of Outbound ATU registers.
-        */
-       immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12);
-       immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12);
-       pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff;
-       immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO);
-
-       /* 
-        * Set up slave window that allows PCI masters to access MPC826x local memory. 
-        * This window is set up using the first set of Inbound ATU registers
-        */
-
-       immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12);
-       immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12);
-       pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff;
-       immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN);
-
-       /* See above for description - puts PCI request as highest priority */
-       immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
-
-       /* Park the bus on the PCI */
-       immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
-
-       /* Host mode - specify the bridge as a host-PCI bridge */
-       early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST);
-
-       /* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */
-       early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort);
-       early_write_config_word(hose, 0, 0, PCI_COMMAND,
-                               tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-}
-
-void __init m8260_find_bridges(void)
-{
-       extern int pci_assign_all_busses;
-       struct pci_controller * hose;
-
-       pci_assign_all_busses = 1;
-
-       hose = pcibios_alloc_controller();
-
-       if (!hose)
-               return;
-
-       ppc_md.pci_swizzle = common_swizzle;
-
-       hose->first_busno = 0;
-       hose->bus_offset = 0;
-       hose->last_busno = 0xff;
-
-       setup_m8260_indirect_pci(hose, 
-                                (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
-                                (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
-
-       m8260_setup_pci(hose);
-        hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET;
-
-        hose->io_base_virt = ioremap(MPC826x_PCI_IO_BASE,
-                                        MPC826x_PCI_IO_SIZE);
-        isa_io_base = (unsigned long) hose->io_base_virt;
-        /* setup resources */
-        pci_init_resource(&hose->mem_resources[0],
-                         MPC826x_PCI_LOWER_MEM,
-                         MPC826x_PCI_UPPER_MEM,
-                         IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
-
-        pci_init_resource(&hose->mem_resources[1],
-                         MPC826x_PCI_LOWER_MMIO,
-                         MPC826x_PCI_UPPER_MMIO,
-                         IORESOURCE_MEM, "PCI memory");
-
-        pci_init_resource(&hose->io_resource,
-                         MPC826x_PCI_LOWER_IO,
-                         MPC826x_PCI_UPPER_IO,
-                         IORESOURCE_IO, "PCI I/O");
-}
diff --git a/arch/ppc/syslib/m8260_pci.h b/arch/ppc/syslib/m8260_pci.h
deleted file mode 100644 (file)
index d135212..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-
-#ifndef _PPC_KERNEL_M8260_PCI_H
-#define _PPC_KERNEL_M8260_PCI_H
-
-#include <asm/m8260_pci.h>
-
-/*
- *   Local->PCI map (from CPU)                             controlled by
- *   MPC826x master window
- *
- *   0x80000000 - 0xBFFFFFFF    Total CPU2PCI space        PCIBR0
- *                       
- *   0x80000000 - 0x9FFFFFFF    PCI Mem with prefetch      (Outbound ATU #1)
- *   0xA0000000 - 0xAFFFFFFF    PCI Mem w/o  prefetch      (Outbound ATU #2)
- *   0xB0000000 - 0xB0FFFFFF    32-bit PCI IO              (Outbound ATU #3)
- *                      
- *   PCI->Local map (from PCI)
- *   MPC826x slave window                                  controlled by
- *
- *   0x00000000 - 0x07FFFFFF    MPC826x local memory       (Inbound ATU #1)
- */
-
-/* 
- * Slave window that allows PCI masters to access MPC826x local memory. 
- * This window is set up using the first set of Inbound ATU registers
- */
-
-#ifndef MPC826x_PCI_SLAVE_MEM_LOCAL
-#define MPC826x_PCI_SLAVE_MEM_LOCAL    (((struct bd_info *)__res)->bi_memstart)
-#define MPC826x_PCI_SLAVE_MEM_BUS      (((struct bd_info *)__res)->bi_memstart)
-#define MPC826x_PCI_SLAVE_MEM_SIZE     (((struct bd_info *)__res)->bi_memsize)
-#endif
-
-/* 
- * This is the window that allows the CPU to access PCI address space.
- * It will be setup with the SIU PCIBR0 register. All three PCI master
- * windows, which allow the CPU to access PCI prefetch, non prefetch,
- * and IO space (see below), must all fit within this window. 
- */
-#ifndef MPC826x_PCI_BASE
-#define MPC826x_PCI_BASE       0x80000000
-#define MPC826x_PCI_MASK       0xc0000000
-#endif
-
-#ifndef MPC826x_PCI_LOWER_MEM
-#define MPC826x_PCI_LOWER_MEM  0x80000000
-#define MPC826x_PCI_UPPER_MEM  0x9fffffff
-#define MPC826x_PCI_MEM_OFFSET 0x00000000
-#endif
-
-#ifndef MPC826x_PCI_LOWER_MMIO
-#define MPC826x_PCI_LOWER_MMIO  0xa0000000
-#define MPC826x_PCI_UPPER_MMIO  0xafffffff
-#define MPC826x_PCI_MMIO_OFFSET 0x00000000
-#endif
-
-#ifndef MPC826x_PCI_LOWER_IO
-#define MPC826x_PCI_LOWER_IO   0x00000000
-#define MPC826x_PCI_UPPER_IO   0x00ffffff
-#define MPC826x_PCI_IO_BASE    0xb0000000
-#define MPC826x_PCI_IO_SIZE    0x01000000
-#endif
-
-#ifndef _IO_BASE
-#define _IO_BASE isa_io_base
-#endif
-
-#ifdef CONFIG_8260_PCI9
-struct pci_controller;
-extern void setup_m8260_indirect_pci(struct pci_controller* hose,
-                                    u32 cfg_addr, u32 cfg_data);
-#else
-#define setup_m8260_indirect_pci setup_indirect_pci
-#endif
-
-#endif /* _PPC_KERNEL_M8260_PCI_H */
index 9c0582d639e051ccba4d213044045bf99211550c..1dc7e4e1d4914ed5d11f583b944de475092436d7 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/immap_cpm2.h>
 #include <asm/cpm2.h>
 
-#include "m8260_pci.h"
+#include "m82xx_pci.h"
 
 #ifdef CONFIG_8260_PCI9
 /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
@@ -248,11 +248,11 @@ EXPORT_SYMBOL(idma_pci9_read_le);
 
 static inline int is_pci_mem(unsigned long addr)
 {
-       if (addr >= MPC826x_PCI_LOWER_MMIO &&
-           addr <= MPC826x_PCI_UPPER_MMIO)
+       if (addr >= M82xx_PCI_LOWER_MMIO &&
+               addr <= M82xx_PCI_UPPER_MMIO)
                return 1;
-       if (addr >= MPC826x_PCI_LOWER_MEM &&
-           addr <= MPC826x_PCI_UPPER_MEM)
+       if (addr >= M82xx_PCI_LOWER_MEM &&
+               addr <= M82xx_PCI_UPPER_MEM)
                return 1;
        return 0;
 }
index 23ea3f694de2066ec5b324ebedb38b1c027415ce..fda75d79050c3e9201ce7033193645bd74609aec 100644 (file)
@@ -34,7 +34,8 @@
 unsigned char __res[sizeof(bd_t)];
 
 extern void cpm2_reset(void);
-extern void m8260_find_bridges(void);
+extern void pq2_find_bridges(void);
+extern void pq2pci_init_irq(void);
 extern void idma_pci9_init(void);
 
 /* Place-holder for board-specific init */
@@ -56,7 +57,7 @@ m8260_setup_arch(void)
        idma_pci9_init();
 #endif
 #ifdef CONFIG_PCI_8260
-       m8260_find_bridges();
+       pq2_find_bridges();
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_start)
@@ -173,6 +174,12 @@ m8260_init_IRQ(void)
         * in case the boot rom changed something on us.
         */
        cpm2_immr->im_intctl.ic_siprr = 0x05309770;
+
+#if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) || defined(CONFIG_PQ2FADS))
+       /* Initialize stuff for the 82xx CPLD IC and install demux  */
+       pq2pci_init_irq();
+#endif
+
 }
 
 /*
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
new file mode 100644 (file)
index 0000000..5e7a7ed
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2004 Red Hat, Inc.
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You 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/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/immap_cpm2.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+
+#include "m82xx_pci.h"
+
+/*
+ * Interrupt routing
+ */
+
+static inline int
+pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+       static char pci_irq_table[][4] =
+       /*
+        *      PCI IDSEL/INTPIN->INTLINE
+        *        A      B      C      D
+        */
+       {
+               { PIRQA, PIRQB, PIRQC, PIRQD }, /* IDSEL 22 - PCI slot 0 */
+               { PIRQD, PIRQA, PIRQB, PIRQC }, /* IDSEL 23 - PCI slot 1 */
+               { PIRQC, PIRQD, PIRQA, PIRQB }, /* IDSEL 24 - PCI slot 2 */
+       };
+
+       const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4;
+       return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static void
+pq2pci_mask_irq(unsigned int irq)
+{
+       int bit = irq - NR_CPM_INTS;
+
+       *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
+       return;
+}
+
+static void
+pq2pci_unmask_irq(unsigned int irq)
+{
+       int bit = irq - NR_CPM_INTS;
+
+       *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
+       return;
+}
+
+static void
+pq2pci_mask_and_ack(unsigned int irq)
+{
+       int bit = irq - NR_CPM_INTS;
+
+       *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
+       return;
+}
+
+static void
+pq2pci_end_irq(unsigned int irq)
+{
+       int bit = irq - NR_CPM_INTS;
+
+       *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
+       return;
+}
+
+struct hw_interrupt_type pq2pci_ic = {
+       "PQ2 PCI",
+       NULL,
+       NULL,
+       pq2pci_unmask_irq,
+       pq2pci_mask_irq,
+       pq2pci_mask_and_ack,
+       pq2pci_end_irq,
+       0
+};
+
+static irqreturn_t
+pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
+{
+       unsigned long stat, mask, pend;
+       int bit;
+
+       for(;;) {
+               stat = *(volatile unsigned long *) PCI_INT_STAT_REG;
+               mask = *(volatile unsigned long *) PCI_INT_MASK_REG;
+               pend = stat & ~mask & 0xf0000000;
+               if (!pend)
+                       break;
+               for (bit = 0; pend != 0; ++bit, pend <<= 1) {
+                       if (pend & 0x80000000)
+                               __do_IRQ(NR_CPM_INTS + bit, regs);
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction pq2pci_irqaction = {
+       .handler = pq2pci_irq_demux,
+       .flags   = SA_INTERRUPT,
+       .mask    = CPU_MASK_NONE,
+       .name    = "PQ2 PCI cascade",
+};
+
+
+void
+pq2pci_init_irq(void)
+{
+       int irq;
+       volatile cpm2_map_t *immap = cpm2_immr;
+#if defined CONFIG_ADS8272
+       /* configure chip select for PCI interrupt controller */
+       immap->im_memctl.memc_br3 = PCI_INT_STAT_REG | 0x00001801;
+       immap->im_memctl.memc_or3 = 0xffff8010;
+#elif defined CONFIG_PQ2FADS
+       immap->im_memctl.memc_br8 = PCI_INT_STAT_REG | 0x00001801;
+       immap->im_memctl.memc_or8 = 0xffff8010;
+#endif
+       for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++)
+               irq_desc[irq].handler = &pq2pci_ic;
+
+       /* make PCI IRQ level sensitive */
+       immap->im_intctl.ic_siexr &=
+               ~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1)));
+
+       /* mask all PCI interrupts */
+       *(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000;
+
+       /* install the demultiplexer for the PCI cascade interrupt */
+       setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction);
+       return;
+}
+
+static int
+pq2pci_exclude_device(u_char bus, u_char devfn)
+{
+       return PCIBIOS_SUCCESSFUL;
+}
+
+/* PCI bus configuration registers.
+ */
+static void
+pq2ads_setup_pci(struct pci_controller *hose)
+{
+       __u32 val;
+       volatile cpm2_map_t *immap = cpm2_immr;
+       bd_t* binfo = (bd_t*) __res;
+       u32 sccr = immap->im_clkrst.car_sccr;
+       uint pci_div,freq,time;
+               /* PCI int lowest prio */
+       /* Each 4 bits is a device bus request  and the MS 4bits
+        is highest priority */
+       /* Bus                4bit value
+          ---                ----------
+          CPM high             0b0000
+          CPM middle           0b0001
+          CPM low              0b0010
+          PCI reguest          0b0011
+          Reserved             0b0100
+          Reserved             0b0101
+          Internal Core        0b0110
+          External Master 1    0b0111
+          External Master 2    0b1000
+          External Master 3    0b1001
+          The rest are reserved
+        */
+       immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
+       /* park bus on core */
+       immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE;
+       /*
+        * Set up master windows that allow the CPU to access PCI space. These
+        * windows are set up using the two SIU PCIBR registers.
+        */
+
+       immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE;
+       immap->im_memctl.memc_pcibr0  = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE;
+
+#ifdef M82xx_PCI_SEC_WND_SIZE
+       immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE;
+       immap->im_memctl.memc_pcibr1  = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE;
+#endif
+
+#if defined CONFIG_ADS8272
+       immap->im_siu_conf.siu_82xx.sc_siumcr =
+               (immap->im_siu_conf.siu_82xx.sc_siumcr &
+               ~(SIUMCR_BBD | SIUMCR_ESE | SIUMCR_PBSE |
+               SIUMCR_CDIS | SIUMCR_DPPC11 | SIUMCR_L2CPC11 |
+               SIUMCR_LBPC11 | SIUMCR_APPC11 |
+               SIUMCR_CS10PC11 | SIUMCR_BCTLC11 | SIUMCR_MMR11)) |
+               SIUMCR_DPPC11 | SIUMCR_L2CPC01 | SIUMCR_LBPC00 |
+               SIUMCR_APPC10 | SIUMCR_CS10PC00 |
+               SIUMCR_BCTLC00 | SIUMCR_MMR11 ;
+
+#elif defined CONFIG_PQ2FADS
+       /*
+        * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
+        * and local bus for PCI (SIUMCR [LBPC]).
+        */
+       immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.sc_siumcr &
+                               ~(SIUMCR_L2PC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) |
+                               SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10;
+#endif
+       /* Enable PCI  */
+       immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
+
+       pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) *
+                       ( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1);
+       freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div));
+       time = (int)666666/freq;
+       /* due to PCI Local Bus spec, some devices needs to wait such a long
+       time after RST  deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */
+       printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq,
+       (time==1) ? "0.5 seconds":"1 second" );
+
+       {
+               int i;
+               for(i=0;i<(500*time);i++)
+                       udelay(1000);
+       }
+
+       /* setup ATU registers */
+       immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO |
+                               ((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT));
+       immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT);
+       immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT);
+
+       /* Set-up non-prefetchable window */
+       immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT));
+       immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT);
+       immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT);
+
+       /* Set-up prefetchable window */
+       immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN |
+               (~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT));
+       immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT);
+       immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT);
+
+       /* Inbound transactions from PCI memory space */
+       immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN |
+                                       ((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT));
+       immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS  >> PITA_ADDR_SHIFT);
+       immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT);
+
+#if defined CONFIG_ADS8272
+       /* PCI int highest prio */
+       immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x01236745;
+#elif defined CONFIG_PQ2FADS
+       immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
+#endif
+       /* park bus on PCI */
+       immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
+
+       /* Enable bus mastering and inbound memory transactions */
+       early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val);
+       val &= 0xffff0000;
+       val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER;
+       early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val);
+
+}
+
+void __init pq2_find_bridges(void)
+{
+       extern int pci_assign_all_busses;
+       struct pci_controller * hose;
+       int host_bridge;
+
+       pci_assign_all_busses = 1;
+
+       hose = pcibios_alloc_controller();
+
+       if (!hose)
+               return;
+
+       ppc_md.pci_swizzle = common_swizzle;
+
+       hose->first_busno = 0;
+       hose->bus_offset = 0;
+       hose->last_busno = 0xff;
+
+#ifdef CONFIG_ADS8272
+       hose->set_cfg_type = 1;
+#endif
+
+       setup_m8260_indirect_pci(hose,
+                                (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
+                                (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
+
+       /* Make sure it is a supported bridge */
+       early_read_config_dword(hose,
+                               0,
+                               PCI_DEVFN(0,0),
+                               PCI_VENDOR_ID,
+                               &host_bridge);
+       switch (host_bridge) {
+               case PCI_DEVICE_ID_MPC8265:
+                       break;
+               case PCI_DEVICE_ID_MPC8272:
+                       break;
+               default:
+                       printk("Attempting to use unrecognized host bridge ID"
+                               " 0x%08x.\n", host_bridge);
+                       break;
+       }
+
+       pq2ads_setup_pci(hose);
+
+       hose->io_space.start =  M82xx_PCI_LOWER_IO;
+       hose->io_space.end = M82xx_PCI_UPPER_IO;
+       hose->mem_space.start = M82xx_PCI_LOWER_MEM;
+       hose->mem_space.end = M82xx_PCI_UPPER_MMIO;
+       hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET;
+
+       isa_io_base =
+       (unsigned long) ioremap(M82xx_PCI_IO_BASE,
+                                       M82xx_PCI_IO_SIZE);
+       hose->io_base_virt = (void *) isa_io_base;
+
+       /* setup resources */
+       pci_init_resource(&hose->mem_resources[0],
+                       M82xx_PCI_LOWER_MEM,
+                       M82xx_PCI_UPPER_MEM,
+                       IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
+
+       pci_init_resource(&hose->mem_resources[1],
+                       M82xx_PCI_LOWER_MMIO,
+                       M82xx_PCI_UPPER_MMIO,
+                       IORESOURCE_MEM, "PCI memory");
+
+       pci_init_resource(&hose->io_resource,
+                       M82xx_PCI_LOWER_IO,
+                       M82xx_PCI_UPPER_IO,
+                       IORESOURCE_IO | 1, "PCI I/O");
+
+       ppc_md.pci_exclude_device = pq2pci_exclude_device;
+       hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+       ppc_md.pci_map_irq = pq2pci_map_irq;
+       ppc_md.pcibios_fixup = NULL;
+       ppc_md.pcibios_fixup_bus = NULL;
+
+}
diff --git a/arch/ppc/syslib/m82xx_pci.h b/arch/ppc/syslib/m82xx_pci.h
new file mode 100644 (file)
index 0000000..924f73f
--- /dev/null
@@ -0,0 +1,92 @@
+
+#ifndef _PPC_KERNEL_M82XX_PCI_H
+#define _PPC_KERNEL_M82XX_PCI_H
+
+#include <asm/m8260_pci.h>
+/*
+ *   Local->PCI map (from CPU)                             controlled by
+ *   MPC826x master window
+ *
+ *   0xF6000000 - 0xF7FFFFFF    IO space
+ *   0x80000000 - 0xBFFFFFFF    CPU2PCI memory space       PCIBR0
+ *
+ *   0x80000000 - 0x9FFFFFFF    PCI Mem with prefetch      (Outbound ATU #1)
+ *   0xA0000000 - 0xBFFFFFFF    PCI Mem w/o  prefetch      (Outbound ATU #2)
+ *   0xF6000000 - 0xF7FFFFFF    32-bit PCI IO              (Outbound ATU #3)
+ *
+ *   PCI->Local map (from PCI)
+ *   MPC826x slave window                                  controlled by
+ *
+ *   0x00000000 - 0x07FFFFFF    MPC826x local memory       (Inbound ATU #1)
+ */
+
+/*
+ * Slave window that allows PCI masters to access MPC826x local memory.
+ * This window is set up using the first set of Inbound ATU registers
+ */
+
+#ifndef M82xx_PCI_SLAVE_MEM_LOCAL
+#define M82xx_PCI_SLAVE_MEM_LOCAL      (((struct bd_info *)__res)->bi_memstart)
+#define M82xx_PCI_SLAVE_MEM_BUS                (((struct bd_info *)__res)->bi_memstart)
+#define M82xx_PCI_SLAVE_MEM_SIZE       (((struct bd_info *)__res)->bi_memsize)
+#endif
+
+/*
+ * This is the window that allows the CPU to access PCI address space.
+ * It will be setup with the SIU PCIBR0 register. All three PCI master
+ * windows, which allow the CPU to access PCI prefetch, non prefetch,
+ * and IO space (see below), must all fit within this window.
+ */
+
+#ifndef M82xx_PCI_LOWER_MEM
+#define M82xx_PCI_LOWER_MEM            0x80000000
+#define M82xx_PCI_UPPER_MEM            0x9fffffff
+#define M82xx_PCI_MEM_OFFSET           0x00000000
+#define M82xx_PCI_MEM_SIZE             0x20000000
+#endif
+
+#ifndef M82xx_PCI_LOWER_MMIO
+#define M82xx_PCI_LOWER_MMIO           0xa0000000
+#define M82xx_PCI_UPPER_MMIO           0xafffffff
+#define M82xx_PCI_MMIO_OFFSET          0x00000000
+#define M82xx_PCI_MMIO_SIZE            0x20000000
+#endif
+
+#ifndef M82xx_PCI_LOWER_IO
+#define M82xx_PCI_LOWER_IO             0x00000000
+#define M82xx_PCI_UPPER_IO             0x01ffffff
+#define M82xx_PCI_IO_BASE              0xf6000000
+#define M82xx_PCI_IO_SIZE              0x02000000
+#endif
+
+#ifndef M82xx_PCI_PRIM_WND_SIZE
+#define M82xx_PCI_PRIM_WND_SIZE        ~(M82xx_PCI_IO_SIZE - 1U)
+#define M82xx_PCI_PRIM_WND_BASE                (M82xx_PCI_IO_BASE)
+#endif
+
+#ifndef M82xx_PCI_SEC_WND_SIZE
+#define M82xx_PCI_SEC_WND_SIZE                 ~(M82xx_PCI_MEM_SIZE + M82xx_PCI_MMIO_SIZE - 1U)
+#define M82xx_PCI_SEC_WND_BASE                 (M82xx_PCI_LOWER_MEM)
+#endif
+
+#ifndef POTA_ADDR_SHIFT
+#define POTA_ADDR_SHIFT                12
+#endif
+
+#ifndef PITA_ADDR_SHIFT
+#define PITA_ADDR_SHIFT                12
+#endif
+
+#ifndef _IO_BASE
+#define _IO_BASE isa_io_base
+#endif
+
+#ifdef CONFIG_8260_PCI9
+struct pci_controller;
+extern void setup_m8260_indirect_pci(struct pci_controller* hose,
+                                       u32 cfg_addr, u32 cfg_data);
+#else
+#define setup_m8260_indirect_pci setup_indirect_pci
+#endif
+
+#endif /* _PPC_KERNEL_M8260_PCI_H */
index 5c1a919eaabfb367a57e0ec714ceebf129aaa0ff..75c8e9834ae70ad142f2aa8e65e025065a4816de 100644 (file)
@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
                .iotype         = UPIO_MEM,
                .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
        },
+       { },
 };
 
 struct platform_device ppc_sys_platform_devices[] = {
index a231795ee26f0a37cc228d51a76a27c314240481..1e658ef57e75d7853ae59b557a5f054ca5a58467 100644 (file)
@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
                .iotype         = UPIO_MEM,
                .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
        },
+       { },
 };
 
 struct platform_device ppc_sys_platform_devices[] = {
index 7619e16fccaef18ddd666a5058487283f884af5c..000ba47c67cbacd5b1bde36148c2fe0328e9db04 100644 (file)
@@ -275,7 +275,7 @@ static void __init openpic_enable_sie(void)
 }
 #endif
 
-#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM)
+#if defined(CONFIG_EPIC_SERIAL_MODE)
 static void openpic_reset(void)
 {
        openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@ -557,12 +557,10 @@ static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
  */
 void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
 {
-       cpumask_t phys;
        DECL_THIS_CPU;
 
        CHECK_THIS_CPU;
        check_arg_ipi(ipi);
-       phys = physmask(cpumask);
        openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
                      cpus_addr(physmask(cpumask))[0]);
 }
@@ -995,8 +993,6 @@ int openpic_resume(struct sys_device *sysdev)
                return 0;
        }
 
-       openpic_reset();
-
        /* OpenPIC sometimes seem to need some time to be fully back up... */
        do {
                openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
index c28f9d679484f348e18c5409141983be5a7fcfe6..843cf8873e60f35376b80e2cda72839ee99fb35a 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/mmu.h>
 #include <asm/ppc_sys.h>
 #include <asm/kgdb.h>
+#include <asm/delay.h>
 
 #include <syslib/ppc83xx_setup.h>
 
@@ -117,7 +118,34 @@ mpc83xx_early_serial_map(void)
 void
 mpc83xx_restart(char *cmd)
 {
+       volatile unsigned char __iomem *reg;
+       unsigned char tmp;
+
+       reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
+
        local_irq_disable();
+
+       /*
+        * Unlock the BCSR bits so a PRST will update the contents.
+        * Otherwise the reset asserts but doesn't clear.
+        */
+       tmp = in_8(reg + BCSR_MISC_REG3_OFF);
+       tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
+       out_8(reg + BCSR_MISC_REG3_OFF, tmp);
+
+       /*
+        * Trigger a reset via a low->high transition of the
+        * PORESET bit.
+        */
+       tmp = in_8(reg + BCSR_MISC_REG2_OFF);
+       tmp &= ~BCSR_MISC_REG2_PORESET;
+       out_8(reg + BCSR_MISC_REG2_OFF, tmp);
+
+       udelay(1);
+
+       tmp |= BCSR_MISC_REG2_PORESET;
+       out_8(reg + BCSR_MISC_REG2_OFF, tmp);
+
        for(;;);
 }
 
index 152c3ef1312aa052072b25d86db7334583c74280..f3277f469e78a2695422189e4a28ba5124878ccd 100644 (file)
@@ -132,6 +132,12 @@ mpc85xx_halt(void)
 }
 
 #ifdef CONFIG_PCI
+
+#if defined(CONFIG_MPC8555_CDS)
+extern void mpc85xx_cds_enable_via(struct pci_controller *hose);
+extern void mpc85xx_cds_fixup_via(struct pci_controller *hose);
+#endif
+
 static void __init
 mpc85xx_setup_pci1(struct pci_controller *hose)
 {
@@ -302,8 +308,18 @@ mpc85xx_setup_hose(void)
 
        ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 
+#if defined(CONFIG_MPC8555_CDS)
+       /* Pre pciauto_bus_scan VIA init */
+       mpc85xx_cds_enable_via(hose_a);
+#endif
+
        hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
 
+#if defined(CONFIG_MPC8555_CDS)
+       /* Post pciauto_bus_scan VIA fixup */
+       mpc85xx_cds_fixup_via(hose_a);
+#endif
+
 #ifdef CONFIG_85xx_PCI2
        hose_b = pcibios_alloc_controller();
 
index 2cee87137f2efa9b6efff2d25aff5c1915061464..7f15136830f4fbf38fe38e3a5418e85e51e47b96 100644 (file)
@@ -626,8 +626,18 @@ inspect_node(phandle node, struct device_node *dad,
        l = call_prom("package-to-path", 3, 1, node,
                      mem_start, mem_end - mem_start);
        if (l >= 0) {
+               char *p, *ep;
+
                np->full_name = PTRUNRELOC((char *) mem_start);
                *(char *)(mem_start + l) = 0;
+               /* Fixup an Apple bug where they have bogus \0 chars in the
+                * middle of the path in some properties
+                */
+               for (p = (char *)mem_start, ep = p + l; p < ep; p++)
+                       if ((*p) == '\0') {
+                               memmove(p, p+1, ep - p);
+                               ep--;
+                       }
                mem_start = ALIGNUL(mem_start + l + 1);
        }
 
index ef1f05e437c4dc9d908076a82a22f5364a471198..5cb343883e4d88649f8e8eaad39c67e856027d1e 100644 (file)
@@ -40,6 +40,10 @@ config COMPAT
        bool
        default y
 
+config SCHED_NO_NO_OMIT_FRAME_POINTER
+       bool
+       default y
+
 # We optimistically allocate largepages from the VM, so make the limit
 # large enough (16MB). This badly named config option is actually
 # max order + 1
@@ -258,6 +262,7 @@ config PPC_RTAS
 config RTAS_PROC
        bool "Proc interface to RTAS"
        depends on PPC_RTAS
+       default y
 
 config RTAS_FLASH
        tristate "Firmware flash interface"
@@ -293,6 +298,9 @@ config SECCOMP
 
 endmenu
 
+config ISA_DMA_API
+       bool
+       default y
 
 menu "General setup"
 
index e341a129da8046b3338deaa2c22c3dad796b341a..46b1ce58da3b39abd2ae6349040bc87001dd607c 100644 (file)
@@ -5,6 +5,9 @@ source "lib/Kconfig.debug"
 config DEBUG_STACKOVERFLOW
        bool "Check for stack overflows"
        depends on DEBUG_KERNEL
+       help
+         This option will cause messages to be printed if free stack space
+         drops below a certain limit.
 
 config KPROBES
        bool "Kprobes"
index b0fa86ad8b1be251c2066920429ae0cb2db1f722..da12ea2ca46497d6bae9f1e6453817cbb0ca2e97 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/string.h>
 #include <asm/processor.h>
 #include <asm/page.h>
-#include <asm/bootinfo.h>
 
 extern void *finddevice(const char *);
 extern int getprop(void *, const char *, void *, int);
index 7b607d1862cb07a9c4fb9a1203447c8bdedde63b..d5218b15824e93444a5b2c8810ffff5e0e6416d4 100644 (file)
 #include <linux/string.h>
 #include <linux/ctype.h>
 
+extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor);
+
+/* The unnecessary pointer compare is there
+ * to check for type safety (n must be 64bit)
+ */
+# define do_div(n,base) ({                             \
+       __u32 __base = (base);                  \
+       __u32 __rem;                                    \
+       (void)(((typeof((n)) *)0) == ((unsigned long long *)0));        \
+       if (((n) >> 32) == 0) {                 \
+               __rem = (__u32)(n) % __base;            \
+               (n) = (__u32)(n) / __base;              \
+       } else                                          \
+               __rem = __div64_32(&(n), __base);       \
+       __rem;                                          \
+ })
+
 int (*prom)(void *);
 
 void *chosen_handle;
@@ -352,7 +369,7 @@ static int skip_atoi(const char **s)
 #define SPECIAL        32              /* 0x */
 #define LARGE  64              /* use 'ABCDEF' instead of 'abcdef' */
 
-static char * number(char * str, long num, int base, int size, int precision, int type)
+static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
 {
        char c,sign,tmp[66];
        const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
@@ -367,9 +384,9 @@ static char * number(char * str, long num, int base, int size, int precision, in
        c = (type & ZEROPAD) ? '0' : ' ';
        sign = 0;
        if (type & SIGN) {
-               if (num < 0) {
+               if ((signed long long)num < 0) {
                        sign = '-';
-                       num = -num;
+                       num = - (signed long long)num;
                        size--;
                } else if (type & PLUS) {
                        sign = '+';
@@ -389,8 +406,7 @@ static char * number(char * str, long num, int base, int size, int precision, in
        if (num == 0)
                tmp[i++]='0';
        else while (num != 0) {
-               tmp[i++] = digits[num % base];
-               num /= base;
+               tmp[i++] = digits[do_div(num, base)];
        }
        if (i > precision)
                precision = i;
@@ -426,7 +442,7 @@ int sprintf(char * buf, const char *fmt, ...);
 int vsprintf(char *buf, const char *fmt, va_list args)
 {
        int len;
-       unsigned long num;
+       unsigned long long num;
        int i, base;
        char * str;
        const char *s;
diff --git a/arch/ppc64/boot/start.c b/arch/ppc64/boot/start.c
deleted file mode 100644 (file)
index ea247e7..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the 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 <stdarg.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-
-#include <asm/div64.h>
-
-int (*prom)(void *);
-
-void *chosen_handle;
-void *stdin;
-void *stdout;
-void *stderr;
-
-void exit(void);
-void *finddevice(const char *name);
-int getprop(void *phandle, const char *name, void *buf, int buflen);
-void chrpboot(int a1, int a2, void *prom);     /* in main.c */
-
-void printk(char *fmt, ...);
-
-void
-start(int a1, int a2, void *promptr)
-{
-       prom = (int (*)(void *)) promptr;
-       chosen_handle = finddevice("/chosen");
-       if (chosen_handle == (void *) -1)
-               exit();
-       if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
-               exit();
-       stderr = stdout;
-       if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
-       exit();
-
-       chrpboot(a1, a2, promptr);
-       for (;;)
-               exit();
-}
-
-int
-write(void *handle, void *ptr, int nb)
-{
-       struct prom_args {
-               char *service;
-               int nargs;
-               int nret;
-               void *ihandle;
-               void *addr;
-               int len;
-               int actual;
-       } args;
-
-       args.service = "write";
-       args.nargs = 3;
-       args.nret = 1;
-       args.ihandle = handle;
-       args.addr = ptr;
-       args.len = nb;
-       args.actual = -1;
-       (*prom)(&args);
-       return args.actual;
-}
-
-int
-read(void *handle, void *ptr, int nb)
-{
-       struct prom_args {
-               char *service;
-               int nargs;
-               int nret;
-               void *ihandle;
-               void *addr;
-               int len;
-               int actual;
-       } args;
-
-       args.service = "read";
-       args.nargs = 3;
-       args.nret = 1;
-       args.ihandle = handle;
-       args.addr = ptr;
-       args.len = nb;
-       args.actual = -1;
-       (*prom)(&args);
-       return args.actual;
-}
-
-void
-exit()
-{
-       struct prom_args {
-               char *service;
-       } args;
-
-       for (;;) {
-               args.service = "exit";
-               (*prom)(&args);
-       }
-}
-
-void
-pause(void)
-{
-       struct prom_args {
-               char *service;
-       } args;
-
-       args.service = "enter";
-       (*prom)(&args);
-}
-
-void *
-finddevice(const char *name)
-{
-       struct prom_args {
-               char *service;
-               int nargs;
-               int nret;
-               const char *devspec;
-               void *phandle;
-       } args;
-
-       args.service = "finddevice";
-       args.nargs = 1;
-       args.nret = 1;
-       args.devspec = name;
-       args.phandle = (void *) -1;
-       (*prom)(&args);
-       return args.phandle;
-}
-
-void *
-claim(unsigned long virt, unsigned long size, unsigned long align)
-{
-       struct prom_args {
-               char *service;
-               int nargs;
-               int nret;
-               unsigned int virt;
-               unsigned int size;
-               unsigned int align;
-               void *ret;
-       } args;
-
-       args.service = "claim";
-       args.nargs = 3;
-       args.nret = 1;
-       args.virt = virt;
-       args.size = size;
-       args.align = align;
-       (*prom)(&args);
-       return args.ret;
-}
-
-int
-getprop(void *phandle, const char *name, void *buf, int buflen)
-{
-       struct prom_args {
-               char *service;
-               int nargs;
-               int nret;
-               void *phandle;
-               const char *name;
-               void *buf;
-               int buflen;
-               int size;
-       } args;
-
-       args.service = "getprop";
-       args.nargs = 4;
-       args.nret = 1;
-       args.phandle = phandle;
-       args.name = name;
-       args.buf = buf;
-       args.buflen = buflen;
-       args.size = -1;
-       (*prom)(&args);
-       return args.size;
-}
-
-int
-putc(int c, void *f)
-{
-       char ch = c;
-
-       if (c == '\n')
-               putc('\r', f);
-       return write(f, &ch, 1) == 1? c: -1;
-}
-
-int
-putchar(int c)
-{
-       return putc(c, stdout);
-}
-
-int
-fputs(char *str, void *f)
-{
-       int n = strlen(str);
-
-       return write(f, str, n) == n? 0: -1;
-}
-
-int
-readchar(void)
-{
-       char ch;
-
-       for (;;) {
-               switch (read(stdin, &ch, 1)) {
-               case 1:
-                       return ch;
-               case -1:
-                       printk("read(stdin) returned -1\r\n");
-                       return -1;
-               }
-       }
-}
-
-static char line[256];
-static char *lineptr;
-static int lineleft;
-
-int
-getchar(void)
-{
-       int c;
-
-       if (lineleft == 0) {
-               lineptr = line;
-               for (;;) {
-                       c = readchar();
-                       if (c == -1 || c == 4)
-                               break;
-                       if (c == '\r' || c == '\n') {
-                               *lineptr++ = '\n';
-                               putchar('\n');
-                               break;
-                       }
-                       switch (c) {
-                       case 0177:
-                       case '\b':
-                               if (lineptr > line) {
-                                       putchar('\b');
-                                       putchar(' ');
-                                       putchar('\b');
-                                       --lineptr;
-                               }
-                               break;
-                       case 'U' & 0x1F:
-                               while (lineptr > line) {
-                                       putchar('\b');
-                                       putchar(' ');
-                                       putchar('\b');
-                                       --lineptr;
-                               }
-                               break;
-                       default:
-                               if (lineptr >= &line[sizeof(line) - 1])
-                                       putchar('\a');
-                               else {
-                                       putchar(c);
-                                       *lineptr++ = c;
-                               }
-                       }
-               }
-               lineleft = lineptr - line;
-               lineptr = line;
-       }
-       if (lineleft == 0)
-               return -1;
-       --lineleft;
-       return *lineptr++;
-}
-
-
-
-/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
-unsigned char _ctype[] = {
-_C,_C,_C,_C,_C,_C,_C,_C,                       /* 0-7 */
-_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,                /* 8-15 */
-_C,_C,_C,_C,_C,_C,_C,_C,                       /* 16-23 */
-_C,_C,_C,_C,_C,_C,_C,_C,                       /* 24-31 */
-_S|_SP,_P,_P,_P,_P,_P,_P,_P,                   /* 32-39 */
-_P,_P,_P,_P,_P,_P,_P,_P,                       /* 40-47 */
-_D,_D,_D,_D,_D,_D,_D,_D,                       /* 48-55 */
-_D,_D,_P,_P,_P,_P,_P,_P,                       /* 56-63 */
-_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,     /* 64-71 */
-_U,_U,_U,_U,_U,_U,_U,_U,                       /* 72-79 */
-_U,_U,_U,_U,_U,_U,_U,_U,                       /* 80-87 */
-_U,_U,_U,_P,_P,_P,_P,_P,                       /* 88-95 */
-_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,     /* 96-103 */
-_L,_L,_L,_L,_L,_L,_L,_L,                       /* 104-111 */
-_L,_L,_L,_L,_L,_L,_L,_L,                       /* 112-119 */
-_L,_L,_L,_P,_P,_P,_P,_C,                       /* 120-127 */
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,               /* 128-143 */
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,               /* 144-159 */
-_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
-_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
-_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
-_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
-_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
-_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
-
-size_t strnlen(const char * s, size_t count)
-{
-       const char *sc;
-
-       for (sc = s; count-- && *sc != '\0'; ++sc)
-               /* nothing */;
-       return sc - s;
-}
-
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
-{
-       unsigned long result = 0,value;
-
-       if (!base) {
-               base = 10;
-               if (*cp == '0') {
-                       base = 8;
-                       cp++;
-                       if ((*cp == 'x') && isxdigit(cp[1])) {
-                               cp++;
-                               base = 16;
-                       }
-               }
-       }
-       while (isxdigit(*cp) &&
-              (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
-               result = result*base + value;
-               cp++;
-       }
-       if (endp)
-               *endp = (char *)cp;
-       return result;
-}
-
-long simple_strtol(const char *cp,char **endp,unsigned int base)
-{
-       if(*cp=='-')
-               return -simple_strtoul(cp+1,endp,base);
-       return simple_strtoul(cp,endp,base);
-}
-
-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' */
-
-static char * number(char * str, long 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;
-}
-
-/* Forward decl. needed for IP address printing stuff... */
-int sprintf(char * buf, const char *fmt, ...);
-
-int vsprintf(char *buf, const char *fmt, va_list args)
-{
-       int len;
-       unsigned long 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 */
-                               /* 'z' support added 23/7/1999 S.H.    */
-                               /* 'z' changed to 'Z' --davidm 1/25/99 */
-
-       
-       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' || *fmt =='Z') {
-                       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 *);
-                       if (!s)
-                               s = "<NULL>";
-
-                       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 if (qualifier == 'Z') {
-                               size_t * ip = va_arg(args, size_t *);
-                               *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, long long);
-               else if (qualifier == 'l') {
-                       num = va_arg(args, unsigned long);
-                       if (flags & SIGN)
-                               num = (signed long) num;
-               } else if (qualifier == 'Z') {
-                       num = va_arg(args, size_t);
-               } else if (qualifier == 'h') {
-                       num = (unsigned short) va_arg(args, int);
-                       if (flags & SIGN)
-                               num = (signed short) num;
-               } else {
-                       num = va_arg(args, unsigned int);
-                       if (flags & SIGN)
-                               num = (signed int) num;
-               }
-               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;
-}
-
-static char sprint_buf[1024];
-
-void
-printk(char *fmt, ...)
-{
-       va_list args;
-       int n;
-
-       va_start(args, fmt);
-       n = vsprintf(sprint_buf, fmt, args);
-       va_end(args);
-       write(stdout, sprint_buf, n);
-}
-
-int
-printf(char *fmt, ...)
-{
-       va_list args;
-       int n;
-
-       va_start(args, fmt);
-       n = vsprintf(sprint_buf, fmt, args);
-       va_end(args);
-       write(stdout, sprint_buf, n);
-       return n;
-}
index 0f90df0b3f9c308b634c9aef891972e3e0710622..1eb33398648edf920bba7fe78137a499d65d1ac9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11
-# Thu Mar 10 16:47:04 2005
+# Linux kernel version: 2.6.12-rc6
+# Tue Jun 14 16:59:20 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -31,19 +32,20 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=17
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
@@ -87,6 +89,8 @@ CONFIG_NR_CPUS=2
 # CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -97,6 +101,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 # CONFIG_HOTPLUG_CPU is not set
 
 #
@@ -104,10 +109,6 @@ CONFIG_PCI_NAMES=y
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -293,7 +294,6 @@ CONFIG_SCSI_SATA_SVW=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -301,7 +301,6 @@ CONFIG_SCSI_SATA_SVW=y
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -310,6 +309,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -332,6 +332,7 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
 
 #
 # Fusion MPT device support
@@ -394,7 +395,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
@@ -564,6 +564,8 @@ CONFIG_E1000=y
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
 CONFIG_TIGON3=m
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -630,18 +632,6 @@ CONFIG_INPUT_JOYDEV=m
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -659,6 +649,16 @@ CONFIG_INPUT_MOUSE=y
 # 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 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -676,6 +676,7 @@ CONFIG_HW_CONSOLE=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_PMACZILOG is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -698,9 +699,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Ftape, the floppy tape device driver
 #
+CONFIG_AGP=m
+CONFIG_AGP_UNINORTH=m
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
 
 #
 # TPM devices
@@ -730,12 +734,11 @@ CONFIG_I2C_ALGOBIT=y
 # 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_ISA is not set
 CONFIG_I2C_KEYWEST=y
-# CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
@@ -772,6 +775,7 @@ CONFIG_I2C_KEYWEST=y
 # 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_SMSC47B397 is not set
@@ -785,6 +789,7 @@ CONFIG_I2C_KEYWEST=y
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -817,6 +822,11 @@ CONFIG_I2C_KEYWEST=y
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
@@ -830,6 +840,7 @@ CONFIG_FB_OF=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_NVIDIA is not set
 CONFIG_FB_RIVA=y
 # CONFIG_FB_RIVA_I2C is not set
 # CONFIG_FB_RIVA_DEBUG is not set
@@ -847,6 +858,7 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -880,6 +892,8 @@ CONFIG_LCD_DEVICE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -890,8 +904,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -917,7 +929,6 @@ CONFIG_USB_PRINTER=y
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_RW_DETECT=y
 CONFIG_USB_STORAGE_DATAFAB=y
 CONFIG_USB_STORAGE_FREECOM=y
 CONFIG_USB_STORAGE_ISD200=y
@@ -1004,8 +1015,10 @@ CONFIG_USB_MON=y
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
 CONFIG_USB_SERIAL_BELKIN=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
 CONFIG_USB_SERIAL_CYPRESS_M8=m
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -1034,6 +1047,7 @@ CONFIG_USB_SERIAL_KLSI=m
 CONFIG_USB_SERIAL_KOBIL_SCT=m
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
 CONFIG_USB_SERIAL_SAFE=m
 CONFIG_USB_SERIAL_SAFE_PADDED=y
 CONFIG_USB_SERIAL_TI=m
@@ -1270,11 +1284,13 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_PRINTK_TIME is not set
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
index a39e9d2e25da1120946947ceac662f96bed0118e..f6a2b99afd6314b445d7b429776590818604f60f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc3-bk6
-# Wed Feb  9 23:34:52 2005
+# Linux kernel version: 2.6.12-rc6
+# Tue Jun 14 17:01:28 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=17
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -79,6 +85,8 @@ CONFIG_NR_CPUS=32
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_MSCHUNKS=y
 CONFIG_LPARCFG=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -89,16 +97,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -210,7 +215,6 @@ CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -219,7 +223,6 @@ CONFIG_SCSI_IBMVSCSI=m
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -228,6 +231,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -250,6 +254,7 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
 
 #
 # Fusion MPT device support
@@ -280,7 +285,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
@@ -445,7 +449,6 @@ CONFIG_PCNET32=y
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -471,6 +474,7 @@ CONFIG_E1000=m
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -538,14 +542,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
 #
 # Input Device Drivers
 #
@@ -555,6 +551,12 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -570,6 +572,7 @@ CONFIG_SOUND_GAMEPORT=y
 #
 CONFIG_SERIAL_CORE=m
 CONFIG_SERIAL_ICOM=m
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -592,9 +595,16 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -633,13 +643,9 @@ CONFIG_MAX_RAW_DEVS=256
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
 
 #
 # USB Gadget Support
@@ -848,10 +854,13 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
@@ -881,6 +890,7 @@ CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
index cf527501915c6051f3ceba11e7968b7353301f10..8051b0f47b6f6ece08107b5a9929943f41b43895 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc3-bk6
-# Wed Feb  9 23:34:53 2005
+# Linux kernel version: 2.6.12-rc6
+# Tue Jun 14 17:12:48 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_AUDIT is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -84,6 +89,8 @@ CONFIG_NR_CPUS=2
 # CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -94,16 +101,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -261,7 +265,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -376,6 +379,8 @@ CONFIG_E1000=y
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -431,14 +436,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
 #
 # Input Device Drivers
 #
@@ -448,6 +445,12 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -469,7 +472,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_PMACZILOG is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -492,8 +495,15 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -518,8 +528,8 @@ CONFIG_I2C_ALGOBIT=y
 CONFIG_I2C_AMD8111=y
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
-# CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_PROSAVAGE is not set
@@ -545,7 +555,9 @@ CONFIG_I2C_AMD8111=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 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
@@ -556,9 +568,11 @@ CONFIG_I2C_AMD8111=y
 # 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_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -568,6 +582,7 @@ CONFIG_I2C_AMD8111=y
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -615,6 +630,8 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -625,8 +642,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -635,6 +650,8 @@ CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_SPLIT_ISO=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_SL811_HCD is not set
 
@@ -688,6 +705,7 @@ CONFIG_USB_HIDINPUT=y
 CONFIG_USB_PEGASUS=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -699,8 +717,10 @@ CONFIG_USB_PEGASUS=y
 CONFIG_USB_SERIAL=y
 # CONFIG_USB_SERIAL_CONSOLE is not set
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
 CONFIG_USB_SERIAL_CYPRESS_M8=m
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
@@ -729,6 +749,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
 CONFIG_USB_SERIAL_TI=m
 # CONFIG_USB_SERIAL_CYBERJACK is not set
@@ -750,6 +771,7 @@ CONFIG_USB_EZUSB=y
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -936,10 +958,13 @@ CONFIG_NLS_UTF8=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
@@ -971,6 +996,7 @@ CONFIG_CRYPTO_MD5=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_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
index 4fecf237d5c9f1be1c3a3b9b1f07b240d1472ad2..3eb5ef25d3a3cbf25984a318ff17f908c4cc7e13 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc3-bk6
-# Wed Feb  9 23:34:54 2005
+# Linux kernel version: 2.6.12-rc6
+# Tue Jun 14 17:13:47 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=17
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_CPUSETS=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -89,9 +95,12 @@ CONFIG_SCHED_SMT=y
 CONFIG_EEH=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_PPC_RTAS=y
+CONFIG_RTAS_PROC=y
 CONFIG_RTAS_FLASH=m
 CONFIG_SCANLOG=m
 CONFIG_LPARCFG=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -102,6 +111,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 CONFIG_HOTPLUG_CPU=y
 
 #
@@ -109,10 +119,6 @@ CONFIG_HOTPLUG_CPU=y
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -147,11 +153,10 @@ CONFIG_FW_LOADER=y
 #
 CONFIG_PARPORT=m
 CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
 # CONFIG_PARPORT_1284 is not set
 
 #
@@ -293,7 +298,6 @@ CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -310,7 +314,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_IPR=y
 CONFIG_SCSI_IPR_TRACE=y
 CONFIG_SCSI_IPR_DUMP=y
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -319,6 +322,7 @@ CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -341,6 +345,8 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -371,7 +377,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
@@ -539,7 +544,6 @@ CONFIG_PCNET32=y
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -565,6 +569,8 @@ CONFIG_E1000=y
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -635,20 +641,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -668,6 +660,18 @@ CONFIG_INPUT_MISC=y
 CONFIG_INPUT_PCSPKR=m
 # CONFIG_INPUT_UINPUT is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -689,8 +693,8 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_PMACZILOG is not set
 CONFIG_SERIAL_ICOM=m
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -718,9 +722,16 @@ CONFIG_HVCS=m
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=1024
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -745,8 +756,8 @@ CONFIG_I2C_ALGOBIT=y
 # 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_ISA is not set
-# CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
@@ -773,7 +784,9 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 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
@@ -784,9 +797,11 @@ CONFIG_I2C_ALGOBIT=y
 # 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_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -796,6 +811,7 @@ CONFIG_I2C_ALGOBIT=y
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -828,8 +844,13 @@ CONFIG_I2C_ALGOBIT=y
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
-# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -838,6 +859,7 @@ CONFIG_FB_OF=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
@@ -858,6 +880,7 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -891,6 +914,8 @@ CONFIG_LCD_DEVICE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -901,8 +926,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -911,6 +934,8 @@ CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 
@@ -926,12 +951,11 @@ CONFIG_USB_OHCI_HCD=y
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT 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_HP8200e 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
@@ -975,6 +999,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -1000,6 +1025,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1208,10 +1234,13 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
@@ -1243,6 +1272,7 @@ CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
index 537b1cc82eab0bdb01a19ac9552b38061aa643c7..2f31bf3046f901a85a4b4361b73b58396b21b150 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc3-bk6
-# Wed Feb  9 23:34:51 2005
+# Linux kernel version: 2.6.12-rc5-git9
+# Sun Jun  5 09:26:47 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_AUDIT is not set
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_CPUSETS=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -91,9 +96,12 @@ CONFIG_DISCONTIGMEM=y
 CONFIG_EEH=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_PPC_RTAS=y
+CONFIG_RTAS_PROC=y
 CONFIG_RTAS_FLASH=m
 CONFIG_SCANLOG=m
 CONFIG_LPARCFG=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -104,6 +112,7 @@ CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 # CONFIG_PCI_LEGACY_PROC is not set
 # CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
 CONFIG_HOTPLUG_CPU=y
 
 #
@@ -111,10 +120,6 @@ CONFIG_HOTPLUG_CPU=y
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -149,11 +154,10 @@ CONFIG_FW_LOADER=y
 #
 CONFIG_PARPORT=m
 CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
 # CONFIG_PARPORT_1284 is not set
 
 #
@@ -301,6 +305,7 @@ CONFIG_SCSI_SATA_SVW=y
 # CONFIG_SCSI_ATA_PIIX is not set
 # CONFIG_SCSI_SATA_NV is not set
 # CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_QSTOR is not set
 # CONFIG_SCSI_SATA_SX4 is not set
 # CONFIG_SCSI_SATA_SIL is not set
 # CONFIG_SCSI_SATA_SIS is not set
@@ -310,7 +315,6 @@ CONFIG_SCSI_SATA_SVW=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -327,7 +331,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_IPR=y
 CONFIG_SCSI_IPR_TRACE=y
 CONFIG_SCSI_IPR_DUMP=y
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -336,6 +339,7 @@ CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 CONFIG_SCSI_DEBUG=m
@@ -358,6 +362,8 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -405,6 +411,7 @@ CONFIG_IEEE1394_AMDTP=m
 #
 CONFIG_ADB=y
 CONFIG_ADB_PMU=y
+CONFIG_PMAC_SMU=y
 # CONFIG_PMAC_PBOOK is not set
 # CONFIG_PMAC_BACKLIGHT is not set
 # CONFIG_INPUT_ADBHID is not set
@@ -420,7 +427,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
@@ -588,7 +594,6 @@ CONFIG_PCNET32=y
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -614,6 +619,8 @@ CONFIG_E1000=y
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -682,20 +689,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -715,6 +708,18 @@ CONFIG_INPUT_MISC=y
 CONFIG_INPUT_PCSPKR=m
 # CONFIG_INPUT_UINPUT is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -738,6 +743,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_PMACZILOG is not set
 CONFIG_SERIAL_ICOM=m
+CONFIG_SERIAL_JSM=m
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -766,9 +772,16 @@ CONFIG_HVCS=m
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -793,9 +806,9 @@ CONFIG_I2C_ALGOBIT=y
 CONFIG_I2C_AMD8111=y
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 CONFIG_I2C_KEYWEST=y
-# CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
@@ -822,7 +835,9 @@ CONFIG_I2C_KEYWEST=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 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
@@ -833,9 +848,11 @@ CONFIG_I2C_KEYWEST=y
 # 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_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -845,6 +862,7 @@ CONFIG_I2C_KEYWEST=y
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -877,6 +895,11 @@ CONFIG_I2C_KEYWEST=y
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
@@ -890,9 +913,8 @@ CONFIG_FB_OF=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_VGA16 is not set
-CONFIG_FB_RIVA=y
-CONFIG_FB_RIVA_I2C=y
-# CONFIG_FB_RIVA_DEBUG is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
@@ -913,6 +935,7 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -946,6 +969,8 @@ CONFIG_LCD_DEVICE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -956,8 +981,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -966,6 +989,8 @@ CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 
@@ -981,12 +1006,11 @@ CONFIG_USB_OHCI_HCD=y
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_RW_DETECT=y
 # 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_HP8200e 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
@@ -1030,6 +1054,7 @@ CONFIG_USB_HIDDEV=y
 CONFIG_USB_PEGASUS=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -1055,6 +1080,7 @@ CONFIG_USB_PEGASUS=y
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1276,10 +1302,13 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
@@ -1311,6 +1340,7 @@ CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
index d3604056e1a9c53d2407243ecb44aa282609363c..b61572eb2a7130d7a46924f8412024b9879286e7 100644 (file)
@@ -436,15 +436,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        REST_8GPRS(14, r1)
        REST_10GPRS(22, r1)
 
-#ifdef CONFIG_PPC_ISERIES
-       clrrdi  r7,r1,THREAD_SHIFT      /* get current_thread_info() */
-       ld      r7,TI_FLAGS(r7)         /* Get run light flag */
-       mfspr   r9,CTRLF
-       srdi    r7,r7,TIF_RUN_LIGHT
-       insrdi  r9,r7,1,63              /* Insert run light into CTRL */
-       mtspr   CTRLT,r9
-#endif
-
        /* convert old thread to its task_struct for return value */
        addi    r3,r3,-THREAD
        ld      r7,_NIP(r1)     /* Return to _switch caller in new task */
index 92a744c31ab183b2aec6e4532a593cef614bba13..346dbf606b5dd910e1a3609d315d96a1a830fa00 100644 (file)
@@ -626,10 +626,10 @@ system_reset_iSeries:
        lhz     r24,PACAPACAINDEX(r13)  /* Get processor # */
        cmpwi   0,r24,0                 /* Are we processor 0? */
        beq     .__start_initialization_iSeries /* Start up the first processor */
-       mfspr   r4,CTRLF
-       li      r5,RUNLATCH             /* Turn off the run light */
+       mfspr   r4,SPRN_CTRLF
+       li      r5,CTRL_RUNLATCH        /* Turn off the run light */
        andc    r4,r4,r5
-       mtspr   CTRLT,r4
+       mtspr   SPRN_CTRLT,r4
 
 1:
        HMT_LOW
@@ -2082,9 +2082,9 @@ _GLOBAL(hmt_start_secondary)
        mfspr   r4, HID0
        ori     r4, r4, 0x1
        mtspr   HID0, r4
-       mfspr   r4, CTRLF
+       mfspr   r4, SPRN_CTRLF
        oris    r4, r4, 0x40
-       mtspr   CTRLT, r4
+       mtspr   SPRN_CTRLT, r4
        blr
 #endif
 
index da20120f22617515f554e405d9eaa744288aca57..6d06eb550a3fb839077953caab8d6f82d96afe8a 100644 (file)
@@ -852,6 +852,28 @@ static int __init iSeries_src_init(void)
 
 late_initcall(iSeries_src_init);
 
+static int set_spread_lpevents(char *str)
+{
+       unsigned long i;
+       unsigned long val = simple_strtoul(str, NULL, 0);
+
+       /*
+        * The parameter is the number of processors to share in processing
+        * lp events.
+        */
+       if (( val > 0) && (val <= NR_CPUS)) {
+               for (i = 1; i < val; ++i)
+                       paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
+
+               printk("lpevent processing spread over %ld processors\n", val);
+       } else {
+               printk("invalid spread_lpevents %ld\n", val);
+       }
+
+       return 1;
+}
+__setup("spread_lpevents=", set_spread_lpevents);
+
 void __init iSeries_early_setup(void)
 {
        iSeries_fixup_klimit();
index 6abc621d3ba0ca1fd2f52b934d83faaae4d8d81e..f24ce2b872004ae4feb1f419eddb3c0866c1c440 100644 (file)
@@ -75,13 +75,9 @@ static int iSeries_idle(void)
 {
        struct paca_struct *lpaca;
        long oldval;
-       unsigned long CTRL;
 
        /* ensure iSeries run light will be out when idle */
-       clear_thread_flag(TIF_RUN_LIGHT);
-       CTRL = mfspr(CTRLF);
-       CTRL &= ~RUNLATCH;
-       mtspr(CTRLT, CTRL);
+       ppc64_runlatch_off();
 
        lpaca = get_paca();
 
@@ -111,7 +107,9 @@ static int iSeries_idle(void)
                        }
                }
 
+               ppc64_runlatch_on();
                schedule();
+               ppc64_runlatch_off();
        }
 
        return 0;
index 103daaf735734e5a6006d95e5a9ecda68cc01f21..e950a2058a1994fc9a9e8531465813f9de3ff09c 100644 (file)
@@ -45,12 +45,17 @@ static struct pt_regs jprobe_saved_regs;
 
 int arch_prepare_kprobe(struct kprobe *p)
 {
+       int ret = 0;
        kprobe_opcode_t insn = *p->addr;
 
-       if (IS_MTMSRD(insn) || IS_RFID(insn))
-               /* cannot put bp on RFID/MTMSRD */
-               return 1;
-       return 0;
+       if ((unsigned long)p->addr & 0x03) {
+               printk("Attempt to register kprobe at an unaligned address\n");
+               ret = -EINVAL;
+       } else if (IS_MTMSRD(insn) || IS_RFID(insn)) {
+               printk("Cannot register a kprobe on rfid or mtmsrd\n");
+               ret = -EINVAL;
+       }
+       return ret;
 }
 
 void arch_copy_kprobe(struct kprobe *p)
@@ -172,8 +177,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
        ret = emulate_step(regs, p->ainsn.insn[0]);
        if (ret == 0)
                regs->nip = (unsigned long)p->addr + 4;
-
-       regs->msr &= ~MSR_SE;
 }
 
 static inline int post_kprobe_handler(struct pt_regs *regs)
@@ -210,6 +213,7 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 
        if (kprobe_status & KPROBE_HIT_SS) {
                resume_execution(current_kprobe, regs);
+               regs->msr &= ~MSR_SE;
                regs->msr |= kprobe_saved_msr;
 
                unlock_kprobes();
@@ -233,8 +237,6 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
         */
        preempt_disable();
        switch (val) {
-       case DIE_IABR_MATCH:
-       case DIE_DABR_MATCH:
        case DIE_BPT:
                if (kprobe_handler(args->regs))
                        ret = NOTIFY_STOP;
index 1bd52ece497c6016a80ff535a68d52babbb139c6..5aca7e8005a80f9b5a188d04269347ac90c411b1 100644 (file)
@@ -1,7 +1,7 @@
 /*
   * mf.c
   * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
-  * Copyright (C) 2004 Stephen Rothwell  IBM Corporation
+  * Copyright (C) 2004-2005 Stephen Rothwell  IBM Corporation
   *
   * This modules exists as an interface between a Linux secondary partition
   * running on an iSeries and the primary partition's Virtual Service
 
 #include <asm/time.h>
 #include <asm/uaccess.h>
+#include <asm/paca.h>
 #include <asm/iSeries/vio.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/HvLpConfig.h>
 #include <asm/iSeries/ItSpCommArea.h>
+#include <asm/iSeries/ItLpQueue.h>
 
 /*
  * This is the structure layout for the Machine Facilites LPAR event
@@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
        complete(&rtc->com);
 }
 
-int mf_get_rtc(struct rtc_time *tm)
+static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
 {
-       struct ce_msg_comp_data ce_complete;
-       struct rtc_time_data rtc_data;
-       int rc;
-
-       memset(&ce_complete, 0, sizeof(ce_complete));
-       memset(&rtc_data, 0, sizeof(rtc_data));
-       init_completion(&rtc_data.com);
-       ce_complete.handler = &get_rtc_time_complete;
-       ce_complete.token = &rtc_data;
-       rc = signal_ce_msg_simple(0x40, &ce_complete);
-       if (rc)
-               return rc;
-       wait_for_completion(&rtc_data.com);
        tm->tm_wday = 0;
        tm->tm_yday = 0;
        tm->tm_isdst = 0;
-       if (rtc_data.rc) {
+       if (rc) {
                tm->tm_sec = 0;
                tm->tm_min = 0;
                tm->tm_hour = 0;
                tm->tm_mday = 15;
                tm->tm_mon = 5;
                tm->tm_year = 52;
-               return rtc_data.rc;
+               return rc;
        }
 
-       if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) ||
-           (rtc_data.ce_msg.ce_msg[2] == 0xaf)) {
+       if ((ce_msg[2] == 0xa9) ||
+           (ce_msg[2] == 0xaf)) {
                /* TOD clock is not set */
                tm->tm_sec = 1;
                tm->tm_min = 1;
@@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm)
                mf_set_rtc(tm);
        }
        {
-               u8 *ce_msg = rtc_data.ce_msg.ce_msg;
                u8 year = ce_msg[5];
                u8 sec = ce_msg[6];
                u8 min = ce_msg[7];
@@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm)
        return 0;
 }
 
+int mf_get_rtc(struct rtc_time *tm)
+{
+       struct ce_msg_comp_data ce_complete;
+       struct rtc_time_data rtc_data;
+       int rc;
+
+       memset(&ce_complete, 0, sizeof(ce_complete));
+       memset(&rtc_data, 0, sizeof(rtc_data));
+       init_completion(&rtc_data.com);
+       ce_complete.handler = &get_rtc_time_complete;
+       ce_complete.token = &rtc_data;
+       rc = signal_ce_msg_simple(0x40, &ce_complete);
+       if (rc)
+               return rc;
+       wait_for_completion(&rtc_data.com);
+       return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+}
+
+struct boot_rtc_time_data {
+       int busy;
+       struct ce_msg_data ce_msg;
+       int rc;
+};
+
+static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
+{
+       struct boot_rtc_time_data *rtc = token;
+
+       memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
+       rtc->rc = 0;
+       rtc->busy = 0;
+}
+
+int mf_get_boot_rtc(struct rtc_time *tm)
+{
+       struct ce_msg_comp_data ce_complete;
+       struct boot_rtc_time_data rtc_data;
+       int rc;
+
+       memset(&ce_complete, 0, sizeof(ce_complete));
+       memset(&rtc_data, 0, sizeof(rtc_data));
+       rtc_data.busy = 1;
+       ce_complete.handler = &get_boot_rtc_time_complete;
+       ce_complete.token = &rtc_data;
+       rc = signal_ce_msg_simple(0x40, &ce_complete);
+       if (rc)
+               return rc;
+       /* We need to poll here as we are not yet taking interrupts */
+       while (rtc_data.busy) {
+               extern unsigned long lpevent_count;
+               struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
+               if (lpq && ItLpQueue_isLpIntPending(lpq))
+                       lpevent_count += ItLpQueue_process(lpq, NULL);
+       }
+       return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+}
+
 int mf_set_rtc(struct rtc_time *tm)
 {
        char ce_time[12];
index 90b41f48d21c05ba516a69db7e9dcab05396e08c..e3c73b3425dc016447d7e417f536d7a66fde39c4 100644 (file)
@@ -32,7 +32,7 @@
        .text
 
 /*
- * Returns (address we're running at) - (address we were linked at)
+ * Returns (address we were linked at) - (address we are running at)
  * for use before the text and data are mapped to KERNELBASE.
  */
 
@@ -792,7 +792,7 @@ _GLOBAL(sys_call_table32)
        .llong .compat_sys_newstat
        .llong .compat_sys_newlstat
        .llong .compat_sys_newfstat
-       .llong .sys_uname
+       .llong .sys32_uname
        .llong .sys_ni_syscall          /* 110 old iopl syscall */
        .llong .sys_vhangup
        .llong .sys_ni_syscall          /* old idle syscall */
index cb5443f2e49b81ba09b70966acf92fd5edcd6aa6..dc2a69d412a204820546107a47ab7c676036a7de 100644 (file)
@@ -47,14 +47,6 @@ static void remove_node_proc_entries(struct device_node *np)
                remove_proc_entry(pp->name, np->pde);
                pp = pp->next;
        }
-
-       /* Assuming that symlinks have the same parent directory as
-        * np->pde.
-        */
-       if (np->name_link)
-               remove_proc_entry(np->name_link->name, parent->pde);
-       if (np->addr_link)
-               remove_proc_entry(np->addr_link->name, parent->pde);
        if (np->pde)
                remove_proc_entry(np->pde->name, parent->pde);
 }
index c60d8cb2b84d21d57c46b6f07fed038c39da2d1c..fbad349ec58c2179fce3731d9ead5b8739cbc8c8 100644 (file)
@@ -326,13 +326,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
 
        cpu_clear(cpu, of_spin_map);
 
-       /*
-        * Put the calling processor into the GIQ.  This is really only
-        * necessary from a secondary thread as the OF start-cpu interface
-        * performs this function for us on primary threads.
-        */
-       rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
-               (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
 }
 
 static DEFINE_SPINLOCK(timebase_lock);
index be3cc387c1ec4bcb18dcac51dd0befef0c588558..d786d4b6af0b2a78403d4bb1325b9f2c2be414fe 100644 (file)
@@ -438,7 +438,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
        int i;
 
        if (page_is_ram(offset >> PAGE_SHIFT))
-               return prot;
+               return __pgprot(prot);
 
        prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
 
index c27588ede2fea38f3990f2104f1af4d37246de23..a23de37227bfcc9b81edc2839a6f817f58e61171 100644 (file)
@@ -68,6 +68,7 @@ extern struct smp_ops_t *smp_ops;
 
 static void (*pmac_tb_freeze)(int freeze);
 static struct device_node *pmac_tb_clock_chip_host;
+static u8 pmac_tb_pulsar_addr;
 static DEFINE_SPINLOCK(timebase_lock);
 static unsigned long timebase;
 
@@ -106,12 +107,9 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
        u8 data;
        int rc;
 
-       /* Strangely, the device-tree says address is 0xd2, but darwin
-        * accesses 0xd0 ...
-        */
        pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
        rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
-                              0xd4 | pmac_low_i2c_read,
+                              pmac_tb_pulsar_addr | pmac_low_i2c_read,
                               0x2e, &data, 1);
        if (rc != 0)
                goto bail;
@@ -120,7 +118,7 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
 
        pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
        rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
-                              0xd4 | pmac_low_i2c_write,
+                              pmac_tb_pulsar_addr | pmac_low_i2c_write,
                               0x2e, &data, 1);
  bail:
        if (rc != 0) {
@@ -185,6 +183,12 @@ static int __init smp_core99_probe(void)
        if (ncpus <= 1)
                return 1;
 
+       /* HW sync only on these platforms */
+       if (!machine_is_compatible("PowerMac7,2") &&
+           !machine_is_compatible("PowerMac7,3") &&
+           !machine_is_compatible("RackMac3,1"))
+               goto nohwsync;
+
        /* Look for the clock chip */
        for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
                struct device_node *p = of_get_parent(cc);
@@ -198,11 +202,18 @@ static int __init smp_core99_probe(void)
                        goto next;
                switch (*reg) {
                case 0xd2:
-                       pmac_tb_freeze = smp_core99_cypress_tb_freeze;
-                       printk(KERN_INFO "Timebase clock is Cypress chip\n");
+                       if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
+                               pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+                               pmac_tb_pulsar_addr = 0xd2;
+                               printk(KERN_INFO "Timebase clock is Pulsar chip\n");
+                       } else if (device_is_compatible(cc, "cy28508")) {
+                               pmac_tb_freeze = smp_core99_cypress_tb_freeze;
+                               printk(KERN_INFO "Timebase clock is Cypress chip\n");
+                       }
                        break;
                case 0xd4:
                        pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+                       pmac_tb_pulsar_addr = 0xd4;
                        printk(KERN_INFO "Timebase clock is Pulsar chip\n");
                        break;
                }
@@ -210,12 +221,15 @@ static int __init smp_core99_probe(void)
                        pmac_tb_clock_chip_host = p;
                        smp_ops->give_timebase = smp_core99_give_timebase;
                        smp_ops->take_timebase = smp_core99_take_timebase;
+                       of_node_put(cc);
+                       of_node_put(p);
                        break;
                }
        next:
                of_node_put(p);
        }
 
+ nohwsync:
        mpic_request_ipis();
 
        return ncpus;
index 8b06861227385709431ace73498417c448b10e5d..cdfecbeb331f58d586edd4b85aa58212f859d872 100644 (file)
@@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
                childregs->gpr[1] = sp + sizeof(struct pt_regs);
                p->thread.regs = NULL;  /* no user register state */
                clear_ti_thread_flag(p->thread_info, TIF_32BIT);
-#ifdef CONFIG_PPC_ISERIES
-               set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT);
-#endif
        } else {
                childregs->gpr[1] = usp;
                p->thread.regs = childregs;
index fe2946c5831457f4baa36e55a7e4a13c20c9b552..eb6538b58008b641f06cd7fab3ca815b4ae4ca3d 100644 (file)
@@ -834,7 +834,7 @@ void __init unflatten_device_tree(void)
 {
        unsigned long start, mem, size;
        struct device_node **allnextp = &allnodes;
-       char *p;
+       char *p = NULL;
        int l = 0;
 
        DBG(" -> unflatten_device_tree()\n");
index 35ec42de962e2f42d331e72f3a09cac678e6486a..b7683abfbe6a5f71e8031610ef8cb67dd14a07bd 100644 (file)
@@ -211,13 +211,23 @@ struct {
  */
 #define ADDR(x)                (u32) ((unsigned long)(x) - offset)
 
+/*
+ * Error results ... some OF calls will return "-1" on error, some
+ * will return 0, some will return either. To simplify, here are
+ * macros to use with any ihandle or phandle return value to check if
+ * it is valid
+ */
+
+#define PROM_ERROR             (-1u)
+#define PHANDLE_VALID(p)       ((p) != 0 && (p) != PROM_ERROR)
+#define IHANDLE_VALID(i)       ((i) != 0 && (i) != PROM_ERROR)
+
+
 /* This is the one and *ONLY* place where we actually call open
  * firmware from, since we need to make sure we're running in 32b
  * mode when we do.  We switch back to 64b mode upon return.
  */
 
-#define PROM_ERROR     (-1)
-
 static int __init call_prom(const char *service, int nargs, int nret, ...)
 {
        int i;
@@ -587,14 +597,13 @@ static void __init prom_send_capabilities(void)
 {
        unsigned long offset = reloc_offset();
        ihandle elfloader;
-       int ret;
 
        elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
        if (elfloader == 0) {
                prom_printf("couldn't open /packages/elf-loader\n");
                return;
        }
-       ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"),
+       call_prom("call-method", 3, 1, ADDR("process-elf-header"),
                        elfloader, ADDR(&fake_elf));
        call_prom("close", 1, 0, elfloader);
 }
@@ -646,7 +655,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align)
            base = _ALIGN_UP(base + 0x100000, align)) {
                prom_debug("    trying: 0x%x\n\r", base);
                addr = (unsigned long)prom_claim(base, size, 0);
-               if ((int)addr != PROM_ERROR)
+               if (addr != PROM_ERROR)
                        break;
                addr = 0;
                if (align == 0)
@@ -708,7 +717,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align,
        for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align))  {
                prom_debug("    trying: 0x%x\n\r", base);
                addr = (unsigned long)prom_claim(base, size, 0);
-               if ((int)addr != PROM_ERROR)
+               if (addr != PROM_ERROR)
                        break;
                addr = 0;
        }
@@ -902,18 +911,19 @@ static void __init prom_instantiate_rtas(void)
 {
        unsigned long offset = reloc_offset();
        struct prom_t *_prom = PTRRELOC(&prom);
-       phandle prom_rtas, rtas_node;
+       phandle rtas_node;
+       ihandle rtas_inst;
        u32 base, entry = 0;
        u32 size = 0;
 
        prom_debug("prom_instantiate_rtas: start...\n");
 
-       prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
-       prom_debug("prom_rtas: %x\n", prom_rtas);
-       if (prom_rtas == (phandle) -1)
+       rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
+       prom_debug("rtas_node: %x\n", rtas_node);
+       if (!PHANDLE_VALID(rtas_node))
                return;
 
-       prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size));
+       prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
        if (size == 0)
                return;
 
@@ -922,14 +932,18 @@ static void __init prom_instantiate_rtas(void)
                prom_printf("RTAS allocation failed !\n");
                return;
        }
-       prom_printf("instantiating rtas at 0x%x", base);
 
-       rtas_node = call_prom("open", 1, 1, ADDR("/rtas"));
-       prom_printf("...");
+       rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
+       if (!IHANDLE_VALID(rtas_inst)) {
+               prom_printf("opening rtas package failed");
+               return;
+       }
+
+       prom_printf("instantiating rtas at 0x%x ...", base);
 
        if (call_prom("call-method", 3, 2,
                      ADDR("instantiate-rtas"),
-                     rtas_node, base) != PROM_ERROR) {
+                     rtas_inst, base) != PROM_ERROR) {
                entry = (long)_prom->args.rets[1];
        }
        if (entry == 0) {
@@ -940,8 +954,8 @@ static void __init prom_instantiate_rtas(void)
 
        reserve_mem(base, size);
 
-       prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base));
-       prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry));
+       prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
+       prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
 
        prom_debug("rtas base     = 0x%x\n", base);
        prom_debug("rtas entry    = 0x%x\n", entry);
@@ -1062,7 +1076,7 @@ static void __init prom_initialize_tce_table(void)
 
                prom_printf("opening PHB %s", path);
                phb_node = call_prom("open", 1, 1, path);
-               if ( (long)phb_node <= 0)
+               if (phb_node == 0)
                        prom_printf("... failed\n");
                else
                        prom_printf("... done\n");
@@ -1279,12 +1293,12 @@ static void __init prom_init_client_services(unsigned long pp)
 
        /* get a handle for the stdout device */
        _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
-       if ((long)_prom->chosen <= 0)
+       if (!PHANDLE_VALID(_prom->chosen))
                prom_panic("cannot find chosen"); /* msg won't be printed :( */
 
        /* get device tree root */
        _prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
-       if ((long)_prom->root <= 0)
+       if (!PHANDLE_VALID(_prom->root))
                prom_panic("cannot find device tree root"); /* msg won't be printed :( */
 }
 
@@ -1356,9 +1370,8 @@ static int __init prom_find_machine_type(void)
        }
        /* Default to pSeries. We need to know if we are running LPAR */
        rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
-       if (rtas != (phandle) -1) {
-               unsigned long x;
-               x = prom_getproplen(rtas, "ibm,hypertas-functions");
+       if (PHANDLE_VALID(rtas)) {
+               int x = prom_getproplen(rtas, "ibm,hypertas-functions");
                if (x != PROM_ERROR) {
                        prom_printf("Hypertas detected, assuming LPAR !\n");
                        return PLATFORM_PSERIES_LPAR;
@@ -1426,12 +1439,13 @@ static void __init prom_check_displays(void)
                 * leave some room at the end of the path for appending extra
                 * arguments
                 */
-               if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0)
+               if (call_prom("package-to-path", 3, 1, node, path,
+                             PROM_SCRATCH_SIZE-10) == PROM_ERROR)
                        continue;
                prom_printf("found display   : %s, opening ... ", path);
                
                ih = call_prom("open", 1, 1, path);
-               if (ih == (ihandle)0 || ih == (ihandle)-1) {
+               if (ih == 0) {
                        prom_printf("failed\n");
                        continue;
                }
@@ -1514,6 +1528,12 @@ static unsigned long __init dt_find_string(char *str)
        return 0;
 }
 
+/*
+ * The Open Firmware 1275 specification states properties must be 31 bytes or
+ * less, however not all firmwares obey this. Make it 64 bytes to be safe.
+ */
+#define MAX_PROPERTY_NAME 64
+
 static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
                                         unsigned long *mem_end)
 {
@@ -1527,10 +1547,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
        /* get and store all property names */
        prev_name = RELOC("");
        for (;;) {
-               
-               /* 32 is max len of name including nul. */
-               namep = make_room(mem_start, mem_end, 32, 1);
-               if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) {
+               int rc;
+
+               /* 64 is max len of name including nul. */
+               namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
+               rc = call_prom("nextprop", 3, 1, node, prev_name, namep);
+               if (rc != 1) {
                        /* No more nodes: unwind alloc */
                        *mem_start = (unsigned long)namep;
                        break;
@@ -1555,18 +1577,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
        }
 }
 
-/*
- * The Open Firmware 1275 specification states properties must be 31 bytes or
- * less, however not all firmwares obey this. Make it 64 bytes to be safe.
- */
-#define MAX_PROPERTY_NAME 64
-
 static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
                                        unsigned long *mem_end)
 {
        int l, align;
        phandle child;
-       char *namep, *prev_name, *sstart;
+       char *namep, *prev_name, *sstart, *p, *ep;
        unsigned long soff;
        unsigned char *valp;
        unsigned long offset = reloc_offset();
@@ -1588,6 +1604,14 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
                        call_prom("package-to-path", 3, 1, node, namep, l);
                }
                namep[l] = '\0';
+               /* Fixup an Apple bug where they have bogus \0 chars in the
+                * middle of the path in some properties
+                */
+               for (p = namep, ep = namep + l; p < ep; p++)
+                       if (*p == '\0') {
+                               memmove(p, p+1, ep - p);
+                               ep--; l--;
+                       }
                *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4);
        }
 
@@ -1599,7 +1623,10 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
        prev_name = RELOC("");
        sstart = (char *)RELOC(dt_string_start);
        for (;;) {
-               if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0)
+               int rc;
+
+               rc = call_prom("nextprop", 3, 1, node, prev_name, pname);
+               if (rc != 1)
                        break;
 
                /* find string offset */
@@ -1615,7 +1642,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
                l = call_prom("getproplen", 2, 1, node, pname);
 
                /* sanity checks */
-               if (l < 0)
+               if (l == PROM_ERROR)
                        continue;
                if (l > MAX_PROPERTY_LENGTH) {
                        prom_printf("WARNING: ignoring large property ");
@@ -1750,7 +1777,45 @@ static void __init flatten_device_tree(void)
        prom_printf("Device tree struct  0x%x -> 0x%x\n",
                    RELOC(dt_struct_start), RELOC(dt_struct_end));
 
- }
+}
+
+
+static void __init fixup_device_tree(void)
+{
+       unsigned long offset = reloc_offset();
+       phandle u3, i2c, mpic;
+       u32 u3_rev;
+       u32 interrupts[2];
+       u32 parent;
+
+       /* Some G5s have a missing interrupt definition, fix it up here */
+       u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
+       if (!PHANDLE_VALID(u3))
+               return;
+       i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
+       if (!PHANDLE_VALID(i2c))
+               return;
+       mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
+       if (!PHANDLE_VALID(mpic))
+               return;
+
+       /* check if proper rev of u3 */
+       if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
+           == PROM_ERROR)
+               return;
+       if (u3_rev != 0x35)
+               return;
+       /* does it need fixup ? */
+       if (prom_getproplen(i2c, "interrupts") > 0)
+               return;
+       /* interrupt on this revision of u3 is number 0 and level */
+       interrupts[0] = 0;
+       interrupts[1] = 1;
+       prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
+       parent = (u32)mpic;
+       prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
+}
+
 
 static void __init prom_find_boot_cpu(void)
 {
@@ -1843,6 +1908,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
        prom_setprop(_prom->chosen, "linux,platform",
                     &getprop_rval, sizeof(getprop_rval));
 
+       /*
+        * On pSeries, inform the firmware about our capabilities
+        */
+       if (RELOC(of_platform) & PLATFORM_PSERIES)
+               prom_send_capabilities();
+
        /*
         * On pSeries, copy the CPU hold code
         */
@@ -1919,6 +1990,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
                        PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
        }
 
+       /*
+        * Fixup any known bugs in the device-tree
+        */
+       fixup_device_tree();
+
        /*
         * Now finally create the flattened device-tree
         */
index 5a846324ca8cc981cfa3fd2d9bf566ab21858ebb..9f8c6087ae568aaa9a7a2dd999ce65d3ea9828b9 100644 (file)
@@ -305,14 +305,17 @@ static void do_syscall_trace(void)
 
 void do_syscall_trace_enter(struct pt_regs *regs)
 {
+       if (test_thread_flag(TIF_SYSCALL_TRACE)
+           && (current->ptrace & PT_PTRACED))
+               do_syscall_trace();
+
        if (unlikely(current->audit_context))
-               audit_syscall_entry(current, regs->gpr[0],
+               audit_syscall_entry(current,
+                                   test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
+                                   regs->gpr[0],
                                    regs->gpr[3], regs->gpr[4],
                                    regs->gpr[5], regs->gpr[6]);
 
-       if (test_thread_flag(TIF_SYSCALL_TRACE)
-           && (current->ptrace & PT_PTRACED))
-               do_syscall_trace();
 }
 
 void do_syscall_trace_leave(struct pt_regs *regs)
@@ -320,7 +323,9 @@ void do_syscall_trace_leave(struct pt_regs *regs)
        secure_computing(regs->gpr[0]);
 
        if (unlikely(current->audit_context))
-               audit_syscall_exit(current, regs->result);
+               audit_syscall_exit(current, 
+                                  (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+                                  regs->result);
 
        if ((test_thread_flag(TIF_SYSCALL_TRACE)
             || test_thread_flag(TIF_SINGLESTEP))
index 3e70b91375fcb808464c190b5e39e1dc72ed9d15..67989055a9fee0b50d9f1b1928183bb66a02be4e 100644 (file)
@@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm)
 
 void iSeries_get_boot_time(struct rtc_time *tm)
 {
-       unsigned long time;
-       static unsigned long lastsec = 1;
-
-       u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
-       u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
-       int year = 1970;
-       int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
-       int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
-       int sec = ( dataWord1 >> 8 ) & 0x000000FF;
-       int min = dataWord1 & 0x000000FF;
-       int hour = ( dataWord2 >> 24 ) & 0x000000FF;
-       int day = ( dataWord2 >> 8 ) & 0x000000FF;
-       int mon = dataWord2 & 0x000000FF;
-
        if ( piranha_simulator )
                return;
 
-       BCD_TO_BIN(sec);
-       BCD_TO_BIN(min);
-       BCD_TO_BIN(hour);
-       BCD_TO_BIN(day);
-       BCD_TO_BIN(mon);
-       BCD_TO_BIN(year1);
-       BCD_TO_BIN(year2);
-       year = year1 * 100 + year2;
-
-       time = mktime(year, mon, day, hour, min, sec);
-       time += ( jiffies / HZ );
-
-       /* Now THIS is a nasty hack!
-       * It ensures that the first two calls get different answers.  
-       * That way the loop in init_time (time.c) will not think
-       * the clock is stuck.
-       */
-       if ( lastsec ) {
-               time -= lastsec;
-               --lastsec;
-       }
-
-       to_tm(time, tm); 
-       tm->tm_year -= 1900;
+       mf_get_boot_rtc(tm);
        tm->tm_mon  -= 1;
 }
 #endif
index 21c57f539c29305b1bf7ecef8c8a7a5b72a33046..dce198d39328aefd6541efef430f6a6e71d9ca4f 100644 (file)
@@ -103,11 +103,6 @@ extern void unflatten_device_tree(void);
 
 extern void smp_release_cpus(void);
 
-unsigned long decr_overclock = 1;
-unsigned long decr_overclock_proc0 = 1;
-unsigned long decr_overclock_set = 0;
-unsigned long decr_overclock_proc0_set = 0;
-
 int have_of = 1;
 int boot_cpuid = 0;
 int boot_cpuid_phys = 0;
@@ -1120,64 +1115,15 @@ void ppc64_dump_msg(unsigned int src, const char *msg)
        printk("[dump]%04x %s\n", src, msg);
 }
 
-int set_spread_lpevents( char * str )
-{
-       /* The parameter is the number of processors to share in processing lp events */
-       unsigned long i;
-       unsigned long val = simple_strtoul( str, NULL, 0 );
-       if ( ( val > 0 ) && ( val <= NR_CPUS ) ) {
-               for ( i=1; i<val; ++i )
-                       paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
-               printk("lpevent processing spread over %ld processors\n", val);
-       }
-       else
-               printk("invalid spreaqd_lpevents %ld\n", val);
-       return 1;
-}      
-
 /* This should only be called on processor 0 during calibrate decr */
 void setup_default_decr(void)
 {
        struct paca_struct *lpaca = get_paca();
 
-       if ( decr_overclock_set && !decr_overclock_proc0_set )
-               decr_overclock_proc0 = decr_overclock;
-
-       lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0;        
+       lpaca->default_decr = tb_ticks_per_jiffy;
        lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
 }
 
-int set_decr_overclock_proc0( char * str )
-{
-       unsigned long val = simple_strtoul( str, NULL, 0 );
-       if ( ( val >= 1 ) && ( val <= 48 ) ) {
-               decr_overclock_proc0_set = 1;
-               decr_overclock_proc0 = val;
-               printk("proc 0 decrementer overclock factor of %ld\n", val);
-       }
-       else
-               printk("invalid proc 0 decrementer overclock factor of %ld\n", val);
-       return 1;
-}
-
-int set_decr_overclock( char * str )
-{
-       unsigned long val = simple_strtoul( str, NULL, 0 );
-       if ( ( val >= 1 ) && ( val <= 48 ) ) {
-               decr_overclock_set = 1;
-               decr_overclock = val;
-               printk("decrementer overclock factor of %ld\n", val);
-       }
-       else
-               printk("invalid decrementer overclock factor of %ld\n", val);
-       return 1;
-
-}
-
-__setup("spread_lpevents=", set_spread_lpevents );
-__setup("decr_overclock_proc0=", set_decr_overclock_proc0 );
-__setup("decr_overclock=", set_decr_overclock );
-
 #ifndef CONFIG_PPC_ISERIES
 /*
  * This function can be used by platforms to "find" legacy serial ports.
index a95a2b49a1d56359237d15e8b76f5d531023f14c..bf782276984c69147411c7aa5f513ab4cc545cda 100644 (file)
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-#ifndef MIN
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#define GP_REGS_SIZE   MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
+#define GP_REGS_SIZE   min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
 #define FP_REGS_SIZE   sizeof(elf_fpregset_t)
 
 #define TRAMP_TRACEBACK        3
index 3b906cd940378086b84d18f2d0b71c70a33308cc..9ef5d36d6b253d38127cc026554e2d0e698f87d5 100644 (file)
@@ -334,7 +334,6 @@ void smp_call_function_interrupt(void)
        }
 }
 
-extern unsigned long decr_overclock;
 extern struct gettimeofday_struct do_gtod;
 
 struct thread_info *current_set[NR_CPUS];
@@ -491,7 +490,7 @@ int __devinit __cpu_up(unsigned int cpu)
        if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))
                return -EINVAL;
 
-       paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock;
+       paca[cpu].default_decr = tb_ticks_per_jiffy;
 
        if (!cpu_has_feature(CPU_FTR_SLB)) {
                void *tmp;
index 7cf7a9600025bdfeb793fbb43dbb2b11c22ea743..9c8e317c598d0ed40e6fcd61c41d61abcd847a98 100644 (file)
@@ -791,31 +791,6 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
 }
 
 
-asmlinkage int ppc64_newuname(struct new_utsname __user * name)
-{
-       int errno = sys_newuname(name);
-
-       if (current->personality == PER_LINUX32 && !errno) {
-               if(copy_to_user(name->machine, "ppc\0\0", 8)) {
-                       errno = -EFAULT;
-               }
-       }
-       return errno;
-}
-
-asmlinkage int ppc64_personality(unsigned long personality)
-{
-       int ret;
-       if (current->personality == PER_LINUX32 && personality == PER_LINUX)
-               personality = PER_LINUX32;
-       ret = sys_personality(personality);
-       if (ret == PER_LINUX32)
-               ret = PER_LINUX;
-       return ret;
-}
-
-
-
 /* Note: it is necessary to treat mode as an unsigned int,
  * with the corresponding cast to a signed int to insure that the 
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -1158,26 +1133,47 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
 }
 #endif
 
+asmlinkage int sys32_uname(struct old_utsname __user * name)
+{
+       int err = 0;
+       
+       down_read(&uts_sem);
+       if (copy_to_user(name, &system_utsname, sizeof(*name)))
+               err = -EFAULT;
+       up_read(&uts_sem);
+       if (!err && personality(current->personality) == PER_LINUX32) {
+               /* change "ppc64" to "ppc" */
+               if (__put_user(0, name->machine + 3)
+                   || __put_user(0, name->machine + 4))
+                       err = -EFAULT;
+       }
+       return err;
+}
+
 asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
 {
        int error;
-       
-       if (!name)
-               return -EFAULT;
+
        if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
                return -EFAULT;
   
        down_read(&uts_sem);
        error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
-       error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
-       error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
-       error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
-       error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
-       error -= __put_user(0,name->release+__OLD_UTS_LEN);
-       error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
-       error -= __put_user(0,name->version+__OLD_UTS_LEN);
-       error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
-       error = __put_user(0,name->machine+__OLD_UTS_LEN);
+       error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
+       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+       error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
+       error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+       error |= __put_user(0,name->release+__OLD_UTS_LEN);
+       error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+       error |= __put_user(0,name->version+__OLD_UTS_LEN);
+       error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+       error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+       if (personality(current->personality) == PER_LINUX32) {
+               /* change "ppc64" to "ppc" */
+               error |= __put_user(0, name->machine + 3);
+               error |= __put_user(0, name->machine + 4);
+       }
+       
        up_read(&uts_sem);
 
        error = error ? -EFAULT : 0;
index f2865ff8d2f93863c1d8eb4416f02a82e9a68ad2..a8cbb202b8cd482f8deb05e68287341600c44637 100644 (file)
@@ -199,24 +199,33 @@ out:
        return ret;
 }
 
-static int __init set_fakeppc(char *str)
+long ppc64_personality(unsigned long personality)
 {
-       if (*str)
-               return 0;
-       init_task.personality = PER_LINUX32;
-       return 1;
+       long ret;
+
+       if (personality(current->personality) == PER_LINUX32
+           && personality == PER_LINUX)
+               personality = PER_LINUX32;
+       ret = sys_personality(personality);
+       if (ret == PER_LINUX32)
+               ret = PER_LINUX;
+       return ret;
 }
-__setup("fakeppc", set_fakeppc);
 
-asmlinkage int sys_uname(struct old_utsname __user * name)
+long ppc64_newuname(struct new_utsname __user * name)
 {
-       int err = -EFAULT;
-       
+       int err = 0;
+
        down_read(&uts_sem);
-       if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
-               err = 0;
+       if (copy_to_user(name, &system_utsname, sizeof(*name)))
+               err = -EFAULT;
        up_read(&uts_sem);
-       
+       if (!err && personality(current->personality) == PER_LINUX32) {
+               /* change ppc64 to ppc */
+               if (__put_user(0, name->machine + 3)
+                   || __put_user(0, name->machine + 4))
+                       err = -EFAULT;
+       }
        return err;
 }
 
index 0925694c3ce5e7873438ae300075a80d648e7657..c8fa6569b2fd789fc3476a3c5ab86c3bf6b3c203 100644 (file)
@@ -113,7 +113,6 @@ void ppc64_enable_pmcs(void)
 #ifdef CONFIG_PPC_PSERIES
        unsigned long set, reset;
        int ret;
-       unsigned int ctrl;
 #endif /* CONFIG_PPC_PSERIES */
 
        /* Only need to enable them once */
@@ -167,11 +166,8 @@ void ppc64_enable_pmcs(void)
         * On SMT machines we have to set the run latch in the ctrl register
         * in order to make PMC6 spin.
         */
-       if (cpu_has_feature(CPU_FTR_SMT)) {
-               ctrl = mfspr(CTRLF);
-               ctrl |= RUNLATCH;
-               mtspr(CTRLT, ctrl);
-       }
+       if (cpu_has_feature(CPU_FTR_SMT))
+               ppc64_runlatch_on();
 #endif /* CONFIG_PPC_PSERIES */
 }
 
index 772a465b49f9c2d65636e71d27b7f4ca70f6c17f..33364a7d2cd2e07dbcdd8567d669da11439b5038 100644 (file)
@@ -325,9 +325,7 @@ int timer_interrupt(struct pt_regs * regs)
 
        irq_enter();
 
-#ifndef CONFIG_PPC_ISERIES
        profile_tick(CPU_PROFILING, regs);
-#endif
 
        lpaca->lppaca.int_dword.fields.decr_int = 0;
 
@@ -515,6 +513,7 @@ void __init time_init(void)
        do_gtod.varp = &do_gtod.vars[0];
        do_gtod.var_idx = 0;
        do_gtod.varp->tb_orig_stamp = tb_last_stamp;
+       get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
        do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
        do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
        do_gtod.varp->tb_to_xs = tb_to_xs;
index eedd1d3c2a10a30891278b1fd7b51faf1a5743d3..879f39b90a337df2b63a88d5399fcf4971da36e7 100644 (file)
@@ -432,6 +432,7 @@ void xics_cause_IPI(int cpu)
 {
        ops->qirr_info(cpu, IPI_PRIORITY);
 }
+#endif /* CONFIG_SMP */
 
 void xics_setup_cpu(void)
 {
@@ -439,9 +440,17 @@ void xics_setup_cpu(void)
 
        ops->cppr_info(cpu, 0xff);
        iosync();
-}
 
-#endif /* CONFIG_SMP */
+       /*
+        * Put the calling processor into the GIQ.  This is really only
+        * necessary from a secondary thread as the OF start-cpu interface
+        * performs this function for us on primary threads.
+        *
+        * XXX: undo of teardown on kexec needs this too, as may hotplug
+        */
+       rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+               (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
+}
 
 void xics_init_IRQ(void)
 {
@@ -563,8 +572,7 @@ nextnode:
        for (; i < NR_IRQS; ++i)
                get_irq_desc(i)->handler = &xics_pic;
 
-       ops->cppr_info(boot_cpuid, 0xff);
-       iosync();
+       xics_setup_cpu();
 
        ppc64_boot_msg(0x21, "XICS Done");
 }
index 144657e0c3d558d573d08ebcff8d9586099c1e33..52b6b9305341e3774b94bba7bca216cbd6ce3bd0 100644 (file)
@@ -320,8 +320,7 @@ static void native_flush_hash_range(unsigned long context,
 
        j = 0;
        for (i = 0; i < number; i++) {
-               if ((batch->addr[i] >= USER_START) &&
-                   (batch->addr[i] <= USER_END))
+               if (batch->addr[i] < KERNELBASE)
                        vsid = get_vsid(context, batch->addr[i]);
                else
                        vsid = get_kernel_vsid(batch->addr[i]);
index e48be12f518c48c9e5f29b9f76bd23225eedf739..0a0f97008d02bc383e2b45aaf10cab443dea9561 100644 (file)
@@ -298,24 +298,23 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
        int local = 0;
        cpumask_t tmp;
 
+       if ((ea & ~REGION_MASK) > EADDR_MASK)
+               return 1;
+
        switch (REGION_ID(ea)) {
        case USER_REGION_ID:
                user_region = 1;
                mm = current->mm;
-               if ((ea > USER_END) || (! mm))
+               if (! mm)
                        return 1;
 
                vsid = get_vsid(mm->context.id, ea);
                break;
        case IO_REGION_ID:
-               if (ea > IMALLOC_END)
-                       return 1;
                mm = &ioremap_mm;
                vsid = get_kernel_vsid(ea);
                break;
        case VMALLOC_REGION_ID:
-               if (ea > VMALLOC_END)
-                       return 1;
                mm = &init_mm;
                vsid = get_kernel_vsid(ea);
                break;
@@ -362,7 +361,7 @@ void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
        unsigned long vsid, vpn, va, hash, secondary, slot;
        unsigned long huge = pte_huge(pte);
 
-       if ((ea >= USER_START) && (ea <= USER_END))
+       if (ea < KERNELBASE)
                vsid = get_vsid(context, ea);
        else
                vsid = get_kernel_vsid(ea);
index 9d92b0d9cde5dd8e62e68859a41c069b2cb919dd..cb8727f3267a1c252b1f4d3d7fe1e498a210d3b4 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/semaphore.h>
+#include <asm/imalloc.h>
 
 static DECLARE_MUTEX(imlist_sem);
 struct vm_struct * imlist = NULL;
@@ -23,11 +24,11 @@ static int get_free_im_addr(unsigned long size, unsigned long *im_addr)
        unsigned long addr;
        struct vm_struct **p, *tmp;
 
-       addr = IMALLOC_START;
+       addr = ioremap_bot;
        for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
                if (size + addr < (unsigned long) tmp->addr)
                        break;
-               if ((unsigned long)tmp->addr >= IMALLOC_START) 
+               if ((unsigned long)tmp->addr >= ioremap_bot)
                        addr = tmp->size + (unsigned long) tmp->addr;
                if (addr > IMALLOC_END-size) 
                        return 1;
index cf33d7ec2e2936d0770064215042e7195e2c7a2e..4b42aff74d7312e7f2cdad4aa58dcdaa13a04e1b 100644 (file)
@@ -64,6 +64,7 @@
 #include <asm/iommu.h>
 #include <asm/abs_addr.h>
 #include <asm/vdso.h>
+#include <asm/imalloc.h>
 
 int mem_init_done;
 unsigned long ioremap_bot = IMALLOC_BASE;
@@ -668,7 +669,7 @@ void __init paging_init(void)
        zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
        zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
 
-       free_area_init_node(0, &contig_page_data, zones_size,
+       free_area_init_node(0, NODE_DATA(0), zones_size,
                            __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
 }
 #endif /* CONFIG_DISCONTIGMEM */
index 31491131d5e4ace3cdd06f2a350ddbf31780a608..df4bbe14153c9af9200368add9a0c48999096242 100644 (file)
 #include <asm/paca.h>
 #include <asm/cputable.h>
 
+struct stab_entry {
+       unsigned long esid_data;
+       unsigned long vsid_data;
+};
+
 /* Both the segment table and SLB code uses the following cache */
 #define NR_STAB_CACHE_ENTRIES 8
 DEFINE_PER_CPU(long, stab_cache_ptr);
index 01ae1964c938cd828379dc594087299309531725..c067435bae4506130b9dd05cbf4e6a30078000a1 100644 (file)
@@ -28,6 +28,7 @@
 //#include <linux/kernel_stat.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
+#include <linux/workqueue.h>
 
 #include "appldata.h"
 
@@ -133,9 +134,12 @@ static int appldata_interval = APPLDATA_CPU_INTERVAL;
 static int appldata_timer_active;
 
 /*
- * Tasklet
+ * Work queue
  */
-static struct tasklet_struct appldata_tasklet_struct;
+static struct workqueue_struct *appldata_wq;
+static void appldata_work_fn(void *data);
+static DECLARE_WORK(appldata_work, appldata_work_fn, NULL);
+
 
 /*
  * Ops list
@@ -144,11 +148,11 @@ static DEFINE_SPINLOCK(appldata_ops_lock);
 static LIST_HEAD(appldata_ops_list);
 
 
-/************************* timer, tasklet, DIAG ******************************/
+/*************************** timer, work, DIAG *******************************/
 /*
  * appldata_timer_function()
  *
- * schedule tasklet and reschedule timer
+ * schedule work and reschedule timer
  */
 static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
 {
@@ -157,22 +161,22 @@ static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
                atomic_read(&appldata_expire_count));
        if (atomic_dec_and_test(&appldata_expire_count)) {
                atomic_set(&appldata_expire_count, num_online_cpus());
-               tasklet_schedule((struct tasklet_struct *) data);
+               queue_work(appldata_wq, (struct work_struct *) data);
        }
 }
 
 /*
- * appldata_tasklet_function()
+ * appldata_work_fn()
  *
  * call data gathering function for each (active) module
  */
-static void appldata_tasklet_function(unsigned long data)
+static void appldata_work_fn(void *data)
 {
        struct list_head *lh;
        struct appldata_ops *ops;
        int i;
 
-       P_DEBUG("  -= Tasklet =-\n");
+       P_DEBUG("  -= Work Queue =-\n");
        i = 0;
        spin_lock(&appldata_ops_lock);
        list_for_each(lh, &appldata_ops_list) {
@@ -231,7 +235,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer,
                        : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc");
        return (int) ry;
 }
-/********************** timer, tasklet, DIAG <END> ***************************/
+/************************ timer, work, DIAG <END> ****************************/
 
 
 /****************************** /proc stuff **********************************/
@@ -411,7 +415,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
        struct list_head *lh;
 
        found = 0;
-       spin_lock_bh(&appldata_ops_lock);
+       spin_lock(&appldata_ops_lock);
        list_for_each(lh, &appldata_ops_list) {
                tmp_ops = list_entry(lh, struct appldata_ops, list);
                if (&tmp_ops->ctl_table[2] == ctl) {
@@ -419,15 +423,15 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
                }
        }
        if (!found) {
-               spin_unlock_bh(&appldata_ops_lock);
+               spin_unlock(&appldata_ops_lock);
                return -ENODEV;
        }
        ops = ctl->data;
        if (!try_module_get(ops->owner)) {      // protect this function
-               spin_unlock_bh(&appldata_ops_lock);
+               spin_unlock(&appldata_ops_lock);
                return -ENODEV;
        }
-       spin_unlock_bh(&appldata_ops_lock);
+       spin_unlock(&appldata_ops_lock);
 
        if (!*lenp || *ppos) {
                *lenp = 0;
@@ -451,10 +455,11 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
                return -EFAULT;
        }
 
-       spin_lock_bh(&appldata_ops_lock);
+       spin_lock(&appldata_ops_lock);
        if ((buf[0] == '1') && (ops->active == 0)) {
-               if (!try_module_get(ops->owner)) {      // protect tasklet
-                       spin_unlock_bh(&appldata_ops_lock);
+               // protect work queue callback
+               if (!try_module_get(ops->owner)) {
+                       spin_unlock(&appldata_ops_lock);
                        module_put(ops->owner);
                        return -ENODEV;
                }
@@ -485,7 +490,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
                }
                module_put(ops->owner);
        }
-       spin_unlock_bh(&appldata_ops_lock);
+       spin_unlock(&appldata_ops_lock);
 out:
        *lenp = len;
        *ppos += len;
@@ -529,7 +534,7 @@ int appldata_register_ops(struct appldata_ops *ops)
        }
        memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table));
 
-       spin_lock_bh(&appldata_ops_lock);
+       spin_lock(&appldata_ops_lock);
        list_for_each(lh, &appldata_ops_list) {
                tmp_ops = list_entry(lh, struct appldata_ops, list);
                P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",
@@ -541,18 +546,18 @@ int appldata_register_ops(struct appldata_ops *ops)
                                APPLDATA_PROC_NAME_LENGTH) == 0) {
                        P_ERROR("Name \"%s\" already registered!\n", ops->name);
                        kfree(ops->ctl_table);
-                       spin_unlock_bh(&appldata_ops_lock);
+                       spin_unlock(&appldata_ops_lock);
                        return -EBUSY;
                }
                if (tmp_ops->ctl_nr == ops->ctl_nr) {
                        P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);
                        kfree(ops->ctl_table);
-                       spin_unlock_bh(&appldata_ops_lock);
+                       spin_unlock(&appldata_ops_lock);
                        return -EBUSY;
                }
        }
        list_add(&ops->list, &appldata_ops_list);
-       spin_unlock_bh(&appldata_ops_lock);
+       spin_unlock(&appldata_ops_lock);
 
        ops->ctl_table[0].ctl_name = CTL_APPLDATA;
        ops->ctl_table[0].procname = appldata_proc_name;
@@ -583,12 +588,12 @@ int appldata_register_ops(struct appldata_ops *ops)
  */
 void appldata_unregister_ops(struct appldata_ops *ops)
 {
-       spin_lock_bh(&appldata_ops_lock);
+       spin_lock(&appldata_ops_lock);
        unregister_sysctl_table(ops->sysctl_header);
        list_del(&ops->list);
        kfree(ops->ctl_table);
        ops->ctl_table = NULL;
-       spin_unlock_bh(&appldata_ops_lock);
+       spin_unlock(&appldata_ops_lock);
        P_INFO("%s-ops unregistered!\n", ops->name);
 }
 /********************** module-ops management <END> **************************/
@@ -602,7 +607,7 @@ appldata_online_cpu(int cpu)
        init_virt_timer(&per_cpu(appldata_timer, cpu));
        per_cpu(appldata_timer, cpu).function = appldata_timer_function;
        per_cpu(appldata_timer, cpu).data = (unsigned long)
-               &appldata_tasklet_struct;
+               &appldata_work;
        atomic_inc(&appldata_expire_count);
        spin_lock(&appldata_timer_lock);
        __appldata_vtimer_setup(APPLDATA_MOD_TIMER);
@@ -615,7 +620,7 @@ appldata_offline_cpu(int cpu)
        del_virt_timer(&per_cpu(appldata_timer, cpu));
        if (atomic_dec_and_test(&appldata_expire_count)) {
                atomic_set(&appldata_expire_count, num_online_cpus());
-               tasklet_schedule(&appldata_tasklet_struct);
+               queue_work(appldata_wq, &appldata_work);
        }
        spin_lock(&appldata_timer_lock);
        __appldata_vtimer_setup(APPLDATA_MOD_TIMER);
@@ -648,7 +653,7 @@ static struct notifier_block __devinitdata appldata_nb = {
 /*
  * appldata_init()
  *
- * init timer and tasklet, register /proc entries
+ * init timer, register /proc entries
  */
 static int __init appldata_init(void)
 {
@@ -657,6 +662,12 @@ static int __init appldata_init(void)
        P_DEBUG("sizeof(parameter_list) = %lu\n",
                sizeof(struct appldata_parameter_list));
 
+       appldata_wq = create_singlethread_workqueue("appldata");
+       if (!appldata_wq) {
+               P_ERROR("Could not create work queue\n");
+               return -ENOMEM;
+       }
+
        for_each_online_cpu(i)
                appldata_online_cpu(i);
 
@@ -670,7 +681,6 @@ static int __init appldata_init(void)
        appldata_table[1].de->owner = THIS_MODULE;
 #endif
 
-       tasklet_init(&appldata_tasklet_struct, appldata_tasklet_function, 0);
        P_DEBUG("Base interface initialized.\n");
        return 0;
 }
@@ -678,7 +688,7 @@ static int __init appldata_init(void)
 /*
  * appldata_exit()
  *
- * stop timer and tasklet, unregister /proc entries
+ * stop timer, unregister /proc entries
  */
 static void __exit appldata_exit(void)
 {
@@ -690,7 +700,7 @@ static void __exit appldata_exit(void)
        /*
         * ops list should be empty, but just in case something went wrong...
         */
-       spin_lock_bh(&appldata_ops_lock);
+       spin_lock(&appldata_ops_lock);
        list_for_each(lh, &appldata_ops_list) {
                ops = list_entry(lh, struct appldata_ops, list);
                rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,
@@ -700,7 +710,7 @@ static void __exit appldata_exit(void)
                                "return code: %d\n", ops->name, rc);
                }
        }
-       spin_unlock_bh(&appldata_ops_lock);
+       spin_unlock(&appldata_ops_lock);
 
        for_each_online_cpu(i)
                appldata_offline_cpu(i);
@@ -709,7 +719,7 @@ static void __exit appldata_exit(void)
 
        unregister_sysctl_table(appldata_sysctl_header);
 
-       tasklet_kill(&appldata_tasklet_struct);
+       destroy_workqueue(appldata_wq);
        P_DEBUG("... module unloaded!\n");
 }
 /**************************** init / exit <END> ******************************/
index 462ee9a84e7655fb39403fdcc4ff2ba83e33823b..f0e2fbed3d4cf86a8000ec212e435546098507fc 100644 (file)
@@ -68,7 +68,7 @@ struct appldata_mem_data {
        u64 pgmajfault;         /* page faults (major only) */
 // <-- New in 2.6
 
-} appldata_mem_data;
+} __attribute__((packed)) appldata_mem_data;
 
 
 static inline void appldata_debug_print(struct appldata_mem_data *mem_data)
index dd61638d3027c6eddcaa0bf8bfd5e1d8d2477541..2a4c7432db4ac2960cde34ee6033671fe171cfc5 100644 (file)
@@ -57,7 +57,7 @@ struct appldata_net_sum_data {
        u64 rx_dropped;         /* no space in linux buffers     */
        u64 tx_dropped;         /* no space available in linux   */
        u64 collisions;         /* collisions while transmitting */
-} appldata_net_sum_data;
+} __attribute__((packed)) appldata_net_sum_data;
 
 
 static inline void appldata_print_debug(struct appldata_net_sum_data *net_data)
index b83f074845514ad409f8c5da3e57cf3a2c2b8459..e0a476bf4fd644691bf5b50e93db05a2367b59bd 100644 (file)
@@ -49,7 +49,7 @@ struct appldata_os_per_cpu {
        u32 per_cpu_softirq;    /* ... spent in softirqs            */
        u32 per_cpu_iowait;     /* ... spent while waiting for I/O  */
 // <-- New in 2.6
-};
+} __attribute__((packed));
 
 struct appldata_os_data {
        u64 timestamp;
@@ -75,7 +75,7 @@ struct appldata_os_data {
 
        /* per cpu data */
        struct appldata_os_per_cpu os_cpu[0];
-};
+} __attribute__((packed));
 
 static struct appldata_os_data *appldata_os_data;
 
index 9f0d73e3f5f727ddbdffe498fcccb65acb48bc8e..06afa3103ace75143d44258c215cc9c3d1a7fb00 100644 (file)
@@ -40,6 +40,7 @@
 #include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/unistd.h>
 
 #ifdef CONFIG_S390_SUPPORT
 #include "compat_ptrace.h"
@@ -130,13 +131,19 @@ static int
 peek_user(struct task_struct *child, addr_t addr, addr_t data)
 {
        struct user *dummy = NULL;
-       addr_t offset, tmp;
+       addr_t offset, tmp, mask;
 
        /*
         * Stupid gdb peeks/pokes the access registers in 64 bit with
         * an alignment of 4. Programmers from hell...
         */
-       if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK)
+       mask = __ADDR_MASK;
+#ifdef CONFIG_ARCH_S390X
+       if (addr >= (addr_t) &dummy->regs.acrs &&
+           addr < (addr_t) &dummy->regs.orig_gpr2)
+               mask = 3;
+#endif
+       if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
                return -EIO;
 
        if (addr < (addr_t) &dummy->regs.acrs) {
@@ -153,6 +160,16 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
                 * access registers are stored in the thread structure
                 */
                offset = addr - (addr_t) &dummy->regs.acrs;
+#ifdef CONFIG_ARCH_S390X
+               /*
+                * Very special case: old & broken 64 bit gdb reading
+                * from acrs[15]. Result is a 64 bit value. Read the
+                * 32 bit acrs[15] value and shift it by 32. Sick...
+                */
+               if (addr == (addr_t) &dummy->regs.acrs[15])
+                       tmp = ((unsigned long) child->thread.acrs[15]) << 32;
+               else
+#endif
                tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset);
 
        } else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
@@ -167,6 +184,9 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
                 */
                offset = addr - (addr_t) &dummy->regs.fp_regs;
                tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset);
+               if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
+                       tmp &= (unsigned long) FPC_VALID_MASK
+                               << (BITS_PER_LONG - 32);
 
        } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
                /*
@@ -191,13 +211,19 @@ static int
 poke_user(struct task_struct *child, addr_t addr, addr_t data)
 {
        struct user *dummy = NULL;
-       addr_t offset;
+       addr_t offset, mask;
 
        /*
         * Stupid gdb peeks/pokes the access registers in 64 bit with
         * an alignment of 4. Programmers from hell indeed...
         */
-       if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK)
+       mask = __ADDR_MASK;
+#ifdef CONFIG_ARCH_S390X
+       if (addr >= (addr_t) &dummy->regs.acrs &&
+           addr < (addr_t) &dummy->regs.orig_gpr2)
+               mask = 3;
+#endif
+       if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
                return -EIO;
 
        if (addr < (addr_t) &dummy->regs.acrs) {
@@ -224,6 +250,17 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
                 * access registers are stored in the thread structure
                 */
                offset = addr - (addr_t) &dummy->regs.acrs;
+#ifdef CONFIG_ARCH_S390X
+               /*
+                * Very special case: old & broken 64 bit gdb writing
+                * to acrs[15] with a 64 bit value. Ignore the lower
+                * half of the value and write the upper 32 bit to
+                * acrs[15]. Sick...
+                */
+               if (addr == (addr_t) &dummy->regs.acrs[15])
+                       child->thread.acrs[15] = (unsigned int) (data >> 32);
+               else
+#endif
                *(addr_t *)((addr_t) &child->thread.acrs + offset) = data;
 
        } else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
@@ -237,7 +274,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
                 * floating point regs. are stored in the thread structure
                 */
                if (addr == (addr_t) &dummy->regs.fp_regs.fpc &&
-                   (data & ~FPC_VALID_MASK) != 0)
+                   (data & ~((unsigned long) FPC_VALID_MASK
+                             << (BITS_PER_LONG - 32))) != 0)
                        return -EINVAL;
                offset = addr - (addr_t) &dummy->regs.fp_regs;
                *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data;
@@ -712,21 +750,23 @@ out:
 asmlinkage void
 syscall_trace(struct pt_regs *regs, int entryexit)
 {
-       if (unlikely(current->audit_context)) {
-               if (!entryexit)
-                       audit_syscall_entry(current, regs->gprs[2],
-                                           regs->orig_gpr2, regs->gprs[3],
-                                           regs->gprs[4], regs->gprs[5]);
-               else
-                       audit_syscall_exit(current, regs->gprs[2]);
-       }
+       if (unlikely(current->audit_context) && entryexit)
+               audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
+
        if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               return;
+               goto out;
        if (!(current->ptrace & PT_PTRACED))
-               return;
+               goto out;
        ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
                                 ? 0x80 : 0));
 
+       /*
+        * If the debuffer has set an invalid system call number,
+        * we prepare to skip the system call restart handling.
+        */
+       if (!entryexit && regs->gprs[2] >= NR_syscalls)
+               regs->trap = -1;
+
        /*
         * this isn't the same as continuing with a signal, but it will do
         * for normal use.  strace only continues with a signal if the
@@ -736,4 +776,10 @@ syscall_trace(struct pt_regs *regs, int entryexit)
                send_sig(current->exit_code, current, 1);
                current->exit_code = 0;
        }
+ out:
+       if (unlikely(current->audit_context) && !entryexit)
+               audit_syscall_entry(current, 
+                                   test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
+                                   regs->gprs[2], regs->orig_gpr2, regs->gprs[3],
+                                   regs->gprs[4], regs->gprs[5]);
 }
index 80306bc8c799b7c7e8c98d819806a78a1a7eb951..75fde949d12570a68d1a5aaa228fc946fccc0c4b 100644 (file)
@@ -207,7 +207,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
         * we are not in an interrupt and that there is a 
         * user context.
         */
-        if (user_address == 0 || in_interrupt() || !mm)
+        if (user_address == 0 || in_atomic() || !mm)
                 goto no_context;
 
        /*
index 722ea1d63c9433f463287b65faa853993aaa6b2e..3468d5127223b7f5422b4b3e838e0d87b8ee3921 100644 (file)
@@ -693,6 +693,10 @@ config RTC_9701JE
 
 endmenu
 
+config ISA_DMA_API
+       bool
+       depends on MPC1211
+       default y
 
 menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
 
index 066e253f9c124fd1c29de3a42f2ee14ffa41ac8d..2c216ffeea90b61535eae1cd37d07b7f9acdb479 100644 (file)
@@ -83,9 +83,6 @@ void default_idle(void)
  */
 void cpu_idle(void)
 {
-       if (current->pid != 0)
-               goto out;
-
        /* endless idle loop with no priority at all */
        for (;;) {
                if (ARCH_SUN4C_SUN4) {
@@ -126,8 +123,6 @@ void cpu_idle(void)
                schedule();
                check_pgt_cache();
        }
-out:
-       return;
 }
 
 #else
index 46aa51afec149ef51582bb0014b2012c0df77cdb..c20e5309f8aa6dd1726f1f6835cb461e7d968be6 100644 (file)
@@ -47,9 +47,9 @@ prom_sortmemlist(struct linux_mlist_v0 *thislist)
        char *tmpaddr;
        char *lowest;
 
-       for(i=0; thislist[i].theres_more != 0; i++) {
+       for(i=0; thislist[i].theres_more; i++) {
                lowest = thislist[i].start_adr;
-               for(mitr = i+1; thislist[mitr-1].theres_more != 0; mitr++)
+               for(mitr = i+1; thislist[mitr-1].theres_more; mitr++)
                        if(thislist[mitr].start_adr < lowest) {
                                lowest = thislist[mitr].start_adr;
                                swapi = mitr;
@@ -85,7 +85,7 @@ void __init prom_meminit(void)
                        prom_phys_total[iter].num_bytes = mptr->num_bytes;
                        prom_phys_total[iter].theres_more = &prom_phys_total[iter+1];
                }
-               prom_phys_total[iter-1].theres_more = 0x0;
+               prom_phys_total[iter-1].theres_more = NULL;
                /* Second, the total prom taken descriptors. */
                for(mptr = (*(romvec->pv_v0mem.v0_prommap)), iter=0;
                    mptr; mptr=mptr->theres_more, iter++) {
@@ -93,7 +93,7 @@ void __init prom_meminit(void)
                        prom_prom_taken[iter].num_bytes = mptr->num_bytes;
                        prom_prom_taken[iter].theres_more = &prom_prom_taken[iter+1];
                }
-               prom_prom_taken[iter-1].theres_more = 0x0;
+               prom_prom_taken[iter-1].theres_more = NULL;
                /* Last, the available physical descriptors. */
                for(mptr = (*(romvec->pv_v0mem.v0_available)), iter=0;
                    mptr; mptr=mptr->theres_more, iter++) {
@@ -101,7 +101,7 @@ void __init prom_meminit(void)
                        prom_phys_avail[iter].num_bytes = mptr->num_bytes;
                        prom_phys_avail[iter].theres_more = &prom_phys_avail[iter+1];
                }
-               prom_phys_avail[iter-1].theres_more = 0x0;
+               prom_phys_avail[iter-1].theres_more = NULL;
                /* Sort all the lists. */
                prom_sortmemlist(prom_phys_total);
                prom_sortmemlist(prom_prom_taken);
@@ -124,7 +124,7 @@ void __init prom_meminit(void)
                        prom_phys_avail[iter].theres_more =
                                &prom_phys_avail[iter+1];
                }
-               prom_phys_avail[iter-1].theres_more = 0x0;
+               prom_phys_avail[iter-1].theres_more = NULL;
 
                num_regs = prom_getproperty(node, "reg",
                                            (char *) prom_reg_memlist,
@@ -138,7 +138,7 @@ void __init prom_meminit(void)
                        prom_phys_total[iter].theres_more =
                                &prom_phys_total[iter+1];
                }
-               prom_phys_total[iter-1].theres_more = 0x0;
+               prom_phys_total[iter-1].theres_more = NULL;
 
                node = prom_getchild(prom_root_node);
                node = prom_searchsiblings(node, "virtual-memory");
@@ -158,7 +158,7 @@ void __init prom_meminit(void)
                        prom_prom_taken[iter].theres_more =
                                &prom_prom_taken[iter+1];
                }
-               prom_prom_taken[iter-1].theres_more = 0x0;
+               prom_prom_taken[iter-1].theres_more = NULL;
 
                prom_sortmemlist(prom_prom_taken);
 
@@ -182,15 +182,15 @@ void __init prom_meminit(void)
        case PROM_SUN4:
 #ifdef CONFIG_SUN4     
                /* how simple :) */
-               prom_phys_total[0].start_adr = 0x0;
+               prom_phys_total[0].start_adr = NULL;
                prom_phys_total[0].num_bytes = *(sun4_romvec->memorysize);
-               prom_phys_total[0].theres_more = 0x0;
-               prom_prom_taken[0].start_adr = 0x0
+               prom_phys_total[0].theres_more = NULL;
+               prom_prom_taken[0].start_adr = NULL
                prom_prom_taken[0].num_bytes = 0x0;
-               prom_prom_taken[0].theres_more = 0x0;
-               prom_phys_avail[0].start_adr = 0x0;
+               prom_prom_taken[0].theres_more = NULL;
+               prom_phys_avail[0].start_adr = NULL;
                prom_phys_avail[0].num_bytes = *(sun4_romvec->memoryavail);
-               prom_phys_avail[0].theres_more = 0x0;
+               prom_phys_avail[0].theres_more = NULL;
 #endif
                break;
 
index 69ca735f0d4e76b7aa6352fb16f2d1b07ff72a65..00390a2652aa16191514d199eb4653481c6d5d1b 100644 (file)
@@ -151,7 +151,7 @@ struct linux_romvec * __init sun4_prom_init(void)
         * have more time, we can teach the penguin to say "By your
         * command" or "Activating turbo boost, Michael". :-)
         */
-       sun4_romvec->setLEDs(0x0);
+       sun4_romvec->setLEDs(NULL);
        
        printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n",
                sun4_romvec->monid,
index a38cb5036df06283848d4a5b2a059ef4be1c88b5..4dcb8af94090cfc490da271877561d988b3a2aea 100644 (file)
@@ -756,7 +756,7 @@ void handler_irq(int irq, struct pt_regs *regs)
                clear_softint(clr_mask);
        }
 #else
-       int should_forward = 1;
+       int should_forward = 0;
 
        clear_softint(1 << irq);
 #endif
@@ -1007,10 +1007,10 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu)
        }
        upa_writel(tid | IMAP_VALID, imap);
 
-       while (!cpu_online(goal_cpu)) {
+       do {
                if (++goal_cpu >= NR_CPUS)
                        goal_cpu = 0;
-       }
+       } while (!cpu_online(goal_cpu));
 
        return goal_cpu;
 }
index 292983413ae2af3616f57b13f47e485212753251..2803bc7c2c798af12fc0d57b701991bc51727995 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/delay.h>
 
 #include <asm/pbm.h>
 
@@ -195,6 +196,34 @@ static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long
        return NULL;
 }
 
+static int iommu_alloc_ctx(struct pci_iommu *iommu)
+{
+       int lowest = iommu->ctx_lowest_free;
+       int sz = IOMMU_NUM_CTXS - lowest;
+       int n = find_next_zero_bit(iommu->ctx_bitmap, sz, lowest);
+
+       if (unlikely(n == sz)) {
+               n = find_next_zero_bit(iommu->ctx_bitmap, lowest, 1);
+               if (unlikely(n == lowest)) {
+                       printk(KERN_WARNING "IOMMU: Ran out of contexts.\n");
+                       n = 0;
+               }
+       }
+       if (n)
+               __set_bit(n, iommu->ctx_bitmap);
+
+       return n;
+}
+
+static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx)
+{
+       if (likely(ctx)) {
+               __clear_bit(ctx, iommu->ctx_bitmap);
+               if (ctx < iommu->ctx_lowest_free)
+                       iommu->ctx_lowest_free = ctx;
+       }
+}
+
 /* Allocate and map kernel buffer of size SIZE using consistent mode
  * DMA for PCI device PDEV.  Return non-NULL cpu-side address if
  * successful and set *DMA_ADDRP to the PCI side dma address.
@@ -235,7 +264,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
        npages = size >> IO_PAGE_SHIFT;
        ctx = 0;
        if (iommu->iommu_ctxflush)
-               ctx = iommu->iommu_cur_ctx++;
+               ctx = iommu_alloc_ctx(iommu);
        first_page = __pa(first_page);
        while (npages--) {
                iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) |
@@ -316,6 +345,8 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_
                }
        }
 
+       iommu_free_ctx(iommu, ctx);
+
        spin_unlock_irqrestore(&iommu->lock, flags);
 
        order = get_order(size);
@@ -359,7 +390,7 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
        base_paddr = __pa(oaddr & IO_PAGE_MASK);
        ctx = 0;
        if (iommu->iommu_ctxflush)
-               ctx = iommu->iommu_cur_ctx++;
+               ctx = iommu_alloc_ctx(iommu);
        if (strbuf->strbuf_enabled)
                iopte_protection = IOPTE_STREAMING(ctx);
        else
@@ -379,6 +410,70 @@ bad:
        return PCI_DMA_ERROR_CODE;
 }
 
+static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages, int direction)
+{
+       int limit;
+
+       if (strbuf->strbuf_ctxflush &&
+           iommu->iommu_ctxflush) {
+               unsigned long matchreg, flushreg;
+               u64 val;
+
+               flushreg = strbuf->strbuf_ctxflush;
+               matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
+
+               pci_iommu_write(flushreg, ctx);
+               val = pci_iommu_read(matchreg);
+               val &= 0xffff;
+               if (!val)
+                       goto do_flush_sync;
+
+               while (val) {
+                       if (val & 0x1)
+                               pci_iommu_write(flushreg, ctx);
+                       val >>= 1;
+               }
+               val = pci_iommu_read(matchreg);
+               if (unlikely(val)) {
+                       printk(KERN_WARNING "pci_strbuf_flush: ctx flush "
+                              "timeout matchreg[%lx] ctx[%lx]\n",
+                              val, ctx);
+                       goto do_page_flush;
+               }
+       } else {
+               unsigned long i;
+
+       do_page_flush:
+               for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
+                       pci_iommu_write(strbuf->strbuf_pflush, vaddr);
+       }
+
+do_flush_sync:
+       /* If the device could not have possibly put dirty data into
+        * the streaming cache, no flush-flag synchronization needs
+        * to be performed.
+        */
+       if (direction == PCI_DMA_TODEVICE)
+               return;
+
+       PCI_STC_FLUSHFLAG_INIT(strbuf);
+       pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
+       (void) pci_iommu_read(iommu->write_complete_reg);
+
+       limit = 100000;
+       while (!PCI_STC_FLUSHFLAG_SET(strbuf)) {
+               limit--;
+               if (!limit)
+                       break;
+               udelay(1);
+               membar("#LoadLoad");
+       }
+       if (!limit)
+               printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout "
+                      "vaddr[%08x] ctx[%lx] npages[%ld]\n",
+                      vaddr, ctx, npages);
+}
+
 /* Unmap a single streaming mode DMA translation. */
 void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
 {
@@ -386,7 +481,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
        struct pci_iommu *iommu;
        struct pci_strbuf *strbuf;
        iopte_t *base;
-       unsigned long flags, npages, i, ctx;
+       unsigned long flags, npages, ctx;
 
        if (direction == PCI_DMA_NONE)
                BUG();
@@ -414,29 +509,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
                ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
 
        /* Step 1: Kick data out of streaming buffers if necessary. */
-       if (strbuf->strbuf_enabled) {
-               u32 vaddr = bus_addr;
-
-               PCI_STC_FLUSHFLAG_INIT(strbuf);
-               if (strbuf->strbuf_ctxflush &&
-                   iommu->iommu_ctxflush) {
-                       unsigned long matchreg, flushreg;
-
-                       flushreg = strbuf->strbuf_ctxflush;
-                       matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
-                       do {
-                               pci_iommu_write(flushreg, ctx);
-                       } while(((long)pci_iommu_read(matchreg)) < 0L);
-               } else {
-                       for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
-                               pci_iommu_write(strbuf->strbuf_pflush, vaddr);
-               }
-
-               pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
-               (void) pci_iommu_read(iommu->write_complete_reg);
-               while (!PCI_STC_FLUSHFLAG_SET(strbuf))
-                       membar("#LoadLoad");
-       }
+       if (strbuf->strbuf_enabled)
+               pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
 
        /* Step 2: Clear out first TSB entry. */
        iopte_make_dummy(iommu, base);
@@ -444,6 +518,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
        free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base,
                               npages, ctx);
 
+       iommu_free_ctx(iommu, ctx);
+
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -583,7 +659,7 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int
        /* Step 4: Choose a context if necessary. */
        ctx = 0;
        if (iommu->iommu_ctxflush)
-               ctx = iommu->iommu_cur_ctx++;
+               ctx = iommu_alloc_ctx(iommu);
 
        /* Step 5: Create the mappings. */
        if (strbuf->strbuf_enabled)
@@ -647,29 +723,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
                ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
 
        /* Step 1: Kick data out of streaming buffers if necessary. */
-       if (strbuf->strbuf_enabled) {
-               u32 vaddr = (u32) bus_addr;
-
-               PCI_STC_FLUSHFLAG_INIT(strbuf);
-               if (strbuf->strbuf_ctxflush &&
-                   iommu->iommu_ctxflush) {
-                       unsigned long matchreg, flushreg;
-
-                       flushreg = strbuf->strbuf_ctxflush;
-                       matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
-                       do {
-                               pci_iommu_write(flushreg, ctx);
-                       } while(((long)pci_iommu_read(matchreg)) < 0L);
-               } else {
-                       for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
-                               pci_iommu_write(strbuf->strbuf_pflush, vaddr);
-               }
-
-               pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
-               (void) pci_iommu_read(iommu->write_complete_reg);
-               while (!PCI_STC_FLUSHFLAG_SET(strbuf))
-                       membar("#LoadLoad");
-       }
+       if (strbuf->strbuf_enabled)
+               pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
 
        /* Step 2: Clear out first TSB entry. */
        iopte_make_dummy(iommu, base);
@@ -677,6 +732,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
        free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base,
                               npages, ctx);
 
+       iommu_free_ctx(iommu, ctx);
+
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -715,28 +772,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size
        }
 
        /* Step 2: Kick data out of streaming buffers. */
-       PCI_STC_FLUSHFLAG_INIT(strbuf);
-       if (iommu->iommu_ctxflush &&
-           strbuf->strbuf_ctxflush) {
-               unsigned long matchreg, flushreg;
-
-               flushreg = strbuf->strbuf_ctxflush;
-               matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
-               do {
-                       pci_iommu_write(flushreg, ctx);
-               } while(((long)pci_iommu_read(matchreg)) < 0L);
-       } else {
-               unsigned long i;
-
-               for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
-                       pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
-       }
-
-       /* Step 3: Perform flush synchronization sequence. */
-       pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
-       (void) pci_iommu_read(iommu->write_complete_reg);
-       while (!PCI_STC_FLUSHFLAG_SET(strbuf))
-               membar("#LoadLoad");
+       pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
 
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
@@ -749,7 +785,8 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
        struct pcidev_cookie *pcp;
        struct pci_iommu *iommu;
        struct pci_strbuf *strbuf;
-       unsigned long flags, ctx;
+       unsigned long flags, ctx, npages, i;
+       u32 bus_addr;
 
        pcp = pdev->sysdata;
        iommu = pcp->pbm->iommu;
@@ -772,36 +809,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
        }
 
        /* Step 2: Kick data out of streaming buffers. */
-       PCI_STC_FLUSHFLAG_INIT(strbuf);
-       if (iommu->iommu_ctxflush &&
-           strbuf->strbuf_ctxflush) {
-               unsigned long matchreg, flushreg;
-
-               flushreg = strbuf->strbuf_ctxflush;
-               matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
-               do {
-                       pci_iommu_write(flushreg, ctx);
-               } while (((long)pci_iommu_read(matchreg)) < 0L);
-       } else {
-               unsigned long i, npages;
-               u32 bus_addr;
-
-               bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
-
-               for(i = 1; i < nelems; i++)
-                       if (!sglist[i].dma_length)
-                               break;
-               i--;
-               npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT;
-               for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
-                       pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
-       }
-
-       /* Step 3: Perform flush synchronization sequence. */
-       pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
-       (void) pci_iommu_read(iommu->write_complete_reg);
-       while (!PCI_STC_FLUSHFLAG_SET(strbuf))
-               membar("#LoadLoad");
+       bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
+       for(i = 1; i < nelems; i++)
+               if (!sglist[i].dma_length)
+                       break;
+       i--;
+       npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length)
+                 - bus_addr) >> IO_PAGE_SHIFT;
+       pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
 
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
index 3567fa879e1fe7a900e545704ad97593d01cc820..534320ef0db2a43992ac6341df4c444d9ccc2182 100644 (file)
@@ -1212,7 +1212,7 @@ static void __init psycho_iommu_init(struct pci_controller_info *p)
 
        /* Setup initial software IOMMU state. */
        spin_lock_init(&iommu->lock);
-       iommu->iommu_cur_ctx = 0;
+       iommu->ctx_lowest_free = 1;
 
        /* Register addresses. */
        iommu->iommu_control  = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL;
index 5525d1ec4af883884404d13b17ddc6deda8379f5..53d333b4a4e809f7ebf48231c46bb5e65af86ec3 100644 (file)
@@ -1265,7 +1265,7 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
 
        /* Setup initial software IOMMU state. */
        spin_lock_init(&iommu->lock);
-       iommu->iommu_cur_ctx = 0;
+       iommu->ctx_lowest_free = 1;
 
        /* Register addresses. */
        iommu->iommu_control  = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL;
index e93fcadc37229f99221d1e7781941e5f00ddf0b1..5753175b94e6c91da7eb7ad91fcf197585bf3c98 100644 (file)
@@ -1753,7 +1753,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
 
        /* Setup initial software IOMMU state. */
        spin_lock_init(&iommu->lock);
-       iommu->iommu_cur_ctx = 0;
+       iommu->ctx_lowest_free = 1;
 
        /* Register addresses, SCHIZO has iommu ctx flushing. */
        iommu->iommu_control  = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
index 26d3ec41da1c376fbe855ec1253c56c327fed43f..a0cd2b2494d6cc5f111faeed82a42ab96ba99323 100644 (file)
@@ -62,9 +62,6 @@ void default_idle(void)
  */
 void cpu_idle(void)
 {
-       if (current->pid != 0)
-               return;
-
        /* endless idle loop with no priority at all */
        for (;;) {
                /* If current->work.need_resched is zero we should really
@@ -80,7 +77,6 @@ void cpu_idle(void)
                schedule();
                check_pgt_cache();
        }
-       return;
 }
 
 #else
index 14d9c3a21b9aab04d79a0fb60703a4661cf2c80d..89f5e019f24c02ade1ed11ab0c6ed721de1b4bfd 100644 (file)
@@ -117,19 +117,42 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages
 
 #define STRBUF_TAG_VALID       0x02UL
 
-static void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
+static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages, int direction)
 {
-       iommu->strbuf_flushflag = 0UL;
-       while (npages--)
-               upa_writeq(base + (npages << IO_PAGE_SHIFT),
+       unsigned long n;
+       int limit;
+
+       n = npages;
+       while (n--)
+               upa_writeq(base + (n << IO_PAGE_SHIFT),
                           iommu->strbuf_regs + STRBUF_PFLUSH);
 
+       /* If the device could not have possibly put dirty data into
+        * the streaming cache, no flush-flag synchronization needs
+        * to be performed.
+        */
+       if (direction == SBUS_DMA_TODEVICE)
+               return;
+
+       iommu->strbuf_flushflag = 0UL;
+
        /* Whoopee cushion! */
        upa_writeq(__pa(&iommu->strbuf_flushflag),
                   iommu->strbuf_regs + STRBUF_FSYNC);
        upa_readq(iommu->sbus_control_reg);
-       while (iommu->strbuf_flushflag == 0UL)
+
+       limit = 100000;
+       while (iommu->strbuf_flushflag == 0UL) {
+               limit--;
+               if (!limit)
+                       break;
+               udelay(1);
                membar("#LoadLoad");
+       }
+       if (!limit)
+               printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout "
+                      "vaddr[%08x] npages[%ld]\n",
+                      base, npages);
 }
 
 static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages)
@@ -406,7 +429,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size,
 
        spin_lock_irqsave(&iommu->lock, flags);
        free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);
-       strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);
+       sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT, direction);
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -569,7 +592,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int
        iommu = sdev->bus->iommu;
        spin_lock_irqsave(&iommu->lock, flags);
        free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT);
-       strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT);
+       sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT, direction);
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -581,7 +604,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t
        size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK));
 
        spin_lock_irqsave(&iommu->lock, flags);
-       strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT);
+       sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT, direction);
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -605,7 +628,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int
        size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base;
 
        spin_lock_irqsave(&iommu->lock, flags);
-       strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
+       sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT, direction);
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
index 12c3d84b7460cb987fc511e0675f0ef5234f58c3..b7e6a91952b213dacfe1ce43e2497df4192de634 100644 (file)
@@ -383,6 +383,17 @@ static void __init process_switch(char c)
                /* Use PROM debug console. */
                register_console(&prom_debug_console);
                break;
+       case 'P':
+               /* Force UltraSPARC-III P-Cache on. */
+               if (tlb_type != cheetah) {
+                       printk("BOOT: Ignoring P-Cache force option.\n");
+                       break;
+               }
+               cheetah_pcache_forced_on = 1;
+               add_taint(TAINT_MACHINE_CHECK);
+               cheetah_enable_pcache();
+               break;
+
        default:
                printk("Unknown boot switch (-%c)\n", c);
                break;
index 6dff06a44e76ed4730d6919fb0c09f3f044f8a42..e5b9c7a27789853d13c6e350afabdfb123092373 100644 (file)
@@ -123,6 +123,9 @@ void __init smp_callin(void)
 
        smp_setup_percpu_timer();
 
+       if (cheetah_pcache_forced_on)
+               cheetah_enable_pcache();
+
        local_irq_enable();
 
        calibrate_delay();
index cad5a11228006abbacd27f321c31166605f49b64..e78cc53594fa5bfbfc480ba874a24047f7f2b508 100644 (file)
@@ -278,7 +278,7 @@ EXPORT_SYMBOL(verify_compat_iovec);
 
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(__pte_alloc_one_kernel);
+EXPORT_SYMBOL(pte_alloc_one_kernel);
 #ifndef CONFIG_SMP
 EXPORT_SYMBOL(pgt_quicklists);
 #endif
index 56b203a2af696e43491e8e4dba0057daa72b95db..a9f4596d7c2bcd82419386d808b5f35d69d2a46a 100644 (file)
@@ -421,6 +421,25 @@ asmlinkage void cee_log(unsigned long ce_status,
        }
 }
 
+int cheetah_pcache_forced_on;
+
+void cheetah_enable_pcache(void)
+{
+       unsigned long dcr;
+
+       printk("CHEETAH: Enabling P-Cache on cpu %d.\n",
+              smp_processor_id());
+
+       __asm__ __volatile__("ldxa [%%g0] %1, %0"
+                            : "=r" (dcr)
+                            : "i" (ASI_DCU_CONTROL_REG));
+       dcr |= (DCU_PE | DCU_HPE | DCU_SPE | DCU_SL);
+       __asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
+                            "membar #Sync"
+                            : /* no outputs */
+                            : "r" (dcr), "i" (ASI_DCU_CONTROL_REG));
+}
+
 /* Cheetah error trap handling. */
 static unsigned long ecache_flush_physbase;
 static unsigned long ecache_flush_linesize;
index db6fa77b4dab67463c14c43da29fd5ee3284abf2..9c5222075da93ac61018cb996f32008178dffcbd 100644 (file)
@@ -1114,7 +1114,7 @@ struct pgtable_cache_struct pgt_quicklists;
 #else
 #define DC_ALIAS_SHIFT 0
 #endif
-pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
        struct page *page;
        unsigned long color;
index b89989de364d1dbe650e988c5ec009b73acc5ba0..bd41e4286d0d4b743fafc74a993f167c7cac0955 100644 (file)
@@ -2,10 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config FRAME_POINTER
-       bool
-       default y if DEBUG_INFO
-
 config PT_PROXY
        bool "Enable ptrace proxy"
        depends on XTERM_CHAN && DEBUG_INFO && MODE_TT
index 3e50fdb67626a20a64a85fa6e4d9ec748bcc28ca..62d87b71179b5b63497d6183c6b2f3c66c994fc1 100644 (file)
@@ -204,5 +204,11 @@ config UML_RANDOM
        http://sourceforge.net/projects/gkernel/).  rngd periodically reads
        /dev/hwrng and injects the entropy into /dev/random.
 
+config MMAPPER
+       tristate "iomem emulation driver"
+       help
+       This driver allows a host file to be used as emulated IO memory inside
+       UML.
+
 endmenu
 
index fd8d7e8982b19b6c066e80b8d46db30eafa3bd77..f162f50f0b179539c5a6f8c0dfa439dc47ebfff5 100644 (file)
@@ -6,6 +6,10 @@ config 64BIT
        bool
        default y
 
+config TOP_ADDR
+       hex
+       default 0x80000000
+
 config 3_LEVEL_PGTABLES
        bool
        default y
index 97bca6b5ca95bfaee3dbf09ca701b835910f5cd7..f2a0c40a9204d5efa76437a45bcec5aaa84fb02d 100644 (file)
@@ -17,7 +17,7 @@ core-y                        += $(ARCH_DIR)/kernel/          \
 
 # Have to precede the include because the included Makefiles reference them.
 SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \
-       arch-signal.h module.h vm-flags.h
+       module.h vm-flags.h elf.h
 SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
 
 # XXX: The "os" symlink is only used by arch/um/include/os.h, which includes
@@ -44,6 +44,11 @@ ifneq ($(MAKEFILES-INCL),)
 endif
 
 ARCH_INCLUDE   := -I$(ARCH_DIR)/include
+ifneq ($(KBUILD_SRC),)
+ARCH_INCLUDE   += -I$(ARCH_DIR)/include2
+ARCH_INCLUDE   += -I$(srctree)/$(ARCH_DIR)/include
+MRPROPER_DIRS  += $(ARCH_DIR)/include2
+endif
 SYS_DIR                := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
 
 include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
@@ -94,17 +99,18 @@ define archhelp
   echo '                  find in the kernel root.'
 endef
 
+ifneq ($(KBUILD_SRC),)
+$(shell mkdir -p $(ARCH_DIR) && ln -fsn $(srctree)/$(ARCH_DIR)/Kconfig_$(SUBARCH) $(ARCH_DIR)/Kconfig_arch)
+CLEAN_FILES += $(ARCH_DIR)/Kconfig_arch
+else
 $(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch)
+endif
 
-prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \
-       $(ARCH_DIR)/kernel/vmlinux.lds.S
+prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
 
 LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
 LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
 
-LD_SCRIPT-$(CONFIG_LD_SCRIPT_STATIC) := uml.lds.S
-LD_SCRIPT-$(CONFIG_LD_SCRIPT_DYN) := dyn.lds.S
-
 CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
 CONFIG_KERNEL_STACK_ORDER ?= 2
 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
@@ -126,7 +132,7 @@ define cmd_vmlinux__
        $(CC) $(CFLAGS_vmlinux) -o $@ \
        -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
        -Wl,--start-group $(vmlinux-main) -Wl,--end-group \
-       -L/usr/lib -lutil \
+       -lutil \
        $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \
        FORCE ,$^) ; rm -f linux
 endef
@@ -145,31 +151,42 @@ archclean:
        @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
                -o -name '*.gcov' \) -type f -print | xargs rm -f
 
-#We need to re-preprocess this when the symlink dest changes.
-#So we touch it when needed.
-$(ARCH_DIR)/kernel/vmlinux.lds.S: FORCE
-       $(Q)if [ "$(shell readlink $@)" != "$(LD_SCRIPT-y)" ]; then \
-               echo '  SYMLINK $@'; \
-               ln -sf $(LD_SCRIPT-y) $@; \
-               touch $@; \
-       fi;
-
 $(SYMLINK_HEADERS):
        @echo '  SYMLINK $@'
+ifneq ($(KBUILD_SRC),)
+       ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
+else
        $(Q)cd $(TOPDIR)/$(dir $@) ; \
        ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
+endif
 
 include/asm-um/arch:
        @echo '  SYMLINK $@'
+ifneq ($(KBUILD_SRC),)
+       $(Q)mkdir -p include/asm-um
+       $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch
+else
        $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
+endif
 
 $(ARCH_DIR)/include/sysdep:
        @echo '  SYMLINK $@'
+ifneq ($(KBUILD_SRC),)
+       $(Q)mkdir -p $(ARCH_DIR)/include
+       $(Q)mkdir -p $(ARCH_DIR)/include2
+       $(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
+       $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep
+else
        $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep
+endif
 
 $(ARCH_DIR)/os:
        @echo '  SYMLINK $@'
+ifneq ($(KBUILD_SRC),)
+       $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os
+else
        $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os
+endif
 
 # Generated files
 define filechk_umlconfig
@@ -179,10 +196,31 @@ endef
 $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
        $(call filechk,umlconfig)
 
+$(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c
+       $(CC) $(USER_CFLAGS) -S -o $@ $<
+
+$(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s
+       $(call filechk,gen-asm-offsets)
+
+CLEAN_FILES += $(ARCH_DIR)/user-offsets.s  $(ARCH_DIR)/user-offsets.h
+
+$(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \
+                                  $(ARCH_SYMLINKS) \
+                                  $(SYS_DIR)/sc.h \
+                                  include/asm include/linux/version.h \
+                                  include/config/MARKER \
+                                  $(ARCH_DIR)/include/user_constants.h
+       $(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $<
+
+$(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s
+       $(call filechk,gen-asm-offsets)
+
+CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s  $(ARCH_DIR)/kernel-offsets.h
+
 $(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task
        $(call filechk,gen_header)
 
-$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os/util/mk_user_constants
+$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants
        $(call filechk,gen_header)
 
 $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants
@@ -191,20 +229,20 @@ $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants
 $(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs
        $(call filechk,gen_header)
 
-$(ARCH_DIR)/os/util/mk_user_constants: $(ARCH_DIR)/os/util FORCE ;
+$(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ;
 
 $(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \
        FORCE ;
 
 $(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ;
 
-$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h FORCE
+$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE
        $(Q)$(MAKE) $(build)=$@
 
-$(ARCH_DIR)/kernel/skas/util: scripts_basic FORCE
+$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
        $(Q)$(MAKE) $(build)=$@
 
-$(ARCH_DIR)/os/util: scripts_basic FORCE
+$(ARCH_DIR)/os-$(OS)/util: scripts_basic FORCE
        $(Q)$(MAKE) $(build)=$@
 
 export SUBARCH USER_CFLAGS OS
index f9e3c0f06541e157fd8fa015aa8b7ba7f6cbf120..29e182d5a83a48508f56bc30e370469af77fe91e 100644 (file)
@@ -32,10 +32,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
 $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 
        $(call filechk,gen_header)
 
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE
+$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
        $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
 
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE
+$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE
        $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
 
 $(SYS_UTIL_DIR): scripts_basic include/asm FORCE
index a77971133e916eda937ed9e8873227b2e49fdf5d..32144562c2798f749640be52f0cf43cedbec671b 100644 (file)
@@ -23,10 +23,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
 $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
        $(call filechk,gen_header)
 
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE
+$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
        $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
 
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE
+$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE
        $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
 
 CLEAN_FILES += $(SYS_HEADERS)
index 323f72c64cd207bb14e77280e540df3f7957ca45..b2de9916c32c08a543325dde86d8069f1535ea5a 100644 (file)
@@ -22,8 +22,8 @@ obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
 obj-$(CONFIG_SSL) += ssl.o
 obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
 
-obj-$(CONFIG_UML_NET_SLIP) += slip.o
-obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
+obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
+obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
 obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
 obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
 #obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP)
@@ -41,6 +41,6 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
 obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
 obj-$(CONFIG_UML_RANDOM) += random.o
 
-USER_OBJS := fd.o null.o pty.o tty.o xterm.o
+USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o
 
 include arch/um/scripts/Makefile.rules
index 0150038af795f054e66b8331f9ffcf4d2e8d612a..14a12d6b3df6e89c695860170ce10145d1556f0d 100644 (file)
 #include "os.h"
 
 #ifdef CONFIG_NOCONFIG_CHAN
+
+/* The printk's here are wrong because we are complaining that there is no
+ * output device, but printk is printing to that output device.  The user will
+ * never see the error.  printf would be better, except it can't run on a
+ * kernel stack because it will overflow it.
+ * Use printk for now since that will avoid crashing.
+ */
+
 static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 {
-       printf(KERN_ERR "Using a channel type which is configured out of "
+       printk(KERN_ERR "Using a channel type which is configured out of "
               "UML\n");
        return(NULL);
 }
@@ -30,27 +38,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 static int not_configged_open(int input, int output, int primary, void *data,
                              char **dev_out)
 {
-       printf(KERN_ERR "Using a channel type which is configured out of "
+       printk(KERN_ERR "Using a channel type which is configured out of "
               "UML\n");
        return(-ENODEV);
 }
 
 static void not_configged_close(int fd, void *data)
 {
-       printf(KERN_ERR "Using a channel type which is configured out of "
+       printk(KERN_ERR "Using a channel type which is configured out of "
               "UML\n");
 }
 
 static int not_configged_read(int fd, char *c_out, void *data)
 {
-       printf(KERN_ERR "Using a channel type which is configured out of "
+       printk(KERN_ERR "Using a channel type which is configured out of "
               "UML\n");
        return(-EIO);
 }
 
 static int not_configged_write(int fd, const char *buf, int len, void *data)
 {
-       printf(KERN_ERR "Using a channel type which is configured out of "
+       printk(KERN_ERR "Using a channel type which is configured out of "
               "UML\n");
        return(-EIO);
 }
@@ -58,7 +66,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
 static int not_configged_console_write(int fd, const char *buf, int len,
                                       void *data)
 {
-       printf(KERN_ERR "Using a channel type which is configured out of "
+       printk(KERN_ERR "Using a channel type which is configured out of "
               "UML\n");
        return(-EIO);
 }
@@ -66,7 +74,7 @@ static int not_configged_console_write(int fd, const char *buf, int len,
 static int not_configged_window_size(int fd, void *data, unsigned short *rows,
                                     unsigned short *cols)
 {
-       printf(KERN_ERR "Using a channel type which is configured out of "
+       printk(KERN_ERR "Using a channel type which is configured out of "
               "UML\n");
        return(-ENODEV);
 }
index 583b8e137c334fe5dba0dee27c937eca6733b293..5d3768156c92b3a9653ac022ce6b9c1f3f486719 100644 (file)
@@ -143,22 +143,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
 {
        struct winch_data data;
        unsigned long stack;
-       int fds[2], pid, n, err;
+       int fds[2], n, err;
        char c;
 
        err = os_pipe(fds, 1, 1);
        if(err < 0){
                printk("winch_tramp : os_pipe failed, err = %d\n", -err);
-               return(err);
+               goto out;
        }
 
        data = ((struct winch_data) { .pty_fd           = fd,
                                      .pipe_fd          = fds[1],
                                      .close_me         = fds[0] } );
-       pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
-       if(pid < 0){
+       err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
+       if(err < 0){
                printk("fork of winch_thread failed - errno = %d\n", errno);
-               return(pid);
+               goto out_close;
        }
 
        os_close_file(fds[1]);
@@ -168,14 +168,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
                printk("winch_tramp : failed to read synchronization byte\n");
                printk("read failed, err = %d\n", -n);
                printk("fd %d will not support SIGWINCH\n", fd);
-               *fd_out = -1;
+                err = -EINVAL;
+               goto out_close1;
        }
-       return(pid);
+       return err ;
+
+ out_close:
+       os_close_file(fds[1]);
+ out_close1:
+       os_close_file(fds[0]);
+ out:
+       return err;
 }
 
 void register_winch(int fd, struct tty_struct *tty)
 {
-       int pid, thread, thread_fd;
+       int pid, thread, thread_fd = -1;
        int count;
        char c = 1;
 
@@ -186,7 +194,7 @@ void register_winch(int fd, struct tty_struct *tty)
        if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
                             tty) && (pid == -1)){
                thread = winch_tramp(fd, tty, &thread_fd);
-               if(fd != -1){
+               if(thread > 0){
                        register_winch_irq(thread_fd, fd, thread, tty);
 
                        count = os_write_file(thread_fd, &c, sizeof(c));
index d0f97127adf691a651d86f896760e5cf5fe01a4e..025d3be8aca4ae522e40b6aaa2a8623834805243 100644 (file)
@@ -462,12 +462,15 @@ out:
        return err;
 }
 
+static void unregister_winch(struct tty_struct *tty);
+
 void line_close(struct tty_struct *tty, struct file * filp)
 {
        struct line *line = tty->driver_data;
 
-       /* XXX: I assume this should be called in process context, not with interrupt
-        * disabled!*/
+       /* XXX: I assume this should be called in process context, not with
+         *  interrupts disabled!
+         */
        spin_lock_irq(&line->lock);
 
        /* We ignore the error anyway! */
@@ -478,6 +481,12 @@ void line_close(struct tty_struct *tty, struct file * filp)
                line_disable(tty, -1);
                tty->driver_data = NULL;
        }
+
+        if((line->count == 0) && line->sigio){
+                unregister_winch(tty);
+                line->sigio = 0;
+        }
+
        spin_unlock_irq(&line->lock);
 }
 
@@ -729,6 +738,34 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
        up(&winch_handler_sem);
 }
 
+static void unregister_winch(struct tty_struct *tty)
+{
+       struct list_head *ele;
+       struct winch *winch, *found = NULL;
+
+       down(&winch_handler_sem);
+       list_for_each(ele, &winch_handlers){
+               winch = list_entry(ele, struct winch, list);
+                if(winch->tty == tty){
+                        found = winch;
+                        break;
+                }
+        }
+
+        if(found == NULL)
+                goto out;
+
+        if(winch->pid != -1)
+                os_kill_process(winch->pid, 1);
+
+        free_irq_by_irq_and_dev(WINCH_IRQ, winch);
+        free_irq(WINCH_IRQ, winch);
+        list_del(&winch->list);
+        kfree(winch);
+ out:
+       up(&winch_handler_sem);
+}
+
 static void winch_cleanup(void)
 {
        struct list_head *ele;
index faf714e87b5b1a8bd78663b18c37c3799b29fb07..217438cdef336fff7e609fbb63378a541c3e93f4 100644 (file)
@@ -73,7 +73,6 @@ int mcast_setup(char *str, char **mac_out, void *data)
        struct mcast_init *init = data;
        char *port_str = NULL, *ttl_str = NULL, *remain;
        char *last;
-       int n;
 
        *init = ((struct mcast_init)
                { .addr         = "239.192.168.1",
@@ -89,13 +88,12 @@ int mcast_setup(char *str, char **mac_out, void *data)
        }
        
        if(port_str != NULL){
-               n = simple_strtoul(port_str, &last, 10);
+               init->port = simple_strtoul(port_str, &last, 10);
                if((*last != '\0') || (last == port_str)){
                        printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 
                               port_str);
                        return(0);
                }
-               init->port = htons(n);
        }
 
        if(ttl_str != NULL){
index 0fe1d9fa9139a8b326ed831527c48e49f378eb2f..7a0d115b29d09e8b9361668e424c208c0f1a6e5b 100644 (file)
@@ -38,7 +38,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
        }
        sin->sin_family = AF_INET;
        sin->sin_addr.s_addr = in_aton(addr);
-       sin->sin_port = port;
+       sin->sin_port = htons(port);
        return(sin);
 }
 
@@ -55,28 +55,25 @@ static int mcast_open(void *data)
        struct mcast_data *pri = data;
        struct sockaddr_in *sin = pri->mcast_addr;
        struct ip_mreq mreq;
-       int fd, yes = 1;
+       int fd = -EINVAL, yes = 1, err = -EINVAL;;
 
 
-       if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
-               fd = -EINVAL;
+       if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
                goto out;
-       }
 
        fd = socket(AF_INET, SOCK_DGRAM, 0);
+
        if (fd < 0){
                printk("mcast_open : data socket failed, errno = %d\n", 
                       errno);
-               fd = -ENOMEM;
+               fd = -errno;
                goto out;
        }
 
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
                printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
                        errno);
-               os_close_file(fd);
-               fd = -EINVAL;
-               goto out;
+               goto out_close;
        }
 
        /* set ttl according to config */
@@ -84,26 +81,20 @@ static int mcast_open(void *data)
                       sizeof(pri->ttl)) < 0) {
                printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
                        errno);
-               os_close_file(fd);
-               fd = -EINVAL;
-               goto out;
+               goto out_close;
        }
 
        /* set LOOP, so data does get fed back to local sockets */
        if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
                printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
                        errno);
-               os_close_file(fd);
-               fd = -EINVAL;
-               goto out;
+               goto out_close;
        }
 
        /* bind socket to mcast address */
        if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
                printk("mcast_open : data bind failed, errno = %d\n", errno);
-               os_close_file(fd);
-               fd = -EINVAL;
-               goto out;
+               goto out_close;
        }               
        
        /* subscribe to the multicast group */
@@ -117,12 +108,15 @@ static int mcast_open(void *data)
                       "interface on the host.\n");
                printk("eth0 should be configured in order to use the "
                       "multicast transport.\n");
-               os_close_file(fd);
-               fd = -EINVAL;
+                goto out_close;
        }
 
  out:
-       return(fd);
+       return fd;
+
+ out_close:
+        os_close_file(fd);
+        return err;
 }
 
 static void mcast_close(int fd, void *data)
@@ -164,14 +158,3 @@ struct net_user_info mcast_user_info = {
        .delete_address = NULL,
        .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
 };
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index a63231dffe058efc6ace1a2364715fd39f081df4..a37a5ac13c22b8fb709d0ced7ec5db0a2629ce63 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/init.h> 
 #include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
@@ -117,24 +118,39 @@ static struct file_operations mmapper_fops = {
        .release        = mmapper_release,
 };
 
+static struct miscdevice mmapper_dev = {
+       .minor          = MISC_DYNAMIC_MINOR,
+       .name           = "mmapper",
+       .fops           = &mmapper_fops
+};
+
 static int __init mmapper_init(void)
 {
+       int err;
+
        printk(KERN_INFO "Mapper v0.1\n");
 
        v_buf = (char *) find_iomem("mmapper", &mmapper_size);
        if(mmapper_size == 0){
                printk(KERN_ERR "mmapper_init - find_iomem failed\n");
-               return(0);
+               goto out;
        }
 
-       p_buf = __pa(v_buf);
+       err = misc_register(&mmapper_dev);
+       if(err){
+               printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
+                      err);
+               goto out;
+       }
 
-       devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper");
-       return(0);
+       p_buf = __pa(v_buf);
+out:
+       return 0;
 }
 
 static void mmapper_exit(void)
 {
+       misc_deregister(&mmapper_dev);
 }
 
 module_init(mmapper_init);
index 47229fe4a8131022c13e09e4b2c660ab93b86013..3730d4f1271368e43ee147303973b8490ab153ea 100644 (file)
@@ -32,7 +32,7 @@ int tap_open_common(void *dev, char *gate_addr)
        return(0);
 }
 
-void tap_check_ips(char *gate_addr, char *eth_addr)
+void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
 {
        int tap_addr[4];
 
index d43e9fab05a769db0dfa53f84aa93527732a6155..f9e22198e011c911c7c2f1d36a1b8da742c2325e 100644 (file)
@@ -1,5 +1,10 @@
-/* Much of this ripped from hw_random.c */
-
+/* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */
+/* Much of this ripped from drivers/char/hw_random.c, see there for other
+ * copyright.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
@@ -12,8 +17,6 @@
  */
 #define RNG_VERSION "1.0.0"
 #define RNG_MODULE_NAME "random"
-#define RNG_DRIVER_NAME   RNG_MODULE_NAME " virtual driver " RNG_VERSION
-#define PFX RNG_MODULE_NAME ": "
 
 #define RNG_MISCDEV_MINOR              183 /* official */
 
@@ -98,7 +101,7 @@ static int __init rng_init (void)
 
        err = misc_register (&rng_miscdev);
        if (err) {
-               printk (KERN_ERR PFX "misc device register failed\n");
+               printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n");
                goto err_out_cleanup_hw;
        }
 
@@ -120,3 +123,6 @@ static void __exit rng_cleanup (void)
 
 module_init (rng_init);
 module_exit (rng_cleanup);
+
+MODULE_DESCRIPTION("UML Host Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL");
index 495f2f1b14202779b686bd93bb5dd053b8ac5bab..bb0dab41c2e43a464f5e7dbfe15c28aca84a197c 100644 (file)
@@ -1,10 +1,7 @@
 #ifndef __UM_SLIP_H
 #define __UM_SLIP_H
 
-#define BUF_SIZE 1500
- /* two bytes each for a (pathological) max packet of escaped chars +  * 
-  * terminating END char + initial END char                            */
-#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
+#include "slip_common.h"
 
 struct slip_data {
        void *dev;
@@ -12,28 +9,12 @@ struct slip_data {
        char *addr;
        char *gate_addr;
        int slave;
-       char ibuf[ENC_BUF_SIZE];
-       char obuf[ENC_BUF_SIZE];
-       int more; /* more data: do not read fd until ibuf has been drained */
-       int pos;
-       int esc;
+       struct slip_proto slip;
 };
 
 extern struct net_user_info slip_user_info;
 
-extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
 extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
 extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
 
 #endif
-
-/*
- * 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-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c
new file mode 100644 (file)
index 0000000..e89cfc6
--- /dev/null
@@ -0,0 +1,54 @@
+#include <string.h>
+#include "slip_common.h"
+#include "net_user.h"
+
+int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip)
+{
+       int i, n, size, start;
+
+       if(slip->more > 0){
+               i = 0;
+               while(i < slip->more){
+                       size = slip_unesc(slip->ibuf[i++], slip->ibuf,
+                                         &slip->pos, &slip->esc);
+                       if(size){
+                               memcpy(buf, slip->ibuf, size);
+                               memmove(slip->ibuf, &slip->ibuf[i],
+                                       slip->more - i);
+                               slip->more = slip->more - i;
+                               return size;
+                       }
+               }
+               slip->more = 0;
+       }
+
+       n = net_read(fd, &slip->ibuf[slip->pos],
+                    sizeof(slip->ibuf) - slip->pos);
+       if(n <= 0)
+               return n;
+
+       start = slip->pos;
+       for(i = 0; i < n; i++){
+               size = slip_unesc(slip->ibuf[start + i], slip->ibuf,&slip->pos,
+                                 &slip->esc);
+               if(size){
+                       memcpy(buf, slip->ibuf, size);
+                       memmove(slip->ibuf, &slip->ibuf[start+i+1],
+                               n - (i + 1));
+                       slip->more = n - (i + 1);
+                       return size;
+               }
+       }
+       return 0;
+}
+
+int slip_proto_write(int fd, void *buf, int len, struct slip_proto *slip)
+{
+       int actual, n;
+
+       actual = slip_esc(buf, slip->obuf, len);
+       n = net_write(fd, slip->obuf, actual);
+       if(n < 0)
+               return n;
+       else return len;
+}
diff --git a/arch/um/drivers/slip_common.h b/arch/um/drivers/slip_common.h
new file mode 100644 (file)
index 0000000..2ae76d8
--- /dev/null
@@ -0,0 +1,104 @@
+#ifndef __UM_SLIP_COMMON_H
+#define __UM_SLIP_COMMON_H
+
+#define BUF_SIZE 1500
+ /* two bytes each for a (pathological) max packet of escaped chars +  *
+  * terminating END char + initial END char                            */
+#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
+
+/* SLIP protocol characters. */
+#define SLIP_END             0300      /* indicates end of frame       */
+#define SLIP_ESC             0333      /* indicates byte stuffing      */
+#define SLIP_ESC_END         0334      /* ESC ESC_END means END 'data' */
+#define SLIP_ESC_ESC         0335      /* ESC ESC_ESC means ESC 'data' */
+
+static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos,
+                             int *esc)
+{
+       int ret;
+
+       switch(c){
+       case SLIP_END:
+               *esc = 0;
+               ret=*pos;
+               *pos=0;
+               return(ret);
+       case SLIP_ESC:
+               *esc = 1;
+               return(0);
+       case SLIP_ESC_ESC:
+               if(*esc){
+                       *esc = 0;
+                       c = SLIP_ESC;
+               }
+               break;
+       case SLIP_ESC_END:
+               if(*esc){
+                       *esc = 0;
+                       c = SLIP_END;
+               }
+               break;
+       }
+       buf[(*pos)++] = c;
+       return(0);
+}
+
+static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
+{
+       unsigned char *ptr = d;
+       unsigned char c;
+
+       /*
+        * Send an initial END character to flush out any
+        * data that may have accumulated in the receiver
+        * due to line noise.
+        */
+
+       *ptr++ = SLIP_END;
+
+       /*
+        * For each byte in the packet, send the appropriate
+        * character sequence, according to the SLIP protocol.
+        */
+
+       while (len-- > 0) {
+               switch(c = *s++) {
+               case SLIP_END:
+                       *ptr++ = SLIP_ESC;
+                       *ptr++ = SLIP_ESC_END;
+                       break;
+               case SLIP_ESC:
+                       *ptr++ = SLIP_ESC;
+                       *ptr++ = SLIP_ESC_ESC;
+                       break;
+               default:
+                       *ptr++ = c;
+                       break;
+               }
+       }
+       *ptr++ = SLIP_END;
+       return (ptr - d);
+}
+
+struct slip_proto {
+       unsigned char ibuf[ENC_BUF_SIZE];
+       unsigned char obuf[ENC_BUF_SIZE];
+       int more; /* more data: do not read fd until ibuf has been drained */
+       int pos;
+       int esc;
+};
+
+#define SLIP_PROTO_INIT { \
+       .ibuf   = { '\0' }, \
+       .obuf   = { '\0' }, \
+        .more  = 0, \
+       .pos    = 0, \
+       .esc    = 0 \
+}
+
+extern int slip_proto_read(int fd, void *buf, int len,
+                          struct slip_proto *slip);
+extern int slip_proto_write(int fd, void *buf, int len,
+                           struct slip_proto *slip);
+
+#endif
index 0886eedba213ad58926104b8c31b9899d39a82cc..9a6f5c85f902ad997a11538a51c8015a99fb5209 100644 (file)
@@ -26,16 +26,16 @@ void slip_init(struct net_device *dev, void *data)
                  .addr         = NULL,
                  .gate_addr    = init->gate_addr,
                  .slave        = -1,
-                 .ibuf         = { '\0' },
-                 .obuf         = { '\0' },
-                 .pos          = 0,
-                 .esc          = 0,
+                 .slip         = SLIP_PROTO_INIT,
                  .dev          = dev });
 
        dev->init = NULL;
+       dev->header_cache_update = NULL;
+       dev->hard_header_cache = NULL;
+       dev->hard_header = NULL;
        dev->hard_header_len = 0;
-       dev->addr_len = 4;
-       dev->type = ARPHRD_ETHER;
+       dev->addr_len = 0;
+       dev->type = ARPHRD_SLIP;
        dev->tx_queue_len = 256;
        dev->flags = IFF_NOARP;
        printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_proto.h
deleted file mode 100644 (file)
index 7206361..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __UM_SLIP_PROTO_H__
-#define __UM_SLIP_PROTO_H__
-
-/* SLIP protocol characters. */
-#define SLIP_END             0300      /* indicates end of frame       */
-#define SLIP_ESC             0333      /* indicates byte stuffing      */
-#define SLIP_ESC_END         0334      /* ESC ESC_END means END 'data' */
-#define SLIP_ESC_ESC         0335      /* ESC ESC_ESC means ESC 'data' */
-
-static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
-{
-       int ret;
-
-       switch(c){
-       case SLIP_END:
-               *esc = 0;
-               ret=*pos;
-               *pos=0;
-               return(ret);
-       case SLIP_ESC:
-               *esc = 1;
-               return(0);
-       case SLIP_ESC_ESC:
-               if(*esc){
-                       *esc = 0;
-                       c = SLIP_ESC;
-               }
-               break;
-       case SLIP_ESC_END:
-               if(*esc){
-                       *esc = 0;
-                       c = SLIP_END;
-               }
-               break;
-       }
-       buf[(*pos)++] = c;
-       return(0);
-}
-
-static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
-{
-       unsigned char *ptr = d;
-       unsigned char c;
-
-       /*
-        * Send an initial END character to flush out any
-        * data that may have accumulated in the receiver
-        * due to line noise.
-        */
-
-       *ptr++ = SLIP_END;
-
-       /*
-        * For each byte in the packet, send the appropriate
-        * character sequence, according to the SLIP protocol.
-        */
-
-       while (len-- > 0) {
-               switch(c = *s++) {
-               case SLIP_END:
-                       *ptr++ = SLIP_ESC;
-                       *ptr++ = SLIP_ESC_END;
-                       break;
-               case SLIP_ESC:
-                       *ptr++ = SLIP_ESC;
-                       *ptr++ = SLIP_ESC_ESC;
-                       break;
-               default:
-                       *ptr++ = c;
-                       break;
-               }
-       }
-       *ptr++ = SLIP_END;
-       return (ptr - d);
-}
-
-#endif
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index d94846b1b4cfd319e94bbeafbbeb21d7de5979ad..71af444e591f8bff7b097ac57dc85376529fb677 100644 (file)
@@ -13,7 +13,7 @@
 #include "user.h"
 #include "net_user.h"
 #include "slip.h"
-#include "slip_proto.h"
+#include "slip_common.h"
 #include "helper.h"
 #include "os.h"
 
@@ -77,41 +77,51 @@ static int slip_tramp(char **argv, int fd)
        err = os_pipe(fds, 1, 0);
        if(err < 0){
                printk("slip_tramp : pipe failed, err = %d\n", -err);
-               return(err);
+               goto out;
        }
 
        err = 0;
        pe_data.stdin = fd;
        pe_data.stdout = fds[1];
        pe_data.close_me = fds[0];
-       pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
+       err = run_helper(slip_pre_exec, &pe_data, argv, NULL);
+       if(err < 0)
+               goto out_close;
+       pid = err;
+
+       output_len = page_size();
+       output = um_kmalloc(output_len);
+       if(output == NULL){
+               printk("slip_tramp : failed to allocate output buffer\n");
+               os_kill_process(pid, 1);
+               err = -ENOMEM;
+               goto out_free;
+       }
 
-       if(pid < 0) err = pid;
-       else {
-               output_len = page_size();
-               output = um_kmalloc(output_len);
-               if(output == NULL)
-                       printk("slip_tramp : failed to allocate output "
-                              "buffer\n");
-
-               os_close_file(fds[1]);
-               read_output(fds[0], output, output_len);
-               if(output != NULL){
-                       printk("%s", output);
-                       kfree(output);
-               }
-               CATCH_EINTR(err = waitpid(pid, &status, 0));
-               if(err < 0)
-                       err = errno;
-               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
-                       printk("'%s' didn't exit with status 0\n", argv[0]);
-                       err = -EINVAL;
-               }
+       os_close_file(fds[1]);
+       read_output(fds[0], output, output_len);
+       printk("%s", output);
+
+       CATCH_EINTR(err = waitpid(pid, &status, 0));
+       if(err < 0)
+               err = errno;
+       else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
+               printk("'%s' didn't exit with status 0\n", argv[0]);
+               err = -EINVAL;
        }
+       else err = 0;
 
        os_close_file(fds[0]);
 
-       return(err);
+out_free:
+       kfree(output);
+       return err;
+
+out_close:
+       os_close_file(fds[0]);
+       os_close_file(fds[1]);
+out:
+       return err;
 }
 
 static int slip_open(void *data)
@@ -123,21 +133,26 @@ static int slip_open(void *data)
                         NULL };
        int sfd, mfd, err;
 
-       mfd = get_pty();
-       if(mfd < 0){
-               printk("umn : Failed to open pty, err = %d\n", -mfd);
-               return(mfd);
+       err = get_pty();
+       if(err < 0){
+               printk("slip-open : Failed to open pty, err = %d\n", -err);
+               goto out;
        }
-       sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
-       if(sfd < 0){
-               printk("Couldn't open tty for slip line, err = %d\n", -sfd);
-               os_close_file(mfd);
-               return(sfd);
+       mfd = err;
+
+       err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
+       if(err < 0){
+               printk("Couldn't open tty for slip line, err = %d\n", -err);
+               goto out_close;
        }
-       if(set_up_tty(sfd)) return(-1);
+       sfd = err;
+
+       if(set_up_tty(sfd))
+               goto out_close2;
+
        pri->slave = sfd;
-       pri->pos = 0;
-       pri->esc = 0;
+       pri->slip.pos = 0;
+       pri->slip.esc = 0;
        if(pri->gate_addr != NULL){
                sprintf(version_buf, "%d", UML_NET_VERSION);
                strcpy(gate_buf, pri->gate_addr);
@@ -146,12 +161,12 @@ static int slip_open(void *data)
 
                if(err < 0){
                        printk("slip_tramp failed - err = %d\n", -err);
-                       return(err);
+                       goto out_close2;
                }
                err = os_get_ifname(pri->slave, pri->name);
                if(err < 0){
                        printk("get_ifname failed, err = %d\n", -err);
-                       return(err);
+                       goto out_close2;
                }
                iter_addresses(pri->dev, open_addr, pri->name);
        }
@@ -160,10 +175,16 @@ static int slip_open(void *data)
                if(err < 0){
                        printk("Failed to set slip discipline encapsulation - "
                               "err = %d\n", -err);
-                       return(err);
+                       goto out_close2;
                }
        }
        return(mfd);
+out_close2:
+       os_close_file(sfd);
+out_close:
+       os_close_file(mfd);
+out:
+       return err;
 }
 
 static void slip_close(int fd, void *data)
@@ -190,48 +211,12 @@ static void slip_close(int fd, void *data)
 
 int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
 {
-       int i, n, size, start;
-
-       if(pri->more>0) {
-               i = 0;
-               while(i < pri->more) {
-                       size = slip_unesc(pri->ibuf[i++],
-                                       pri->ibuf, &pri->pos, &pri->esc);
-                       if(size){
-                               memcpy(buf, pri->ibuf, size);
-                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
-                               pri->more=pri->more-i; 
-                               return(size);
-                       }
-               }
-               pri->more=0;
-       }
-
-       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
-       if(n <= 0) return(n);
-
-       start = pri->pos;
-       for(i = 0; i < n; i++){
-               size = slip_unesc(pri->ibuf[start + i],
-                               pri->ibuf, &pri->pos, &pri->esc);
-               if(size){
-                       memcpy(buf, pri->ibuf, size);
-                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
-                       pri->more=n-(i+1); 
-                       return(size);
-               }
-       }
-       return(0);
+       return slip_proto_read(fd, buf, len, &pri->slip);
 }
 
 int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
 {
-       int actual, n;
-
-       actual = slip_esc(buf, pri->obuf, len);
-       n = net_write(fd, pri->obuf, actual);
-       if(n < 0) return(n);
-       else return(len);
+       return slip_proto_write(fd, buf, len, &pri->slip);
 }
 
 static int slip_set_mtu(int mtu, void *data)
@@ -267,14 +252,3 @@ struct net_user_info slip_user_info = {
        .delete_address = slip_del_addr,
        .max_packet     = BUF_SIZE
 };
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index 04e407d1e44aeceb18ec5ef6313816899a8bd068..6cf88ab580c99a7828fbf545fa8b427ec8b862b5 100644 (file)
@@ -1,10 +1,7 @@
 #ifndef __UM_SLIRP_H
 #define __UM_SLIRP_H
 
-#define BUF_SIZE 1500
- /* two bytes each for a (pathological) max packet of escaped chars +  * 
-  * terminating END char + initial END char                            */
-#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
+#include "slip_common.h"
 
 #define SLIRP_MAX_ARGS 100
 /*
@@ -24,28 +21,13 @@ struct slirp_data {
        struct arg_list_dummy_wrapper argw;
        int pid;
        int slave;
-       char ibuf[ENC_BUF_SIZE];
-       char obuf[ENC_BUF_SIZE];
-       int more; /* more data: do not read fd until ibuf has been drained */
-       int pos;
-       int esc;
+       struct slip_proto slip;
 };
 
 extern struct net_user_info slirp_user_info;
 
-extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
 extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
-extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
+extern int slirp_user_write(int fd, void *buf, int len,
+                           struct slirp_data *pri);
 
 #endif
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index c9d6b52a831de0c5836222bb14cf27bb3c760b0a..9864d27afdbe22f27319042030116caef12f93d9 100644 (file)
@@ -25,10 +25,7 @@ void slirp_init(struct net_device *dev, void *data)
                { .argw         = init->argw,
                  .pid          = -1,
                  .slave        = -1,
-                 .ibuf         = { '\0' },
-                 .obuf         = { '\0' },
-                 .pos          = 0,
-                 .esc          = 0,
+                 .slip         = SLIP_PROTO_INIT,
                  .dev          = dev });
 
        dev->init = NULL;
index c322515c71ccb4071cc6b0e4cf718720d047cbba..8d91f663d82c684267567f2489f8059b738590e8 100644 (file)
@@ -12,7 +12,7 @@
 #include "user.h"
 #include "net_user.h"
 #include "slirp.h"
-#include "slip_proto.h"
+#include "slip_common.h"
 #include "helper.h"
 #include "os.h"
 
@@ -48,47 +48,32 @@ static int slirp_tramp(char **argv, int fd)
        return(pid);
 }
 
-/* XXX This is just a trivial wrapper around os_pipe */
-static int slirp_datachan(int *mfd, int *sfd)
-{
-       int fds[2], err;
-
-       err = os_pipe(fds, 1, 1);
-       if(err < 0){
-               printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
-               return(err);
-       }
-
-       *mfd = fds[0];
-       *sfd = fds[1];
-       return(0);
-}
-
 static int slirp_open(void *data)
 {
        struct slirp_data *pri = data;
-       int sfd, mfd, pid, err;
+       int fds[2], pid, err;
 
-       err = slirp_datachan(&mfd, &sfd);
+       err = os_pipe(fds, 1, 1);
        if(err)
                return(err);
 
-       pid = slirp_tramp(pri->argw.argv, sfd);
-
-       if(pid < 0){
-               printk("slirp_tramp failed - errno = %d\n", -pid);
-               os_close_file(sfd);     
-               os_close_file(mfd);     
-               return(pid);
+       err = slirp_tramp(pri->argw.argv, fds[1]);
+       if(err < 0){
+               printk("slirp_tramp failed - errno = %d\n", -err);
+               goto out;
        }
-
-       pri->slave = sfd;
-       pri->pos = 0;
-       pri->esc = 0;
-
-       pri->pid = pid;
-
-       return(mfd);
+       pid = err;
+
+       pri->slave = fds[1];
+       pri->slip.pos = 0;
+       pri->slip.esc = 0;
+       pri->pid = err;
+
+       return(fds[0]);
+out:
+       os_close_file(fds[0]);
+       os_close_file(fds[1]);
+       return err;
 }
 
 static void slirp_close(int fd, void *data)
@@ -129,48 +114,12 @@ static void slirp_close(int fd, void *data)
 
 int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
 {
-       int i, n, size, start;
-
-       if(pri->more>0) {
-               i = 0;
-               while(i < pri->more) {
-                       size = slip_unesc(pri->ibuf[i++],
-                                       pri->ibuf,&pri->pos,&pri->esc);
-                       if(size){
-                               memcpy(buf, pri->ibuf, size);
-                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
-                               pri->more=pri->more-i; 
-                               return(size);
-                       }
-               }
-               pri->more=0;
-       }
-
-       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
-       if(n <= 0) return(n);
-
-       start = pri->pos;
-       for(i = 0; i < n; i++){
-               size = slip_unesc(pri->ibuf[start + i],
-                               pri->ibuf,&pri->pos,&pri->esc);
-               if(size){
-                       memcpy(buf, pri->ibuf, size);
-                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
-                       pri->more=n-(i+1); 
-                       return(size);
-               }
-       }
-       return(0);
+       return slip_proto_read(fd, buf, len, &pri->slip);
 }
 
 int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
 {
-       int actual, n;
-
-       actual = slip_esc(buf, pri->obuf, len);
-       n = net_write(fd, pri->obuf, actual);
-       if(n < 0) return(n);
-       else return(len);
+       return slip_proto_write(fd, buf, len, &pri->slip);
 }
 
 static int slirp_set_mtu(int mtu, void *data)
@@ -188,14 +137,3 @@ struct net_user_info slirp_user_info = {
        .delete_address = NULL,
        .max_packet     = BUF_SIZE
 };
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index a2bac429f3d41d8b1941969318b2831fc3750567..b32a77010fbe5743aace38839dcf21f477c7da25 100644 (file)
@@ -22,7 +22,6 @@
 #include "init.h"
 #include "irq_user.h"
 #include "mconsole_kern.h"
-#include "2_5compat.h"
 
 static int ssl_version = 1;
 
index 98565b53d170158a678a12b2ba72a582d4220854..429ae8e6c7e514f67fac718d9912828dec7e7768 100644 (file)
@@ -22,9 +22,9 @@ static void stderr_console_write(struct console *console, const char *string,
 }
 
 static struct console stderr_console = {
-       .name           "stderr",
-       .write          stderr_console_write,
-       .flags          CON_PRINTBUFFER,
+       .name           "stderr",
+       .write          stderr_console_write,
+       .flags          CON_PRINTBUFFER,
 };
 
 static int __init stderr_console_init(void)
index 361d0be342b3e68c717802ac0b3fa2dae4d10c0d..afbe1e71ed8310f36b2be4f8f633b61ca84af0a2 100644 (file)
@@ -28,7 +28,6 @@
 #include "irq_user.h"
 #include "mconsole_kern.h"
 #include "init.h"
-#include "2_5compat.h"
 
 #define MAX_TTYS (16)
 
index 9a56ff94308dff7a06a5b0fd5cff8ed3b14249ad..2a7f6892c55c203d66c03640acdccb8a3655b8e3 100644 (file)
 #include "irq_user.h"
 #include "irq_kern.h"
 #include "ubd_user.h"
-#include "2_5compat.h"
 #include "os.h"
 #include "mem.h"
 #include "mem_kern.h"
 #include "cow.h"
 
-enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
+enum ubd_req { UBD_READ, UBD_WRITE };
 
 struct io_thread_req {
        enum ubd_req op;
@@ -68,8 +67,6 @@ struct io_thread_req {
        unsigned long sector_mask;
        unsigned long long cow_offset;
        unsigned long bitmap_words[2];
-       int map_fd;
-       unsigned long long map_offset;
        int error;
 };
 
@@ -122,10 +119,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
 
 #define MAX_DEV (8)
 
-/* Changed in early boot */
-static int ubd_do_mmap = 0;
-#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
-
 static struct block_device_operations ubd_blops = {
         .owner         = THIS_MODULE,
         .open          = ubd_open,
@@ -175,12 +168,6 @@ struct ubd {
        int no_cow;
        struct cow cow;
        struct platform_device pdev;
-
-       int map_writes;
-       int map_reads;
-       int nomap_writes;
-       int nomap_reads;
-       int write_maps;
 };
 
 #define DEFAULT_COW { \
@@ -200,11 +187,6 @@ struct ubd {
        .openflags =            OPEN_FLAGS, \
         .no_cow =               0, \
         .cow =                 DEFAULT_COW, \
-       .map_writes             = 0, \
-       .map_reads              = 0, \
-       .nomap_writes           = 0, \
-       .nomap_reads            = 0, \
-       .write_maps             = 0, \
 }
 
 struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
@@ -314,13 +296,6 @@ static int ubd_setup_common(char *str, int *index_out)
                int major;
 
                str++;
-               if(!strcmp(str, "mmap")){
-                       CHOOSE_MODE(printk("mmap not supported by the ubd "
-                                          "driver in tt mode\n"),
-                                   ubd_do_mmap = 1);
-                       return(0);
-               }
-
                if(!strcmp(str, "sync")){
                        global_openflags = of_sync(global_openflags);
                        return(0);
@@ -464,9 +439,9 @@ static int udb_setup(char *str)
 __setup("udb", udb_setup);
 __uml_help(udb_setup,
 "udb\n"
-"    This option is here solely to catch ubd -> udb typos, which can be\n\n"
-"    to impossible to catch visually unless you specifically look for\n\n"
-"    them.  The only result of any option starting with 'udb' is an error\n\n"
+"    This option is here solely to catch ubd -> udb typos, which can be\n"
+"    to impossible to catch visually unless you specifically look for\n"
+"    them.  The only result of any option starting with 'udb' is an error\n"
 "    in the boot output.\n\n"
 );
 
@@ -524,7 +499,7 @@ static void ubd_handler(void)
 {
        struct io_thread_req req;
        struct request *rq = elv_next_request(ubd_queue);
-       int n, err;
+       int n;
 
        do_ubd = NULL;
        intr_count++;
@@ -538,19 +513,6 @@ static void ubd_handler(void)
                return;
        }
         
-       if((req.op != UBD_MMAP) &&
-          ((req.offset != ((__u64) (rq->sector)) << 9) ||
-           (req.length != (rq->current_nr_sectors) << 9)))
-               panic("I/O op mismatch");
-       
-       if(req.map_fd != -1){
-               err = physmem_subst_mapping(req.buffer, req.map_fd,
-                                           req.map_offset, 1);
-               if(err)
-                       printk("ubd_handler - physmem_subst_mapping failed, "
-                              "err = %d\n", -err);
-       }
-
        ubd_finish(rq, req.error);
        reactivate_fd(thread_fd, UBD_IRQ);      
        do_ubd_request(ubd_queue);
@@ -583,14 +545,10 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out)
 
 static void ubd_close(struct ubd *dev)
 {
-       if(ubd_do_mmap)
-               physmem_forget_descriptor(dev->fd);
        os_close_file(dev->fd);
        if(dev->cow.file == NULL)
                return;
 
-       if(ubd_do_mmap)
-               physmem_forget_descriptor(dev->cow.fd);
        os_close_file(dev->cow.fd);
        vfree(dev->cow.bitmap);
        dev->cow.bitmap = NULL;
@@ -1010,94 +968,13 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
                           req->bitmap_words, bitmap_len);
 }
 
-static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
-{
-       __u64 sector;
-       unsigned char *bitmap;
-       int bit, i;
-
-       /* mmap must have been requested on the command line */
-       if(!ubd_do_mmap)
-               return(-1);
-
-       /* The buffer must be page aligned */
-       if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
-               return(-1);
-
-       /* The request must be a page long */
-       if((req->current_nr_sectors << 9) != PAGE_SIZE)
-               return(-1);
-
-       if(dev->cow.file == NULL)
-               return(dev->fd);
-
-       sector = offset >> 9;
-       bitmap = (unsigned char *) dev->cow.bitmap;
-       bit = ubd_test_bit(sector, bitmap);
-
-       for(i = 1; i < req->current_nr_sectors; i++){
-               if(ubd_test_bit(sector + i, bitmap) != bit)
-                       return(-1);
-       }
-
-       if(bit || (rq_data_dir(req) == WRITE))
-               offset += dev->cow.data_offset;
-
-       /* The data on disk must be page aligned */
-       if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
-               return(-1);
-
-       return(bit ? dev->fd : dev->cow.fd);
-}
-
-static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
-                               struct request *req,
-                               struct io_thread_req *io_req)
-{
-       int err;
-
-       if(rq_data_dir(req) == WRITE){
-               /* Writes are almost no-ops since the new data is already in the
-                * host page cache
-                */
-               dev->map_writes++;
-               if(dev->cow.file != NULL)
-                       cowify_bitmap(io_req->offset, io_req->length,
-                                     &io_req->sector_mask, &io_req->cow_offset,
-                                     dev->cow.bitmap, dev->cow.bitmap_offset,
-                                     io_req->bitmap_words,
-                                     dev->cow.bitmap_len);
-       }
-       else {
-               int w;
-
-               if((dev->cow.file != NULL) && (fd == dev->cow.fd))
-                       w = 0;
-               else w = dev->openflags.w;
-
-               if((dev->cow.file != NULL) && (fd == dev->fd))
-                       offset += dev->cow.data_offset;
-
-               err = physmem_subst_mapping(req->buffer, fd, offset, w);
-               if(err){
-                       printk("physmem_subst_mapping failed, err = %d\n",
-                              -err);
-                       return(1);
-               }
-               dev->map_reads++;
-       }
-       io_req->op = UBD_MMAP;
-       io_req->buffer = req->buffer;
-       return(0);
-}
-
 /* Called with ubd_io_lock held */
 static int prepare_request(struct request *req, struct io_thread_req *io_req)
 {
        struct gendisk *disk = req->rq_disk;
        struct ubd *dev = disk->private_data;
        __u64 offset;
-       int len, fd;
+       int len;
 
        if(req->rq_status == RQ_INACTIVE) return(1);
 
@@ -1114,34 +991,12 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
 
        io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
        io_req->fds[1] = dev->fd;
-       io_req->map_fd = -1;
        io_req->cow_offset = -1;
        io_req->offset = offset;
        io_req->length = len;
        io_req->error = 0;
        io_req->sector_mask = 0;
 
-       fd = mmap_fd(req, dev, io_req->offset);
-       if(fd > 0){
-               /* If mmapping is otherwise OK, but the first access to the
-                * page is a write, then it's not mapped in yet.  So we have
-                * to write the data to disk first, then we can map the disk
-                * page in and continue normally from there.
-                */
-               if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
-                       io_req->map_fd = dev->fd;
-                       io_req->map_offset = io_req->offset +
-                               dev->cow.data_offset;
-                       dev->write_maps++;
-               }
-               else return(prepare_mmap_request(dev, fd, io_req->offset, req,
-                                                io_req));
-       }
-
-       if(rq_data_dir(req) == READ)
-               dev->nomap_reads++;
-       else dev->nomap_writes++;
-
        io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
        io_req->offsets[0] = 0;
        io_req->offsets[1] = dev->cow.data_offset;
@@ -1229,143 +1084,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
        return(-EINVAL);
 }
 
-static int ubd_check_remapped(int fd, unsigned long address, int is_write,
-                             __u64 offset)
-{
-       __u64 bitmap_offset;
-       unsigned long new_bitmap[2];
-       int i, err, n;
-
-       /* If it's not a write access, we can't do anything about it */
-       if(!is_write)
-               return(0);
-
-       /* We have a write */
-       for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
-               struct ubd *dev = &ubd_dev[i];
-
-               if((dev->fd != fd) && (dev->cow.fd != fd))
-                       continue;
-
-               /* It's a write to a ubd device */
-
-               /* This should be impossible now */
-               if(!dev->openflags.w){
-                       /* It's a write access on a read-only device - probably
-                        * shouldn't happen.  If the kernel is trying to change
-                        * something with no intention of writing it back out,
-                        * then this message will clue us in that this needs
-                        * fixing
-                        */
-                       printk("Write access to mapped page from readonly ubd "
-                              "device %d\n", i);
-                       return(0);
-               }
-
-               /* It's a write to a writeable ubd device - it must be COWed
-                * because, otherwise, the page would have been mapped in
-                * writeable
-                */
-
-               if(!dev->cow.file)
-                       panic("Write fault on writeable non-COW ubd device %d",
-                             i);
-
-               /* It should also be an access to the backing file since the
-                * COW pages should be mapped in read-write
-                */
-
-               if(fd == dev->fd)
-                       panic("Write fault on a backing page of ubd "
-                             "device %d\n", i);
-
-               /* So, we do the write, copying the backing data to the COW
-                * file...
-                */
-
-               err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
-               if(err < 0)
-                       panic("Couldn't seek to %lld in COW file of ubd "
-                             "device %d, err = %d",
-                             offset + dev->cow.data_offset, i, -err);
-
-               n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
-               if(n != PAGE_SIZE)
-                       panic("Couldn't copy data to COW file of ubd "
-                             "device %d, err = %d", i, -n);
-
-               /* ... updating the COW bitmap... */
-
-               cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
-                             dev->cow.bitmap, dev->cow.bitmap_offset,
-                             new_bitmap, dev->cow.bitmap_len);
-
-               err = os_seek_file(dev->fd, bitmap_offset);
-               if(err < 0)
-                       panic("Couldn't seek to %lld in COW file of ubd "
-                             "device %d, err = %d", bitmap_offset, i, -err);
-
-               n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
-               if(n != sizeof(new_bitmap))
-                       panic("Couldn't update bitmap  of ubd device %d, "
-                             "err = %d", i, -n);
-
-               /* Maybe we can map the COW page in, and maybe we can't.  If
-                * it is a pre-V3 COW file, we can't, since the alignment will
-                * be wrong.  If it is a V3 or later COW file which has been
-                * moved to a system with a larger page size, then maybe we
-                * can't, depending on the exact location of the page.
-                */
-
-               offset += dev->cow.data_offset;
-
-               /* Remove the remapping, putting the original anonymous page
-                * back.  If the COW file can be mapped in, that is done.
-                * Otherwise, the COW page is read in.
-                */
-
-               if(!physmem_remove_mapping((void *) address))
-                       panic("Address 0x%lx not remapped by ubd device %d",
-                             address, i);
-               if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
-                       physmem_subst_mapping((void *) address, dev->fd,
-                                             offset, 1);
-               else {
-                       err = os_seek_file(dev->fd, offset);
-                       if(err < 0)
-                               panic("Couldn't seek to %lld in COW file of "
-                                     "ubd device %d, err = %d", offset, i,
-                                     -err);
-
-                       n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
-                       if(n != PAGE_SIZE)
-                               panic("Failed to read page from offset %llx of "
-                                     "COW file of ubd device %d, err = %d",
-                                     offset, i, -n);
-               }
-
-               return(1);
-       }
-
-       /* It's not a write on a ubd device */
-       return(0);
-}
-
-static struct remapper ubd_remapper = {
-       .list   = LIST_HEAD_INIT(ubd_remapper.list),
-       .proc   = ubd_check_remapped,
-};
-
-static int ubd_remapper_setup(void)
-{
-       if(ubd_do_mmap)
-               register_remapper(&ubd_remapper);
-
-       return(0);
-}
-
-__initcall(ubd_remapper_setup);
-
 static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
 {
        struct uml_stat buf1, buf2;
@@ -1568,15 +1286,6 @@ void do_io(struct io_thread_req *req)
        int err;
        __u64 off;
 
-       if(req->op == UBD_MMAP){
-               /* Touch the page to force the host to do any necessary IO to
-                * get it into memory
-                */
-               n = *((volatile int *) req->buffer);
-               req->error = update_bitmap(req);
-               return;
-       }
-
        nsectors = req->length / req->sectorsize;
        start = 0;
        do {
index 7917b9d1cec8fa0fde9d4107dd5603862059ff05..a4fdf3584ad2c455e6165de1f88e5cc9a75ce62b 100644 (file)
@@ -7,7 +7,6 @@
 #include "linux/slab.h"
 #include "linux/signal.h"
 #include "linux/interrupt.h"
-#include "asm/semaphore.h"
 #include "asm/irq.h"
 #include "irq_user.h"
 #include "irq_kern.h"
diff --git a/arch/um/include/2_5compat.h b/arch/um/include/2_5compat.h
deleted file mode 100644 (file)
index abdb015..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __2_5_COMPAT_H__
-#define __2_5_COMPAT_H__
-
-#define INIT_HARDSECT(arr, maj, sizes)
-
-#define SET_PRI(task) do ; while(0)
-
-#endif
-
-/*
- * 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-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
new file mode 100644 (file)
index 0000000..d705daa
--- /dev/null
@@ -0,0 +1,14 @@
+/* for use by sys-$SUBARCH/kernel-offsets.c */
+
+OFFSET(TASK_REGS, task_struct, thread.regs);
+OFFSET(TASK_PID, task_struct, pid);
+DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
+DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
+DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
+DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
+DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
+DEFINE_STR(UM_KERN_ERR, KERN_ERR);
+DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
+DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
+DEFINE_STR(UM_KERN_INFO, KERN_INFO);
+DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
index 15389c886b41272c5e05eccdcdc576e0b5bbb9cb..e5fec5570199851967a4d501aa683932c4164900 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "linux/threads.h"
 #include "sysdep/ptrace.h"
+#include "sysdep/faultinfo.h"
 
 extern int ncpus;
 extern char *linux_prog;
@@ -31,8 +32,8 @@ extern int current_pid(void);
 extern unsigned long alloc_stack(int order, int atomic);
 extern int do_signal(void);
 extern int is_stack_fault(unsigned long sp);
-extern unsigned long segv(unsigned long address, unsigned long ip, 
-                         int is_write, int is_user, void *sc);
+extern unsigned long segv(struct faultinfo fi, unsigned long ip,
+                         int is_user, void *sc);
 extern int handle_page_fault(unsigned long address, unsigned long ip,
                             int is_write, int is_user, int *code_out);
 extern void syscall_ready(void);
@@ -82,7 +83,7 @@ extern void timer_irq(union uml_pt_regs *regs);
 extern void unprotect_stack(unsigned long stack);
 extern void do_uml_exitcalls(void);
 extern int attach_debugger(int idle_pid, int pid, int stop);
-extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
+extern void bad_segv(struct faultinfo fi, unsigned long ip);
 extern int config_gdb(char *str);
 extern int remove_gdb(void);
 extern char *uml_strdup(char *string);
index 9fbe3083fdd8c70c7e2ac74e8dbe4f5d7dd238fc..cfa368e045a548b76aa2bd05677effbf584d07f7 100644 (file)
@@ -56,7 +56,7 @@ struct mc_request
        int as_interrupt;
 
        int originating_fd;
-       int originlen;
+       unsigned int originlen;
        unsigned char origin[128];                      /* sockaddr_un */
 
        struct mconsole_request request;
index 36807b796e9ffe542e57397034899a91691b898f..89885a77a771f203edbbf39d6fadd6742e54e2e2 100644 (file)
@@ -35,7 +35,7 @@ extern void *get_output_buffer(int *len_out);
 extern void free_output_buffer(void *buffer);
 
 extern int tap_open_common(void *dev, char *gate_addr);
-extern void tap_check_ips(char *gate_addr, char *eth_addr);
+extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr);
 
 extern void read_output(int fd, char *output_out, int len);
 
index 07340c8cf20305c5a2985f8d93915f213e7f5f03..881d2988d2d80ef2564a41309edf0c93099f4edd 100644 (file)
@@ -136,7 +136,7 @@ extern int os_seek_file(int fd, __u64 offset);
 extern int os_open_file(char *file, struct openflags flags, int mode);
 extern int os_read_file(int fd, void *buf, int len);
 extern int os_write_file(int fd, const void *buf, int count);
-extern int os_file_size(char *file, long long *size_out);
+extern int os_file_size(char *file, unsigned long long *size_out);
 extern int os_file_modtime(char *file, unsigned long *modtime);
 extern int os_pipe(int *fd, int stream, int close_on_exec);
 extern int os_set_fd_async(int fd, int owner);
@@ -160,6 +160,7 @@ extern void os_kill_process(int pid, int reap_child);
 extern void os_kill_ptraced_process(int pid, int reap_child);
 extern void os_usr1_process(int pid);
 extern int os_getpid(void);
+extern int os_getpgrp(void);
 
 extern int os_map_memory(void *virt, int fd, unsigned long long off,
                         unsigned long len, int r, int w, int x);
index cfb5fb4f5b91ff4202ef109c10468d40b31ca43d..cd2327d09c8dfe669732182bf7e4e8537a2e6482 100644 (file)
@@ -6,22 +6,11 @@
 #ifndef __SKAS_PTRACE_H
 #define __SKAS_PTRACE_H
 
-struct ptrace_faultinfo {
-       int is_write;
-       unsigned long addr;
-};
-
-struct ptrace_ldt {
-       int func;
-       void *ptr;
-       unsigned long bytecount;
-};
-
 #define PTRACE_FAULTINFO 52
-#define PTRACE_SIGPENDING 53
-#define PTRACE_LDT 54
 #define PTRACE_SWITCH_MM 55
 
+#include "sysdep/skas_ptrace.h"
+
 #endif
 
 /*
index 3a2a45811aa3e89fcc5743d8ead8d6bb2e215376..764ba4db4788064965ea824a498025436d88441b 100644 (file)
 unsigned int csum_partial(const unsigned char * buff, int len, 
                          unsigned int sum);
 
-/*
- * the same as csum_partial, but copies from src while it
- * checksums, and handles user-space pointer exceptions correctly, when needed.
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst,
-                                 int len, int sum, int *err_ptr);
-unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst,
-                                   int len, int sum, int *err_ptr);
-
 /*
  *     Note: when you get a NULL pointer exception here this means someone
  *     passed in an incorrect kernel address to one of these functions.
@@ -52,11 +39,24 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
        return(csum_partial(dst, len, sum));
 }
 
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums, and handles user-space pointer exceptions correctly, when needed.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
 static __inline__
 unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
                                         int len, int sum, int *err_ptr)
 {
-       return csum_partial_copy_from(src, dst, len, sum, err_ptr);
+       if(copy_from_user(dst, src, len)){
+               *err_ptr = -EFAULT;
+               return(-1);
+       }
+
+       return csum_partial(dst, len, sum);
 }
 
 /*
@@ -67,7 +67,6 @@ unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char
  */
 
 #define csum_partial_copy_fromuser csum_partial_copy_from_user
-unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum);
 
 /*
  *     This is a version of ip_compute_csum() optimized for IP headers,
@@ -196,8 +195,14 @@ static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src,
                                                     unsigned char *dst,
                                                     int len, int sum, int *err_ptr)
 {
-       if (access_ok(VERIFY_WRITE, dst, len))
-               return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
+       if (access_ok(VERIFY_WRITE, dst, len)){
+               if(copy_to_user(dst, src, len)){
+                       *err_ptr = -EFAULT;
+                       return(-1);
+               }
+
+               return csum_partial(src, len, sum);
+       }
 
        if (len)
                *err_ptr = -EFAULT;
diff --git a/arch/um/include/sysdep-i386/faultinfo.h b/arch/um/include/sysdep-i386/faultinfo.h
new file mode 100644 (file)
index 0000000..db437cc
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ * Licensed under the GPL
+ */
+
+#ifndef __FAULTINFO_I386_H
+#define __FAULTINFO_I386_H
+
+/* this structure contains the full arch-specific faultinfo
+ * from the traps.
+ * On i386, ptrace_faultinfo unfortunately doesn't provide
+ * all the info, since trap_no is missing.
+ * All common elements are defined at the same position in
+ * both structures, thus making it easy to copy the
+ * contents without knowledge about the structure elements.
+ */
+struct faultinfo {
+        int error_code; /* in ptrace_faultinfo misleadingly called is_write */
+        unsigned long cr2; /* in ptrace_faultinfo called addr */
+        int trap_no; /* missing in ptrace_faultinfo */
+};
+
+#define FAULT_WRITE(fi) ((fi).error_code & 2)
+#define FAULT_ADDRESS(fi) ((fi).cr2)
+
+#define PTRACE_FULL_FAULTINFO 0
+
+#endif
index 661d495e2044888572abb7c7aeb4609dae07876b..c8ee9559f3ab2d3994fc83e424627b9c53993607 100644 (file)
@@ -8,6 +8,8 @@
 
 #include "uml-config.h"
 #include "user_constants.h"
+#include "sysdep/faultinfo.h"
+#include "choose-mode.h"
 
 #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
 #define MAX_REG_OFFSET (UM_FRAME_SIZE)
@@ -53,24 +55,17 @@ extern int sysemu_supported;
 
 #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
 
-#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
-
-#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
-
-#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
-
 #endif
 #ifndef PTRACE_SYSEMU_SINGLESTEP
 #define PTRACE_SYSEMU_SINGLESTEP 32
 #endif
 
-#include "choose-mode.h"
-
 union uml_pt_regs {
 #ifdef UML_CONFIG_MODE_TT
        struct tt_regs {
                long syscall;
                void *sc;
+                struct faultinfo faultinfo;
        } tt;
 #endif
 #ifdef UML_CONFIG_MODE_SKAS
@@ -78,9 +73,7 @@ union uml_pt_regs {
                unsigned long regs[HOST_FRAME_SIZE];
                unsigned long fp[HOST_FP_SIZE];
                unsigned long xfp[HOST_XFP_SIZE];
-               unsigned long fault_addr;
-               unsigned long fault_type;
-               unsigned long trap_type;
+                struct faultinfo faultinfo;
                long syscall;
                int is_user;
        } skas;
@@ -217,15 +210,8 @@ struct syscall_args {
 #define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
 #define UPT_SYSCALL_RET(r) UPT_EAX(r)
 
-#define UPT_SEGV_IS_FIXABLE(r) \
-       CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
-                    REGS_SEGV_IS_FIXABLE(&r->skas))
-
-#define UPT_FAULT_ADDR(r) \
-       __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
-
-#define UPT_FAULT_WRITE(r) \
-       CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
+#define UPT_FAULTINFO(r) \
+        CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
 
 #endif
 
index dfee589de3608ab2e8ca42838020c74a2c87202f..1fe729265167ad6cfc796cd30957e5ffcff09aa8 100644 (file)
 #define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
 #define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
 
-#define SC_FAULT_ADDR(sc) SC_CR2(sc)
-#define SC_FAULT_TYPE(sc) SC_ERR(sc)
-
-#define FAULT_WRITE(err) (err & 2)
-#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
-
-#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
-
-#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
+#define GET_FAULTINFO_FROM_SC(fi,sc) \
+       { \
+               (fi).cr2 = SC_CR2(sc); \
+               (fi).error_code = SC_ERR(sc); \
+               (fi).trap_no = SC_TRAPNO(sc); \
+       }
 
 /* ptrace expects that, at the start of a system call, %eax contains
  * -ENOSYS, so this makes it so.
@@ -29,9 +26,7 @@
 #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
 
 /* This is Page Fault */
-#define SEGV_IS_FIXABLE(trap) (trap == 14)
-
-#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
+#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
 
 extern unsigned long *sc_sigmask(void *sc_ptr);
 extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
index b1e1f7a77499920266f47a4c520cb90a7c78f32a..07518b16213619a1d88649ceb1ed84dd019cae2d 100644 (file)
@@ -8,6 +8,8 @@
 
 #include <signal.h>
 
+#define ARCH_SIGHDLR_PARAM int sig
+
 #define ARCH_GET_SIGCONTEXT(sc, sig) \
        do sc = (struct sigcontext *) (&sig + 1); while(0)
 
diff --git a/arch/um/include/sysdep-i386/skas_ptrace.h b/arch/um/include/sysdep-i386/skas_ptrace.h
new file mode 100644 (file)
index 0000000..e27b8a7
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_I386_SKAS_PTRACE_H
+#define __SYSDEP_I386_SKAS_PTRACE_H
+
+struct ptrace_faultinfo {
+        int is_write;
+        unsigned long addr;
+};
+
+struct ptrace_ldt {
+        int func;
+        void *ptr;
+        unsigned long bytecount;
+};
+
+#define PTRACE_LDT 54
+
+#endif
diff --git a/arch/um/include/sysdep-ia64/skas_ptrace.h b/arch/um/include/sysdep-ia64/skas_ptrace.h
new file mode 100644 (file)
index 0000000..25a38e7
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_IA64_SKAS_PTRACE_H
+#define __SYSDEP_IA64_SKAS_PTRACE_H
+
+struct ptrace_faultinfo {
+        int is_write;
+        unsigned long addr;
+};
+
+struct ptrace_ldt {
+        int func;
+        void *ptr;
+        unsigned long bytecount;
+};
+
+#define PTRACE_LDT 54
+
+#endif
diff --git a/arch/um/include/sysdep-ppc/skas_ptrace.h b/arch/um/include/sysdep-ppc/skas_ptrace.h
new file mode 100644 (file)
index 0000000..d9fbbac
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_PPC_SKAS_PTRACE_H
+#define __SYSDEP_PPC_SKAS_PTRACE_H
+
+struct ptrace_faultinfo {
+        int is_write;
+        unsigned long addr;
+};
+
+struct ptrace_ldt {
+        int func;
+        void *ptr;
+        unsigned long bytecount;
+};
+
+#define PTRACE_LDT 54
+
+#endif
index 572c6c19be33b3ea0e496ea803011040db5cfb4f..ea97005af69443883110f3573035b6cf5f5ab753 100644 (file)
@@ -9,8 +9,6 @@
 #include "linux/in6.h"
 #include "asm/uaccess.h"
 
-extern unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, int len,
-                                          int sum, int *err_ptr);
 extern unsigned csum_partial(const unsigned char *buff, unsigned len,
                              unsigned sum);
 
@@ -31,10 +29,15 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
 }
 
 static __inline__
-unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
-                                        int len, int sum, int *err_ptr)
+unsigned int csum_partial_copy_from_user(const unsigned char *src,
+                                         unsigned char *dst, int len, int sum,
+                                         int *err_ptr)
 {
-       return csum_partial_copy_from(src, dst, len, sum, err_ptr);
+        if(copy_from_user(dst, src, len)){
+                *err_ptr = -EFAULT;
+                return(-1);
+        }
+        return csum_partial(dst, len, sum);
 }
 
 /**
@@ -137,15 +140,6 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b)
         return a;
 }
 
-#endif
+extern unsigned short ip_compute_csum(unsigned char * buff, int len);
 
-/*
- * 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-file-style: "linux"
- * End:
- */
+#endif
diff --git a/arch/um/include/sysdep-x86_64/faultinfo.h b/arch/um/include/sysdep-x86_64/faultinfo.h
new file mode 100644 (file)
index 0000000..cb917b0
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ * Licensed under the GPL
+ */
+
+#ifndef __FAULTINFO_X86_64_H
+#define __FAULTINFO_X86_64_H
+
+/* this structure contains the full arch-specific faultinfo
+ * from the traps.
+ * On i386, ptrace_faultinfo unfortunately doesn't provide
+ * all the info, since trap_no is missing.
+ * All common elements are defined at the same position in
+ * both structures, thus making it easy to copy the
+ * contents without knowledge about the structure elements.
+ */
+struct faultinfo {
+        int error_code; /* in ptrace_faultinfo misleadingly called is_write */
+        unsigned long cr2; /* in ptrace_faultinfo called addr */
+        int trap_no; /* missing in ptrace_faultinfo */
+};
+
+#define FAULT_WRITE(fi) ((fi).error_code & 2)
+#define FAULT_ADDRESS(fi) ((fi).cr2)
+
+#define PTRACE_FULL_FAULTINFO 1
+
+#endif
index 915c82daffbd6bb742031a1eea49a57498b32d40..be8acd5efd974ac9a3b36a2b3a7703d332900996 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "uml-config.h"
 #include "user_constants.h"
+#include "sysdep/faultinfo.h"
 
 #define MAX_REG_OFFSET (UM_FRAME_SIZE)
 #define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
@@ -83,6 +84,7 @@ union uml_pt_regs {
                long syscall;
                unsigned long orig_rax;
                void *sc;
+                struct faultinfo faultinfo;
        } tt;
 #endif
 #ifdef UML_CONFIG_MODE_SKAS
@@ -90,9 +92,7 @@ union uml_pt_regs {
                /* XXX */
                unsigned long regs[27];
                unsigned long fp[65];
-               unsigned long fault_addr;
-               unsigned long fault_type;
-               unsigned long trap_type;
+                struct faultinfo faultinfo;
                long syscall;
                int is_user;
        } skas;
@@ -135,6 +135,7 @@ extern int mode_tt;
        __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
 #define UPT_SC(r) ((r)->tt.sc)
 #define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
+#define UPT_SYSCALL_RET(r) UPT_RAX(r)
 
 extern int user_context(unsigned long sp);
 
@@ -196,32 +197,32 @@ struct syscall_args {
 
 
 #define UPT_SET(regs, reg, val) \
-        ({      unsigned long val; \
+        ({      unsigned long __upt_val = val; \
                 switch(reg){ \
-               case R8: UPT_R8(regs) = val; break; \
-               case R9: UPT_R9(regs) = val; break; \
-               case R10: UPT_R10(regs) = val; break; \
-               case R11: UPT_R11(regs) = val; break; \
-               case R12: UPT_R12(regs) = val; break; \
-               case R13: UPT_R13(regs) = val; break; \
-               case R14: UPT_R14(regs) = val; break; \
-               case R15: UPT_R15(regs) = val; break; \
-                case RIP: UPT_IP(regs) = val; break; \
-                case RSP: UPT_SP(regs) = val; break; \
-                case RAX: UPT_RAX(regs) = val; break; \
-                case RBX: UPT_RBX(regs) = val; break; \
-                case RCX: UPT_RCX(regs) = val; break; \
-                case RDX: UPT_RDX(regs) = val; break; \
-                case RSI: UPT_RSI(regs) = val; break; \
-                case RDI: UPT_RDI(regs) = val; break; \
-                case RBP: UPT_RBP(regs) = val; break; \
-                case ORIG_RAX: UPT_ORIG_RAX(regs) = val; break; \
-                case CS: UPT_CS(regs) = val; break; \
-                case DS: UPT_DS(regs) = val; break; \
-                case ES: UPT_ES(regs) = val; break; \
-                case FS: UPT_FS(regs) = val; break; \
-                case GS: UPT_GS(regs) = val; break; \
-                case EFLAGS: UPT_EFLAGS(regs) = val; break; \
+                case R8: UPT_R8(regs) = __upt_val; break; \
+                case R9: UPT_R9(regs) = __upt_val; break; \
+                case R10: UPT_R10(regs) = __upt_val; break; \
+                case R11: UPT_R11(regs) = __upt_val; break; \
+                case R12: UPT_R12(regs) = __upt_val; break; \
+                case R13: UPT_R13(regs) = __upt_val; break; \
+                case R14: UPT_R14(regs) = __upt_val; break; \
+                case R15: UPT_R15(regs) = __upt_val; break; \
+                case RIP: UPT_IP(regs) = __upt_val; break; \
+                case RSP: UPT_SP(regs) = __upt_val; break; \
+                case RAX: UPT_RAX(regs) = __upt_val; break; \
+                case RBX: UPT_RBX(regs) = __upt_val; break; \
+                case RCX: UPT_RCX(regs) = __upt_val; break; \
+                case RDX: UPT_RDX(regs) = __upt_val; break; \
+                case RSI: UPT_RSI(regs) = __upt_val; break; \
+                case RDI: UPT_RDI(regs) = __upt_val; break; \
+                case RBP: UPT_RBP(regs) = __upt_val; break; \
+                case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
+                case CS: UPT_CS(regs) = __upt_val; break; \
+                case DS: UPT_DS(regs) = __upt_val; break; \
+                case ES: UPT_ES(regs) = __upt_val; break; \
+                case FS: UPT_FS(regs) = __upt_val; break; \
+                case GS: UPT_GS(regs) = __upt_val; break; \
+                case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
                 default :  \
                         panic("Bad register in UPT_SET : %d\n", reg);  \
                        break; \
@@ -241,24 +242,7 @@ struct syscall_args {
        CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
                     REGS_SEGV_IS_FIXABLE(&r->skas))
 
-#define UPT_FAULT_ADDR(r) \
-       __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
-
-#define UPT_FAULT_WRITE(r) \
-       CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
-
-#define UPT_TRAP(r) __CHOOSE_MODE(SC_TRAP_TYPE(UPT_SC(r)), REGS_TRAP(&r->skas))
-#define UPT_ERR(r) __CHOOSE_MODE(SC_FAULT_TYPE(UPT_SC(r)), REGS_ERR(&r->skas))
+#define UPT_FAULTINFO(r) \
+        CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
 
 #endif
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index 1e38a54ff4cf3167d2f7fdac49c278e33cdf3f21..2a78260d15a0d550cf348d4ad9ce7f8f58a12a47 100644 (file)
 #define SC_FAULT_ADDR(sc) SC_CR2(sc)
 #define SC_FAULT_TYPE(sc) SC_ERR(sc)
 
-#define FAULT_WRITE(err) ((err) & 2)
-
-#define SC_FAULT_WRITE(sc) FAULT_WRITE(SC_FAULT_TYPE(sc))
-
-#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
+#define GET_FAULTINFO_FROM_SC(fi,sc) \
+       { \
+               (fi).cr2 = SC_CR2(sc); \
+               (fi).error_code = SC_ERR(sc); \
+               (fi).trap_no = SC_TRAPNO(sc); \
+       }
 
 /* ptrace expects that, at the start of a system call, %eax contains
  * -ENOSYS, so this makes it so.
@@ -29,8 +30,8 @@
 
 #define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
 
-#define SEGV_IS_FIXABLE(trap) ((trap) == 14)
-#define SC_SEGV_IS_FIXABLE(sc) SEGV_IS_FIXABLE(SC_TRAP_TYPE(sc))
+/* This is Page Fault */
+#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
 
 extern unsigned long *sc_sigmask(void *sc_ptr);
 
index e5e52756fab4fb97ea26c69de8bb980817d1dbb4..6142897af3d11c2f5289115f8726e9202a52cb6e 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef __X86_64_SIGNAL_H_
 #define __X86_64_SIGNAL_H_
 
+#define ARCH_SIGHDLR_PARAM int sig
+
 #define ARCH_GET_SIGCONTEXT(sc, sig_addr) \
        do { \
                struct ucontext *__uc; \
diff --git a/arch/um/include/sysdep-x86_64/skas_ptrace.h b/arch/um/include/sysdep-x86_64/skas_ptrace.h
new file mode 100644 (file)
index 0000000..95db4be
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_SKAS_PTRACE_H
+#define __SYSDEP_X86_64_SKAS_PTRACE_H
+
+struct ptrace_faultinfo {
+        int is_write;
+        unsigned long addr;
+};
+
+struct ptrace_ldt {
+        int func;
+        void *ptr;
+        unsigned long bytecount;
+};
+
+#define PTRACE_LDT 54
+
+#endif
index 2ce9423460b3858f5fc68db67d2fc1d85b90d865..c8d332b56b98b636adb113eef91ec1372cef2a92 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __UM_SYSRQ_H
 #define __UM_SYSRQ_H
 
-extern void show_trace(unsigned long *stack);
+struct task_struct;
+extern void show_trace(struct task_struct* task, unsigned long *stack);
 
 #endif
index 103cd320386cfe56c2b15a6079e6d0bf93cd177e..7b6a24dfd302b7b90388a164c72e6c9ee79219f2 100644 (file)
@@ -41,9 +41,6 @@ extern unsigned long highmem;
 extern char host_info[];
 
 extern char saved_command_line[];
-extern char command_line[];
-
-extern char *tempdir;
 
 extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
 extern unsigned long _unprotected_end;
@@ -67,7 +64,6 @@ extern void *um_kmalloc(int size);
 extern int switcheroo(int fd, int prot, void *from, void *to, int size);
 extern void setup_machinename(char *machine_out);
 extern void setup_hostinfo(void);
-extern void add_arg(char *arg);
 extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
 extern void init_new_thread_signals(int altstack);
 extern void do_exec(int old_pid, int new_pid);
index 246f0e7fb4cc76a872cc632c211d1692e1c1b7af..a8918e80df9623542a7b2cce781c2476b4fb9827 100644 (file)
@@ -4,9 +4,9 @@
 #
 
 extra-y := vmlinux.lds
-clean-files := vmlinux.lds.S config.tmp
+clean-files :=
 
-obj-y = checksum.o config.o exec_kern.o exitcode.o \
+obj-y = config.o exec_kern.o exitcode.o \
        helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
        physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
        sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
@@ -14,7 +14,7 @@ obj-y = checksum.o config.o exec_kern.o exitcode.o \
        tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
        user_util.o
 
-obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
+obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
 obj-$(CONFIG_GPROF)    += gprof_syms.o
 obj-$(CONFIG_GCOV)     += gmon_syms.o
 obj-$(CONFIG_TTY_LOG)  += tty_log.o
@@ -23,18 +23,14 @@ obj-$(CONFIG_SYSCALL_DEBUG) += syscall_user.o
 obj-$(CONFIG_MODE_TT) += tt/
 obj-$(CONFIG_MODE_SKAS) += skas/
 
-# This needs be compiled with frame pointers regardless of how the rest of the
-# kernel is built.
-CFLAGS_frame.o := -fno-omit-frame-pointer
-
 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
 
 USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \
-       time.o tty_log.o umid.o user_util.o frame.o
+       time.o tty_log.o umid.o user_util.o
 
 include arch/um/scripts/Makefile.rules
 
-targets += config.c
+targets := config.c config.tmp
 
 # Be careful with the below Sed code - sed is pitfall-rich!
 # We use sed to lower build requirements, for "embedded" builders for instance.
diff --git a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c
deleted file mode 100644 (file)
index e69b2be..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "asm/uaccess.h"
-#include "linux/errno.h"
-#include "linux/module.h"
-
-unsigned int arch_csum_partial(const unsigned char *buff, int len, int sum);
-
-unsigned int csum_partial(unsigned char *buff, int len, int sum)
-{
-        return arch_csum_partial(buff, len, sum);
-}
-
-EXPORT_SYMBOL(csum_partial);
-
-unsigned int csum_partial_copy_to(const unsigned char *src,
-                                  unsigned char __user *dst, int len, int sum,
-                                  int *err_ptr)
-{
-        if(copy_to_user(dst, src, len)){
-                *err_ptr = -EFAULT;
-                return(-1);
-        }
-
-        return(arch_csum_partial(src, len, sum));
-}
-
-unsigned int csum_partial_copy_from(const unsigned char __user *src,
-                                    unsigned char *dst,        int len, int sum,
-                                    int *err_ptr)
-{
-        if(copy_from_user(dst, src, len)){
-                *err_ptr = -EFAULT;
-                return(-1);
-        }
-
-        return arch_csum_partial(dst, len, sum);
-}
index 49ddabe69be74e3db30641cad223f90610896b10..efd222ffe20e1df22fa2e04a4c61cdd5d6a3a419 100644 (file)
@@ -16,7 +16,6 @@
 #include "kern.h"
 #include "irq_user.h"
 #include "tlb.h"
-#include "2_5compat.h"
 #include "os.h"
 #include "time_user.h"
 #include "choose-mode.h"
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c
new file mode 100644 (file)
index 0000000..82ecf90
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include "linux/init.h"
+#include "linux/bootmem.h"
+#include "linux/initrd.h"
+#include "asm/types.h"
+#include "user_util.h"
+#include "kern_util.h"
+#include "initrd.h"
+#include "init.h"
+#include "os.h"
+
+/* Changed by uml_initrd_setup, which is a setup */
+static char *initrd __initdata = NULL;
+
+static int __init read_initrd(void)
+{
+       void *area;
+       long long size;
+       int err;
+
+       if(initrd == NULL) return 0;
+       err = os_file_size(initrd, &size);
+       if(err) return 0;
+       area = alloc_bootmem(size);
+       if(area == NULL) return 0;
+       if(load_initrd(initrd, area, size) == -1) return 0;
+       initrd_start = (unsigned long) area;
+       initrd_end = initrd_start + size;
+       return 0;
+}
+
+__uml_postsetup(read_initrd);
+
+static int __init uml_initrd_setup(char *line, int *add)
+{
+       initrd = line;
+       return 0;
+}
+
+__uml_setup("initrd=", uml_initrd_setup,
+"initrd=<initrd image>\n"
+"    This is used to boot UML from an initrd image.  The argument is the\n"
+"    name of the file containing the image.\n\n"
+);
+
+int load_initrd(char *filename, void *buf, int size)
+{
+       int fd, n;
+
+       fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
+       if(fd < 0){
+               printk("Opening '%s' failed - err = %d\n", filename, -fd);
+               return(-1);
+       }
+       n = os_read_file(fd, buf, size);
+       if(n != size){
+               printk("Read of %d bytes from '%s' failed, err = %d\n", size,
+                      filename, -n);
+               return(-1);
+       }
+
+       os_close_file(fd);
+       return(0);
+}
+/*
+ * 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-file-style: "linux"
+ * End:
+ */
diff --git a/arch/um/kernel/initrd_kern.c b/arch/um/kernel/initrd_kern.c
deleted file mode 100644 (file)
index fc568af..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "linux/init.h"
-#include "linux/bootmem.h"
-#include "linux/initrd.h"
-#include "asm/types.h"
-#include "user_util.h"
-#include "kern_util.h"
-#include "initrd.h"
-#include "init.h"
-#include "os.h"
-
-/* Changed by uml_initrd_setup, which is a setup */
-static char *initrd __initdata = NULL;
-
-static int __init read_initrd(void)
-{
-       void *area;
-       long long size;
-       int err;
-
-       if(initrd == NULL) return 0;
-       err = os_file_size(initrd, &size);
-       if(err) return 0;
-       area = alloc_bootmem(size);
-       if(area == NULL) return 0;
-       if(load_initrd(initrd, area, size) == -1) return 0;
-       initrd_start = (unsigned long) area;
-       initrd_end = initrd_start + size;
-       return 0;
-}
-
-__uml_postsetup(read_initrd);
-
-static int __init uml_initrd_setup(char *line, int *add)
-{
-       initrd = line;
-       return 0;
-}
-
-__uml_setup("initrd=", uml_initrd_setup, 
-"initrd=<initrd image>\n"
-"    This is used to boot UML from an initrd image.  The argument is the\n"
-"    name of the file containing the image.\n\n"
-);
-
-/*
- * 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-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c
deleted file mode 100644 (file)
index cb90681..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#include "user_util.h"
-#include "kern_util.h"
-#include "user.h"
-#include "initrd.h"
-#include "os.h"
-
-int load_initrd(char *filename, void *buf, int size)
-{
-       int fd, n;
-
-       fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
-       if(fd < 0){
-               printk("Opening '%s' failed - err = %d\n", filename, -fd);
-               return(-1);
-       }
-       n = os_read_file(fd, buf, size);
-       if(n != size){
-               printk("Read of %d bytes from '%s' failed, err = %d\n", size,
-                      filename, -n);
-               return(-1);
-       }
-
-       os_close_file(fd);
-       return(0);
-}
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index d71e8f00810feaab0731ae30cc3aeb8bd3b66959..d44fb52825479fb8c00f67360c547c37473e1877 100644 (file)
@@ -163,7 +163,6 @@ void __init init_IRQ(void)
                irq_desc[i].handler = &SIGIO_irq_type;
                enable_irq(i);
        }
-       init_irq_signals(0);
 }
 
 /*
index 6d6f9484b884d357240beaf65266c0d376644e55..b3074cbaa479ac3de6c42242006d8e5c1f33cb42 100644 (file)
@@ -236,9 +236,15 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
                                       (*prev)->fd, pollfds[i].fd);
                                goto out;
                        }
-                       memcpy(&pollfds[i], &pollfds[i + 1],
-                              (pollfds_num - i - 1) * sizeof(pollfds[0]));
+
                        pollfds_num--;
+
+                       /* This moves the *whole* array after pollfds[i] (though
+                        * it doesn't spot as such)! */
+
+                       memmove(&pollfds[i], &pollfds[i + 1],
+                              (pollfds_num - i) * sizeof(pollfds[0]));
+
                        if(last_irq_ptr == &old_fd->next) 
                                last_irq_ptr = prev;
                        *prev = (*prev)->next;
index b41d3397d07b5089d702e0809be73c172e16d131..99439fa15ef42514b8e563623f6eaa8238c829cc 100644 (file)
@@ -10,7 +10,6 @@
 #include "linux/spinlock.h"
 #include "linux/highmem.h"
 #include "asm/current.h"
-#include "asm/delay.h"
 #include "asm/processor.h"
 #include "asm/unistd.h"
 #include "asm/pgalloc.h"
@@ -28,8 +27,6 @@ EXPORT_SYMBOL(uml_physmem);
 EXPORT_SYMBOL(set_signals);
 EXPORT_SYMBOL(get_signals);
 EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(__const_udelay);
-EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(sys_waitpid);
 EXPORT_SYMBOL(task_size);
 EXPORT_SYMBOL(flush_tlb_range);
@@ -60,6 +57,7 @@ EXPORT_SYMBOL(copy_to_user_tt);
 EXPORT_SYMBOL(strncpy_from_user_skas);
 EXPORT_SYMBOL(copy_to_user_skas);
 EXPORT_SYMBOL(copy_from_user_skas);
+EXPORT_SYMBOL(clear_user_skas);
 #endif
 EXPORT_SYMBOL(uml_strdup);
 
index a17c49703f9bd2513af8eef1eae001dc4fd11a52..e59f581526782adca0763540a98bc80505a7a79a 100644 (file)
@@ -24,8 +24,6 @@
 #include "mode.h"
 #include "choose-mode.h"
 #include "uml-config.h"
-#include "irq_user.h"
-#include "time_user.h"
 #include "os.h"
 
 /* Set in set_stklim, which is called from main and __wrap_malloc.
@@ -71,7 +69,7 @@ static __init void do_uml_initcalls(void)
 
 static void last_ditch_exit(int sig)
 {
-       CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
+        kmalloc_ok = 0;
        signal(SIGINT, SIG_DFL);
        signal(SIGTERM, SIG_DFL);
        signal(SIGHUP, SIG_DFL);
@@ -87,7 +85,7 @@ int main(int argc, char **argv, char **envp)
 {
        char **new_argv;
        sigset_t mask;
-       int ret, i;
+       int ret, i, err;
 
        /* Enable all signals except SIGIO - in some environments, we can
         * enter with some signals blocked
@@ -160,27 +158,29 @@ int main(int argc, char **argv, char **envp)
         */
        change_sig(SIGPROF, 0);
 
-       /* Reboot */
-       if(ret){
-               int err;
+        /* This signal stuff used to be in the reboot case.  However,
+         * sometimes a SIGVTALRM can come in when we're halting (reproducably
+         * when writing out gcov information, presumably because that takes
+         * some time) and cause a segfault.
+         */
 
-               printf("\n");
+        /* stop timers and set SIG*ALRM to be ignored */
+        disable_timer();
 
-               /* stop timers and set SIG*ALRM to be ignored */
-               disable_timer();
+        /* disable SIGIO for the fds and set SIGIO to be ignored */
+        err = deactivate_all_fds();
+        if(err)
+                printf("deactivate_all_fds failed, errno = %d\n", -err);
 
-               /* disable SIGIO for the fds and set SIGIO to be ignored */
-               err = deactivate_all_fds();
-               if(err)
-                       printf("deactivate_all_fds failed, errno = %d\n",
-                              -err);
-
-               /* Let any pending signals fire now.  This ensures
-                * that they won't be delivered after the exec, when
-                * they are definitely not expected.
-                */
-               unblock_signals();
+        /* Let any pending signals fire now.  This ensures
+         * that they won't be delivered after the exec, when
+         * they are definitely not expected.
+         */
+        unblock_signals();
 
+       /* Reboot */
+       if(ret){
+               printf("\n");
                execvp(new_argv[0], new_argv);
                perror("Failed to exec kernel");
                ret = 1;
index f156661781cb19a2000900d195503616090de77d..c22825f13e40fda8ab8a2b21d8cc5df6fc04f6d4 100644 (file)
@@ -100,12 +100,37 @@ void mem_init(void)
 #endif
 }
 
+/*
+ * Create a page table and place a pointer to it in a middle page
+ * directory entry.
+ */
+static void __init one_page_table_init(pmd_t *pmd)
+{
+       if (pmd_none(*pmd)) {
+               pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+               set_pmd(pmd, __pmd(_KERNPG_TABLE +
+                                          (unsigned long) __pa(pte)));
+               if (pte != pte_offset_kernel(pmd, 0))
+                       BUG();
+       }
+}
+
+static void __init one_md_table_init(pud_t *pud)
+{
+#ifdef CONFIG_3_LEVEL_PGTABLES
+       pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+       set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table)));
+       if (pmd_table != pmd_offset(pud, 0))
+               BUG();
+#endif
+}
+
 static void __init fixrange_init(unsigned long start, unsigned long end, 
                                 pgd_t *pgd_base)
 {
        pgd_t *pgd;
+       pud_t *pud;
        pmd_t *pmd;
-       pte_t *pte;
        int i, j;
        unsigned long vaddr;
 
@@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
        pgd = pgd_base + i;
 
        for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
-               pmd = (pmd_t *)pgd;
+               pud = pud_offset(pgd, vaddr);
+               if (pud_none(*pud))
+                       one_md_table_init(pud);
+               pmd = pmd_offset(pud, vaddr);
                for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
-                       if (pmd_none(*pmd)) {
-                               pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-                               set_pmd(pmd, __pmd(_KERNPG_TABLE + 
-                                                  (unsigned long) __pa(pte)));
-                               if (pte != pte_offset_kernel(pmd, 0))
-                                       BUG();
-                       }
+                       one_page_table_init(pmd);
                        vaddr += PMD_SIZE;
                }
                j = 0;
index f76a2692adcae42ddc1ffcef5ce822027a44f320..1b5ef3e96c7161fad6a8c2c41a927e5d795ee2fa 100644 (file)
@@ -30,7 +30,6 @@
 #include "init.h"
 #include "os.h"
 #include "uml-config.h"
-#include "ptrace_user.h"
 #include "choose-mode.h"
 #include "mode.h"
 #ifdef UML_CONFIG_MODE_SKAS
@@ -65,8 +64,6 @@ void init_new_thread_signals(int altstack)
                    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
        set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, 
                    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
-       set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, 
-                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
        set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
                    flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
        signal(SIGHUP, SIG_IGN);
@@ -133,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
        return(arg.pid);
 }
 
-static int ptrace_child(void *arg)
+static int ptrace_child(void)
 {
        int ret;
        int pid = os_getpid(), ppid = getppid();
@@ -162,20 +159,16 @@ static int ptrace_child(void *arg)
        _exit(ret);
 }
 
-static int start_ptraced_child(void **stack_out)
+static int start_ptraced_child(void)
 {
-       void *stack;
-       unsigned long sp;
        int pid, n, status;
        
-       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
-                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-       if(stack == MAP_FAILED)
-               panic("check_ptrace : mmap failed, errno = %d", errno);
-       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
-       pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
+       pid = fork();
+       if(pid == 0)
+               ptrace_child();
+
        if(pid < 0)
-               panic("check_ptrace : clone failed, errno = %d", errno);
+               panic("check_ptrace : fork failed, errno = %d", errno);
        CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
        if(n < 0)
                panic("check_ptrace : wait failed, errno = %d", errno);
@@ -183,7 +176,6 @@ static int start_ptraced_child(void **stack_out)
                panic("check_ptrace : expected SIGSTOP, got status = %d",
                      status);
 
-       *stack_out = stack;
        return(pid);
 }
 
@@ -191,12 +183,12 @@ static int start_ptraced_child(void **stack_out)
  * just avoid using sysemu, not panic, but only if SYSEMU features are broken.
  * So only for SYSEMU features we test mustpanic, while normal host features
  * must work anyway!*/
-static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
+static int stop_ptraced_child(int pid, int exitcode, int mustexit)
 {
        int status, n, ret = 0;
 
        if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
-               panic("check_ptrace : ptrace failed, errno = %d", errno);
+               panic("stop_ptraced_child : ptrace failed, errno = %d", errno);
        CATCH_EINTR(n = waitpid(pid, &status, 0));
        if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
                int exit_with = WEXITSTATUS(status);
@@ -207,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
                printk("check_ptrace : child exited with exitcode %d, while "
                      "expecting %d; status 0x%x", exit_with,
                      exitcode, status);
-               if (mustpanic)
+               if (mustexit)
                        panic("\n");
                else
                        printk("\n");
                ret = -1;
        }
 
-       if(munmap(stack, PAGE_SIZE) < 0)
-               panic("check_ptrace : munmap failed, errno = %d", errno);
        return ret;
 }
 
@@ -237,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
 
 static void __init check_sysemu(void)
 {
-       void *stack;
        int pid, syscall, n, status, count=0;
 
        printk("Checking syscall emulation patch for ptrace...");
        sysemu_supported = 0;
-       pid = start_ptraced_child(&stack);
+       pid = start_ptraced_child();
 
        if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
                goto fail;
@@ -260,7 +249,7 @@ static void __init check_sysemu(void)
                panic("check_sysemu : failed to modify system "
                      "call return, errno = %d", errno);
 
-       if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+       if (stop_ptraced_child(pid, 0, 0) < 0)
                goto fail_stopped;
 
        sysemu_supported = 1;
@@ -268,7 +257,7 @@ static void __init check_sysemu(void)
        set_using_sysemu(!force_sysemu_disabled);
 
        printk("Checking advanced syscall emulation patch for ptrace...");
-       pid = start_ptraced_child(&stack);
+       pid = start_ptraced_child();
        while(1){
                count++;
                if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
@@ -293,7 +282,7 @@ static void __init check_sysemu(void)
                        break;
                }
        }
-       if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+       if (stop_ptraced_child(pid, 0, 0) < 0)
                goto fail_stopped;
 
        sysemu_supported = 2;
@@ -304,18 +293,17 @@ static void __init check_sysemu(void)
        return;
 
 fail:
-       stop_ptraced_child(pid, stack, 1, 0);
+       stop_ptraced_child(pid, 1, 0);
 fail_stopped:
        printk("missing\n");
 }
 
 void __init check_ptrace(void)
 {
-       void *stack;
        int pid, syscall, n, status;
 
        printk("Checking that ptrace can change system call numbers...");
-       pid = start_ptraced_child(&stack);
+       pid = start_ptraced_child();
 
        if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
                panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
@@ -342,7 +330,7 @@ void __init check_ptrace(void)
                        break;
                }
        }
-       stop_ptraced_child(pid, stack, 0, 1);
+       stop_ptraced_child(pid, 0, 1);
        printk("OK\n");
        check_sysemu();
 }
@@ -374,11 +362,10 @@ void forward_pending_sigio(int target)
 static inline int check_skas3_ptrace_support(void)
 {
        struct ptrace_faultinfo fi;
-       void *stack;
        int pid, n, ret = 1;
 
        printf("Checking for the skas3 patch in the host...");
-       pid = start_ptraced_child(&stack);
+       pid = start_ptraced_child();
 
        n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
        if (n < 0) {
@@ -393,7 +380,7 @@ static inline int check_skas3_ptrace_support(void)
        }
 
        init_registers(pid);
-       stop_ptraced_child(pid, stack, 1, 1);
+       stop_ptraced_child(pid, 1, 1);
 
        return(ret);
 }
index 7a943696f9507b64230c3528c4ccfddb77795227..804c6bbdf67c157e5e28b6a9be9a76c9d8c0ce04 100644 (file)
@@ -43,7 +43,6 @@
 #include "tlb.h"
 #include "frame_kern.h"
 #include "sigcontext.h"
-#include "2_5compat.h"
 #include "os.h"
 #include "mode.h"
 #include "mode_kern.h"
  */
 struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
 
-struct task_struct *get_task(int pid, int require)
-{
-        struct task_struct *ret;
-
-        read_lock(&tasklist_lock);
-       ret = find_task_by_pid(pid);
-        read_unlock(&tasklist_lock);
-
-        if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
-        return(ret);
-}
-
 int external_pid(void *t)
 {
        struct task_struct *task = t ? t : current;
@@ -115,16 +102,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
        return(pid);
 }
 
-void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
-              struct task_struct *tsk)
-{
-       int cpu = smp_processor_id();
-
-       if (prev != next) 
-               cpu_clear(cpu, prev->cpu_vm_mask);
-       cpu_set(cpu, next->cpu_vm_mask);
-}
-
 void set_current(void *t)
 {
        struct task_struct *task = t;
@@ -152,7 +129,6 @@ void release_thread(struct task_struct *task)
  
 void exit_thread(void)
 {
-       CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
        unprotect_stack((unsigned long) current_thread);
 }
  
@@ -200,7 +176,6 @@ void default_idle(void)
 
        while(1){
                /* endless idle loop with no priority at all */
-               SET_PRI(current);
 
                /*
                 * although we are an idle CPU, we do not want to
@@ -223,11 +198,6 @@ int page_size(void)
        return(PAGE_SIZE);
 }
 
-unsigned long page_mask(void)
-{
-       return(PAGE_MASK);
-}
-
 void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
                      pte_t *pte_out)
 {
@@ -360,11 +330,6 @@ char *uml_strdup(char *string)
        return(new);
 }
 
-void *get_init_task(void)
-{
-       return(&init_thread_union.thread_info.task);
-}
-
 int copy_to_user_proc(void __user *to, void *from, int size)
 {
        return(copy_to_user(to, from, size));
@@ -476,21 +441,18 @@ int singlestepping(void * t)
        return 2;
 }
 
+/*
+ * Only x86 and x86_64 have an arch_align_stack().
+ * All other arches have "#define arch_align_stack(x) (x)"
+ * in their asm/system.h
+ * As this is included in UML from asm-um/system-generic.h,
+ * we can use it to behave as the subarch does.
+ */
+#ifndef arch_align_stack
 unsigned long arch_align_stack(unsigned long sp)
 {
        if (randomize_va_space)
                sp -= get_random_int() % 8192;
        return sp & ~0xf;
 }
-
-
-/*
- * 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-file-style: "linux"
- * End:
- */
+#endif
index e50e60ff5d275bca5664b2db0b26e2f7b3e2129d..71af4d5038994014f12e5030dd3187bcbaae9450 100644 (file)
 #include "skas_ptrace.h"
 #include "sysdep/ptrace.h"
 
+static inline void set_singlestepping(struct task_struct *child, int on)
+{
+        if (on)
+                child->ptrace |= PT_DTRACE;
+        else
+                child->ptrace &= ~PT_DTRACE;
+        child->thread.singlestep_syscall = 0;
+
+#ifdef SUBARCH_SET_SINGLESTEPPING
+        SUBARCH_SET_SINGLESTEPPING(child, on);
+#endif
+}
+
 /*
  * Called by kernel/ptrace.c when detaching..
  */
 void ptrace_disable(struct task_struct *child)
 { 
-       child->ptrace &= ~PT_DTRACE;
-       child->thread.singlestep_syscall = 0;
+        set_singlestepping(child,0);
 }
 
+extern int peek_user(struct task_struct * child, long addr, long data);
+extern int poke_user(struct task_struct * child, long addr, long data);
+
 long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
@@ -67,6 +82,10 @@ long sys_ptrace(long request, long pid, long addr, long data)
                goto out_tsk;
        }
 
+#ifdef SUBACH_PTRACE_SPECIAL
+        SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
+#endif
+
        ret = ptrace_check_attach(child, request == PTRACE_KILL);
        if (ret < 0)
                goto out_tsk;
@@ -87,26 +106,9 @@ long sys_ptrace(long request, long pid, long addr, long data)
        }
 
        /* read the word at location addr in the USER area. */
-       case PTRACE_PEEKUSR: {
-               unsigned long tmp;
-
-               ret = -EIO;
-               if ((addr & 3) || addr < 0) 
-                       break;
-
-               tmp = 0;  /* Default return condition */
-               if(addr < MAX_REG_OFFSET){
-                       tmp = getreg(child, addr);
-               }
-               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
-                       (addr <= offsetof(struct user, u_debugreg[7]))){
-                       addr -= offsetof(struct user, u_debugreg[0]);
-                       addr = addr >> 2;
-                       tmp = child->thread.arch.debugregs[addr];
-               }
-               ret = put_user(tmp, (unsigned long __user *) data);
-               break;
-       }
+        case PTRACE_PEEKUSR:
+                ret = peek_user(child, addr, data);
+                break;
 
        /* when I and D space are separate, this will have to be fixed. */
        case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -119,26 +121,8 @@ long sys_ptrace(long request, long pid, long addr, long data)
                break;
 
        case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
-               ret = -EIO;
-               if ((addr & 3) || addr < 0)
-                       break;
-
-               if (addr < MAX_REG_OFFSET) {
-                       ret = putreg(child, addr, data);
-                       break;
-               }
-#if 0 /* XXX x86_64 */
-               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
-                       (addr <= offsetof(struct user, u_debugreg[7]))){
-                         addr -= offsetof(struct user, u_debugreg[0]);
-                         addr = addr >> 2;
-                         if((addr == 4) || (addr == 5)) break;
-                         child->thread.arch.debugregs[addr] = data;
-                         ret = 0;
-               }
-#endif
-
-               break;
+                ret = poke_user(child, addr, data);
+                break;
 
        case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
        case PTRACE_CONT: { /* restart after signal. */
@@ -146,8 +130,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                if (!valid_signal(data))
                        break;
 
-               child->ptrace &= ~PT_DTRACE;
-               child->thread.singlestep_syscall = 0;
+                set_singlestepping(child, 0);
                if (request == PTRACE_SYSCALL) {
                        set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
                }
@@ -170,8 +153,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                if (child->exit_state == EXIT_ZOMBIE)   /* already dead */
                        break;
 
-               child->ptrace &= ~PT_DTRACE;
-               child->thread.singlestep_syscall = 0;
+                set_singlestepping(child, 0);
                child->exit_code = SIGKILL;
                wake_up_process(child);
                break;
@@ -182,8 +164,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                if (!valid_signal(data))
                        break;
                clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               child->ptrace |= PT_DTRACE;
-               child->thread.singlestep_syscall = 0;
+                set_singlestepping(child, 1);
                child->exit_code = data;
                /* give it a chance to run. */
                wake_up_process(child);
@@ -250,23 +231,19 @@ long sys_ptrace(long request, long pid, long addr, long data)
                break;
 #endif
        case PTRACE_FAULTINFO: {
-               struct ptrace_faultinfo fault;
-
-               fault = ((struct ptrace_faultinfo) 
-                       { .is_write     = child->thread.err,
-                         .addr         = child->thread.cr2 });
-               ret = copy_to_user((unsigned long __user *) data, &fault,
-                                  sizeof(fault));
+                /* Take the info from thread->arch->faultinfo,
+                 * but transfer max. sizeof(struct ptrace_faultinfo).
+                 * On i386, ptrace_faultinfo is smaller!
+                 */
+                ret = copy_to_user((unsigned long __user *) data,
+                                   &child->thread.arch.faultinfo,
+                                   sizeof(struct ptrace_faultinfo));
                if(ret)
                        break;
                break;
        }
-       case PTRACE_SIGPENDING:
-               ret = copy_to_user((unsigned long __user *) data,
-                                  &child->pending.signal,
-                                  sizeof(child->pending.signal));
-               break;
 
+#ifdef PTRACE_LDT
        case PTRACE_LDT: {
                struct ptrace_ldt ldt;
 
@@ -282,6 +259,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                ret = -EIO;
                break;
        }
+#endif
 #ifdef CONFIG_PROC_MM
        case PTRACE_SWITCH_MM: {
                struct mm_struct *old = child->mm;
@@ -337,15 +315,16 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
 
        if (unlikely(current->audit_context)) {
                if (!entryexit)
-                       audit_syscall_entry(current, 
-                                           UPT_SYSCALL_NR(&regs->regs),
-                                           UPT_SYSCALL_ARG1(&regs->regs),
-                                           UPT_SYSCALL_ARG2(&regs->regs),
-                                           UPT_SYSCALL_ARG3(&regs->regs),
-                                           UPT_SYSCALL_ARG4(&regs->regs));
-               else
-                       audit_syscall_exit(current, 
-                                          UPT_SYSCALL_RET(&regs->regs));
+                       audit_syscall_entry(current,
+                                            HOST_AUDIT_ARCH,
+                                           UPT_SYSCALL_NR(regs),
+                                           UPT_SYSCALL_ARG1(regs),
+                                           UPT_SYSCALL_ARG2(regs),
+                                           UPT_SYSCALL_ARG3(regs),
+                                           UPT_SYSCALL_ARG4(regs));
+               else audit_syscall_exit(current,
+                                        AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
+                                        UPT_SYSCALL_RET(regs));
        }
 
        /* Fake a debug trap */
@@ -375,14 +354,3 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
                current->exit_code = 0;
        }
 }
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index 668df13d8c9d67e25ceeaaf908fca11e18c58808..e89218958f38c4bbe9bd1473363a862235ad4fcd 100644 (file)
@@ -182,6 +182,7 @@ static int write_sigio_thread(void *unused)
        int i, n, respond_fd;
        char c;
 
+        signal(SIGWINCH, SIG_IGN);
        fds = &current_poll;
        while(1){
                n = poll(fds->poll, fds->used, -1);
index 94c564962378d6f241c3af8892014edbdb5fa5ae..e48490028111ba7d260707c273242e4579cac349 100644 (file)
@@ -18,7 +18,6 @@ extern int copy_thread_skas(int nr, unsigned long clone_flags,
                            unsigned long sp, unsigned long stack_top,
                            struct task_struct *p, struct pt_regs *regs);
 extern void release_thread_skas(struct task_struct *task);
-extern void exit_thread_skas(void);
 extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
 extern void init_idle_skas(void);
 extern void flush_tlb_kernel_range_skas(unsigned long start,
index f0702c2c72042eaa1d901d3f05a55bd4a6ddd8c6..96b51dba34718fae36d0946c7dc26814393a88c6 100644 (file)
@@ -27,9 +27,10 @@ extern void map(int fd, unsigned long virt, unsigned long len, int r, int w,
 extern int unmap(int fd, void *addr, unsigned long len);
 extern int protect(int fd, unsigned long addr, unsigned long len, 
                   int r, int w, int x);
-extern void user_signal(int sig, union uml_pt_regs *regs);
+extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
 extern int new_mm(int from);
 extern void start_userspace(int cpu);
+extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
 extern long execute_syscall_skas(void *r);
 
 #endif
index c35620385da0b057f4efa1f9eebb21c1f9cd5b0a..cd6c280482cb271bef3e5975e6e385fae7fc4dd0 100644 (file)
@@ -18,8 +18,8 @@
          ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
          ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
 
-static inline int __deprecated verify_area_skas(int type, const void * addr,
-                                  unsigned long size)
+static inline int verify_area_skas(int type, const void * addr,
+                                   unsigned long size)
 {
        return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
 }
index b4ffaaa81241d1b8bed315cceff3a9284ef8ff12..773cd2b525fc6e45ea58ce891a56f39360dd3355 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <errno.h>
 #include <signal.h>
 #include "chan_user.h"
 #include "signal_user.h"
 #include "registers.h"
+#include "process.h"
 
 int is_skas_winch(int pid, int fd, void *data)
 {
-       if(pid != os_getpid())
+        if(pid != os_getpgrp())
                return(0);
 
        register_winch_irq(-1, fd, -1, data);
        return(1);
 }
 
-static void handle_segv(int pid)
+void get_skas_faultinfo(int pid, struct faultinfo * fi)
 {
-       struct ptrace_faultinfo fault;
        int err;
 
-       err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
+        err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
        if(err)
-               panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
-                     errno);
+                panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
+                      "errno = %d\n", errno);
+
+        /* Special handling for i386, which has different structs */
+        if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
+                memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
+                       sizeof(struct faultinfo) -
+                       sizeof(struct ptrace_faultinfo));
+}
 
-       segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
+static void handle_segv(int pid, union uml_pt_regs * regs)
+{
+        get_skas_faultinfo(pid, &regs->skas.faultinfo);
+        segv(regs->skas.faultinfo, 0, 1, NULL);
 }
 
 /*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
@@ -163,7 +174,7 @@ void userspace(union uml_pt_regs *regs)
                if(WIFSTOPPED(status)){
                        switch(WSTOPSIG(status)){
                        case SIGSEGV:
-                               handle_segv(pid);
+                                handle_segv(pid, regs);
                                break;
                        case SIGTRAP + 0x80:
                                handle_trap(pid, regs, local_using_sysemu);
@@ -177,7 +188,7 @@ void userspace(union uml_pt_regs *regs)
                        case SIGBUS:
                        case SIGFPE:
                        case SIGWINCH:
-                               user_signal(WSTOPSIG(status), regs);
+                                user_signal(WSTOPSIG(status), regs, pid);
                                break;
                        default:
                                printk("userspace - child stopped with signal "
@@ -190,6 +201,11 @@ void userspace(union uml_pt_regs *regs)
                }
        }
 }
+#define INIT_JMP_NEW_THREAD 0
+#define INIT_JMP_REMOVE_SIGSTACK 1
+#define INIT_JMP_CALLBACK 2
+#define INIT_JMP_HALT 3
+#define INIT_JMP_REBOOT 4
 
 void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
                void (*handler)(int))
@@ -225,7 +241,7 @@ void thread_wait(void *sw, void *fb)
        *switch_buf = &buf;
        fork_buf = fb;
        if(sigsetjmp(buf, 1) == 0)
-               siglongjmp(*fork_buf, 1);
+               siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
 }
 
 void switch_threads(void *me, void *next)
@@ -249,23 +265,31 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
        sigjmp_buf **switch_buf = switch_buf_ptr;
        int n;
 
+       set_handler(SIGWINCH, (__sighandler_t) sig_handler,
+                   SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
+                   SIGVTALRM, -1);
+
        *fork_buf_ptr = &initial_jmpbuf;
        n = sigsetjmp(initial_jmpbuf, 1);
-       if(n == 0)
-               new_thread_proc((void *) stack, new_thread_handler);
-       else if(n == 1)
-               remove_sigstack();
-       else if(n == 2){
+        switch(n){
+        case INIT_JMP_NEW_THREAD:
+                new_thread_proc((void *) stack, new_thread_handler);
+                break;
+        case INIT_JMP_REMOVE_SIGSTACK:
+                remove_sigstack();
+                break;
+        case INIT_JMP_CALLBACK:
                (*cb_proc)(cb_arg);
                siglongjmp(*cb_back, 1);
-       }
-       else if(n == 3){
+                break;
+        case INIT_JMP_HALT:
                kmalloc_ok = 0;
                return(0);
-       }
-       else if(n == 4){
+        case INIT_JMP_REBOOT:
                kmalloc_ok = 0;
                return(1);
+        default:
+                panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
        }
        siglongjmp(**switch_buf, 1);
 }
@@ -290,7 +314,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
 
        block_signals();
        if(sigsetjmp(here, 1) == 0)
-               siglongjmp(initial_jmpbuf, 2);
+               siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK);
        unblock_signals();
 
        cb_proc = NULL;
@@ -301,13 +325,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
 void halt_skas(void)
 {
        block_signals();
-       siglongjmp(initial_jmpbuf, 3);
+       siglongjmp(initial_jmpbuf, INIT_JMP_HALT);
 }
 
 void reboot_skas(void)
 {
        block_signals();
-       siglongjmp(initial_jmpbuf, 4);
+       siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
 }
 
 void switch_mm_skas(int mm_fd)
index 5d096ea63b97a696be392daa08d92536a6375c9c..fc71ef295782296d10d118f3cc95b336e6b01fcb 100644 (file)
@@ -68,8 +68,11 @@ void new_thread_handler(int sig)
         * 0 if it just exits
         */
        n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
-       if(n == 1)
+       if(n == 1){
+               /* Handle any immediate reschedules or signals */
+               interrupt_end();
                userspace(&current->thread.regs.regs);
+       }
        else do_exit(0);
 }
 
@@ -83,10 +86,6 @@ void release_thread_skas(struct task_struct *task)
 {
 }
 
-void exit_thread_skas(void)
-{
-}
-
 void fork_handler(int sig)
 {
         change_sig(SIGUSR1, 1);
@@ -100,6 +99,8 @@ void fork_handler(int sig)
        schedule_tail(current->thread.prev_sched);
        current->thread.prev_sched = NULL;
 
+       /* Handle any immediate reschedules or signals */
+       interrupt_end();
        userspace(&current->thread.regs.regs);
 }
 
index 8e9b46d4702ecec7bf46b92a5092fcd7c4cca2be..0dee1d95c806be4be14ed475008d51e1992e01fb 100644 (file)
@@ -5,12 +5,15 @@
 
 #include <signal.h>
 #include <errno.h>
-#include "sysdep/ptrace.h"
 #include "signal_user.h"
 #include "user_util.h"
 #include "kern_util.h"
 #include "task.h"
 #include "sigcontext.h"
+#include "skas.h"
+#include "ptrace_user.h"
+#include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
 
 void sig_handler_common_skas(int sig, void *sc_ptr)
 {
@@ -31,9 +34,11 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
        r = &TASK_REGS(get_current())->skas;
        save_user = r->is_user;
        r->is_user = 0;
-       r->fault_addr = SC_FAULT_ADDR(sc);
-       r->fault_type = SC_FAULT_TYPE(sc);
-       r->trap_type = SC_TRAP_TYPE(sc);
+        if ( sig == SIGFPE || sig == SIGSEGV ||
+             sig == SIGBUS || sig == SIGILL ||
+             sig == SIGTRAP ) {
+                GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
+        }
 
        change_sig(SIGUSR1, 1);
        info = &sig_info[sig];
@@ -45,14 +50,17 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
        r->is_user = save_user;
 }
 
-void user_signal(int sig, union uml_pt_regs *regs)
+extern int ptrace_faultinfo;
+
+void user_signal(int sig, union uml_pt_regs *regs, int pid)
 {
        struct signal_info *info;
+        int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
+                    (sig == SIGILL) || (sig == SIGTRAP));
 
        regs->skas.is_user = 1;
-       regs->skas.fault_addr = 0;
-       regs->skas.fault_type = 0;
-       regs->skas.trap_type = 0;
+       if (segv)
+               get_skas_faultinfo(pid, &regs->skas.faultinfo);
        info = &sig_info[sig];
        (*info->handler)(sig, regs);
 
index f7da9d027672d1de660dca3c22695db536ca7524..75195281081e10252e840ea2bf533e3cd193a27d 100644 (file)
@@ -29,9 +29,12 @@ static unsigned long maybe_map(unsigned long virt, int is_write)
        if(IS_ERR(phys) || (is_write && !pte_write(pte))){
                err = handle_page_fault(virt, 0, is_write, 1, &dummy_code);
                if(err)
-                       return(0);
+                       return(-1UL);
                phys = um_virt_to_phys(current, virt, NULL);
        }
+        if(IS_ERR(phys))
+                phys = (void *) -1;
+
        return((unsigned long) phys);
 }
 
@@ -42,7 +45,7 @@ static int do_op(unsigned long addr, int len, int is_write,
        int n;
 
        addr = maybe_map(addr, is_write);
-       if(addr == -1)
+       if(addr == -1UL)
                return(-1);
 
        page = phys_to_page(addr);
index 17f5909d60f7f45960f13a9f458ec0f035a1ae8f..f7b7eba83340d39fd33157e4b5af2a8e1e9fcede 100644 (file)
@@ -2,3 +2,4 @@ hostprogs-y             := mk_ptregs
 always                 := $(hostprogs-y)
 
 mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
+HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um
index 0788dd05bcacd56741272aef43095c5b4b11cf85..1f96e1eeb8a78c324c68bd2a8ea85be42ff1fc6e 100644 (file)
@@ -1,8 +1,7 @@
 #include <stdio.h>
-#include <asm/ptrace.h>
-#include <asm/user.h>
+#include <user-offsets.h>
 
-#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
+#define SHOW(name) printf("#define %s %d\n", #name, name)
 
 int main(int argc, char **argv)
 {
@@ -12,28 +11,27 @@ int main(int argc, char **argv)
        printf("#ifndef __SKAS_PT_REGS_\n");
        printf("#define __SKAS_PT_REGS_\n");
        printf("\n");
-       printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
-       printf("#define HOST_FP_SIZE %d\n",
-              sizeof(struct user_i387_struct) / sizeof(unsigned long));
-       printf("#define HOST_XFP_SIZE %d\n",
-              sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
+       SHOW(HOST_FRAME_SIZE);
+       SHOW(HOST_FP_SIZE);
+       SHOW(HOST_XFP_SIZE);
+
+       SHOW(HOST_IP);
+       SHOW(HOST_SP);
+       SHOW(HOST_EFLAGS);
+       SHOW(HOST_EAX);
+       SHOW(HOST_EBX);
+       SHOW(HOST_ECX);
+       SHOW(HOST_EDX);
+       SHOW(HOST_ESI);
+       SHOW(HOST_EDI);
+       SHOW(HOST_EBP);
+       SHOW(HOST_CS);
+       SHOW(HOST_SS);
+       SHOW(HOST_DS);
+       SHOW(HOST_FS);
+       SHOW(HOST_ES);
+       SHOW(HOST_GS);
 
-       PRINT_REG("IP", EIP);
-       PRINT_REG("SP", UESP);
-       PRINT_REG("EFLAGS", EFL);
-       PRINT_REG("EAX", EAX);
-       PRINT_REG("EBX", EBX);
-       PRINT_REG("ECX", ECX);
-       PRINT_REG("EDX", EDX);
-       PRINT_REG("ESI", ESI);
-       PRINT_REG("EDI", EDI);
-       PRINT_REG("EBP", EBP);
-       PRINT_REG("CS", CS);
-       PRINT_REG("SS", SS);
-       PRINT_REG("DS", DS);
-       PRINT_REG("FS", FS);
-       PRINT_REG("ES", ES);
-       PRINT_REG("GS", GS);
        printf("\n");
        printf("#endif\n");
        return(0);
index 67aee92a70efa50a209dbe60e04548277cfe479a..5fccbfe35f78e1b3f9ce4eda375aaa1d4e084a79 100644 (file)
@@ -5,11 +5,10 @@
  */
 
 #include <stdio.h>
-#define __FRAME_OFFSETS
-#include <asm/ptrace.h>
+#include <user-offsets.h>
 
-#define PRINT_REG(name, val) \
-       printf("#define HOST_%s (%d / sizeof(unsigned long))\n", (name), (val))
+#define SHOW(name) \
+       printf("#define %s (%d / sizeof(unsigned long))\n", #name, name)
 
 int main(int argc, char **argv)
 {
@@ -18,36 +17,35 @@ int main(int argc, char **argv)
        printf("\n");
        printf("#ifndef __SKAS_PT_REGS_\n");
        printf("#define __SKAS_PT_REGS_\n");
-       printf("#define HOST_FRAME_SIZE (%d / sizeof(unsigned long))\n",
-              FRAME_SIZE);
-       PRINT_REG("RBX", RBX);
-       PRINT_REG("RCX", RCX);
-       PRINT_REG("RDI", RDI);
-       PRINT_REG("RSI", RSI);
-       PRINT_REG("RDX", RDX);
-       PRINT_REG("RBP", RBP);
-       PRINT_REG("RAX", RAX);
-       PRINT_REG("R8", R8);
-       PRINT_REG("R9", R9);
-       PRINT_REG("R10", R10);
-       PRINT_REG("R11", R11);
-       PRINT_REG("R12", R12);
-       PRINT_REG("R13", R13);
-       PRINT_REG("R14", R14);
-       PRINT_REG("R15", R15);
-       PRINT_REG("ORIG_RAX", ORIG_RAX);
-       PRINT_REG("CS", CS);
-       PRINT_REG("SS", SS);
-       PRINT_REG("EFLAGS", EFLAGS);
+       SHOW(HOST_FRAME_SIZE);
+       SHOW(HOST_RBX);
+       SHOW(HOST_RCX);
+       SHOW(HOST_RDI);
+       SHOW(HOST_RSI);
+       SHOW(HOST_RDX);
+       SHOW(HOST_RBP);
+       SHOW(HOST_RAX);
+       SHOW(HOST_R8);
+       SHOW(HOST_R9);
+       SHOW(HOST_R10);
+       SHOW(HOST_R11);
+       SHOW(HOST_R12);
+       SHOW(HOST_R13);
+       SHOW(HOST_R14);
+       SHOW(HOST_R15);
+       SHOW(HOST_ORIG_RAX);
+       SHOW(HOST_CS);
+       SHOW(HOST_SS);
+       SHOW(HOST_EFLAGS);
 #if 0
-       PRINT_REG("FS", FS);
-       PRINT_REG("GS", GS);
-       PRINT_REG("DS", DS);
-       PRINT_REG("ES", ES);
+       SHOW(HOST_FS);
+       SHOW(HOST_GS);
+       SHOW(HOST_DS);
+       SHOW(HOST_ES);
 #endif
 
-       PRINT_REG("IP", RIP);
-       PRINT_REG("SP", RSP);
+       SHOW(HOST_IP);
+       SHOW(HOST_SP);
        printf("#define HOST_FP_SIZE 0\n");
        printf("#define HOST_XFP_SIZE 0\n");
        printf("\n");
index 42731e04f50fda4fdfed91a5142af3ef7019a527..b7a55251e89727d44cf7ba841b309091034edcdb 100644 (file)
@@ -17,7 +17,6 @@
 #include "linux/utime.h"
 #include "asm/mman.h"
 #include "asm/uaccess.h"
-#include "asm/ipc.h"
 #include "kern_util.h"
 #include "user_util.h"
 #include "sysdep/syscalls.h"
index e630438f9e73ee7d28c9101037a56a0c0a48bc9e..f80850091e798c1eab0ad3f820cdf21350cf22b3 100644 (file)
@@ -3,6 +3,7 @@
  * Licensed under the GPL
  */
 
+#include "linux/config.h"
 #include "linux/sched.h"
 #include "linux/kernel.h"
 #include "linux/module.h"
 #include "sysrq.h"
 #include "user_util.h"
 
-void show_trace(unsigned long * stack)
+/* Catch non-i386 SUBARCH's. */
+#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
+void show_trace(struct task_struct *task, unsigned long * stack)
 {
-       /* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from
-        * arch/i386/kernel/traps.c, and then move this to sys-i386/sysrq.c.*/
         unsigned long addr;
 
         if (!stack) {
-                stack = (unsigned long*) &stack;
+               stack = (unsigned long*) &stack;
                WARN_ON(1);
        }
 
@@ -35,6 +36,7 @@ void show_trace(unsigned long * stack)
         }
         printk("\n");
 }
+#endif
 
 /*
  * stack dumps generator - this is used by arch-independent code.
@@ -44,7 +46,7 @@ void dump_stack(void)
 {
        unsigned long stack;
 
-       show_trace(&stack);
+       show_trace(current, &stack);
 }
 EXPORT_SYMBOL(dump_stack);
 
@@ -59,7 +61,11 @@ void show_stack(struct task_struct *task, unsigned long *esp)
        int i;
 
        if (esp == NULL) {
-               if (task != current) {
+               if (task != current && task != NULL) {
+                       /* XXX: Isn't this bogus? I.e. isn't this the
+                        * *userspace* stack of this task? If not so, use this
+                        * even when task == current (as in i386).
+                        */
                        esp = (unsigned long *) KSTK_ESP(task);
                        /* Which one? No actual difference - just coding style.*/
                        //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
@@ -77,5 +83,6 @@ void show_stack(struct task_struct *task, unsigned long *esp)
                printk("%08lx ", *stack++);
        }
 
-       show_trace(esp);
+       printk("Call Trace: \n");
+       show_trace(current, esp);
 }
index 2461cd73ca879012688f9c705882a7e4fad8968e..6516fc52afe01f23ecfbe0365cb251e9d3c8635d 100644 (file)
@@ -48,8 +48,6 @@ static unsigned long long prev_usecs;
 static long long delta;                /* Deviation per interval */
 #endif
 
-#define MILLION 1000000
-
 void timer_irq(union uml_pt_regs *regs)
 {
        unsigned long long ticks = 0;
@@ -136,22 +134,6 @@ long um_stime(int __user *tptr)
        return 0;
 }
 
-void __udelay(unsigned long usecs)
-{
-       int i, n;
-
-       n = (loops_per_jiffy * HZ * usecs) / MILLION;
-       for(i=0;i<n;i++) ;
-}
-
-void __const_udelay(unsigned long usecs)
-{
-       int i, n;
-
-       n = (loops_per_jiffy * HZ * usecs) / MILLION;
-       for(i=0;i<n;i++) ;
-}
-
 void timer_handler(int sig, union uml_pt_regs *regs)
 {
        local_irq_disable();
index 47e766e6ba102cf436193efb5cdffdcef7a47e45..c20aef120598ddb071f6362ca8868ecdc8373eca 100644 (file)
@@ -23,7 +23,6 @@
 #include "kern.h"
 #include "chan_kern.h"
 #include "mconsole_kern.h"
-#include "2_5compat.h"
 #include "mem.h"
 #include "mem_kern.h"
 
@@ -48,7 +47,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
                goto good_area;
        else if(!(vma->vm_flags & VM_GROWSDOWN)) 
                goto out;
-       else if(!ARCH_IS_STACKGROW(address))
+       else if(is_user && !ARCH_IS_STACKGROW(address))
                goto out;
        else if(expand_stack(vma, address)) 
                goto out;
@@ -57,10 +56,11 @@ int handle_page_fault(unsigned long address, unsigned long ip,
        *code_out = SEGV_ACCERR;
        if(is_write && !(vma->vm_flags & VM_WRITE)) 
                goto out;
+
+        if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                goto out;
+
        page = address & PAGE_MASK;
-       pgd = pgd_offset(mm, page);
-       pud = pud_offset(pgd, page);
-       pmd = pmd_offset(pud, page);
        do {
  survive:
                switch (handle_mm_fault(mm, vma, address, is_write)){
@@ -106,46 +106,24 @@ out_of_memory:
        goto out;
 }
 
-LIST_HEAD(physmem_remappers);
-
-void register_remapper(struct remapper *info)
-{
-       list_add(&info->list, &physmem_remappers);
-}
-
-static int check_remapped_addr(unsigned long address, int is_write)
-{
-       struct remapper *remapper;
-       struct list_head *ele;
-       __u64 offset;
-       int fd;
-
-       fd = phys_mapping(__pa(address), &offset);
-       if(fd == -1)
-               return(0);
-
-       list_for_each(ele, &physmem_remappers){
-               remapper = list_entry(ele, struct remapper, list);
-               if((*remapper->proc)(fd, address, is_write, offset))
-                       return(1);
-       }
-
-       return(0);
-}
-
-unsigned long segv(unsigned long address, unsigned long ip, int is_write, 
-                  int is_user, void *sc)
+/*
+ * We give a *copy* of the faultinfo in the regs to segv.
+ * This must be done, since nesting SEGVs could overwrite
+ * the info in the regs. A pointer to the info then would
+ * give us bad data!
+ */
+unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
 {
        struct siginfo si;
        void *catcher;
        int err;
+        int is_write = FAULT_WRITE(fi);
+        unsigned long address = FAULT_ADDRESS(fi);
 
         if(!is_user && (address >= start_vm) && (address < end_vm)){
                 flush_tlb_kernel_vm();
                 return(0);
         }
-       else if(check_remapped_addr(address & PAGE_MASK, is_write))
-               return(0);
        else if(current->mm == NULL)
                panic("Segfault with no mm");
        err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
@@ -159,7 +137,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
        } 
        else if(current->thread.fault_addr != NULL)
                panic("fault_addr set but no fault catcher");
-       else if(arch_fixup(ip, sc))
+        else if(!is_user && arch_fixup(ip, sc))
                return(0);
 
        if(!is_user) 
@@ -171,6 +149,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
                si.si_errno = 0;
                si.si_code = BUS_ADRERR;
                si.si_addr = (void *)address;
+                current->thread.arch.faultinfo = fi;
                force_sig_info(SIGBUS, &si, current);
        }
        else if(err == -ENOMEM){
@@ -180,22 +159,20 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
        else {
                si.si_signo = SIGSEGV;
                si.si_addr = (void *) address;
-               current->thread.cr2 = address;
-               current->thread.err = is_write;
+                current->thread.arch.faultinfo = fi;
                force_sig_info(SIGSEGV, &si, current);
        }
        return(0);
 }
 
-void bad_segv(unsigned long address, unsigned long ip, int is_write)
+void bad_segv(struct faultinfo fi, unsigned long ip)
 {
        struct siginfo si;
 
        si.si_signo = SIGSEGV;
        si.si_code = SEGV_ACCERR;
-       si.si_addr = (void *) address;
-       current->thread.cr2 = address;
-       current->thread.err = is_write;
+        si.si_addr = (void *) FAULT_ADDRESS(fi);
+        current->thread.arch.faultinfo = fi;
        force_sig_info(SIGSEGV, &si, current);
 }
 
@@ -204,6 +181,7 @@ void relay_signal(int sig, union uml_pt_regs *regs)
        if(arch_handle_signal(sig, regs)) return;
        if(!UPT_IS_USER(regs))
                panic("Kernel mode signal %d", sig);
+        current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
        force_sig(sig, current);
 }
 
index 50a4042a509f9043621b6cdf7178c0a629b7e58a..f825a6eda3f599ac6f080cedce1f52bb69955715 100644 (file)
@@ -54,23 +54,22 @@ struct {
 void segv_handler(int sig, union uml_pt_regs *regs)
 {
        int index, max;
+        struct faultinfo * fi = UPT_FAULTINFO(regs);
 
-       if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
-               bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), 
-                        UPT_FAULT_WRITE(regs));
+        if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
+                bad_segv(*fi, UPT_IP(regs));
                return;
        }
        max = sizeof(segfault_record)/sizeof(segfault_record[0]);
        index = next_trap_index(max);
 
        nsegfaults++;
-       segfault_record[index].address = UPT_FAULT_ADDR(regs);
+        segfault_record[index].address = FAULT_ADDRESS(*fi);
        segfault_record[index].pid = os_getpid();
-       segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
+        segfault_record[index].is_write = FAULT_WRITE(*fi);
        segfault_record[index].sp = UPT_SP(regs);
        segfault_record[index].is_user = UPT_IS_USER(regs);
-       segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
-            UPT_IS_USER(regs), regs);
+        segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
 }
 
 void usr2_handler(int sig, union uml_pt_regs *regs)
index 3d5177df3504cd53df8bba7fda7d6c68d68ed379..c3faea21a996316fa2012c9c1f215305ee20ff93 100644 (file)
@@ -4,6 +4,7 @@
 #
 
 extra-y := unmap_fin.o
+targets := unmap.o
 clean-files := unmap_tmp.o
 
 obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
index 28aaab3448fa9033f7d7589be52a74b64b25bf94..e0ca0e0b251644f9a9fd30af8d2a5f7299077e9e 100644 (file)
@@ -19,7 +19,6 @@ extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
                          unsigned long stack_top, struct task_struct *p,
                          struct pt_regs *regs);
 extern void release_thread_tt(struct task_struct *task);
-extern void exit_thread_tt(void);
 extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
 extern void init_idle_tt(void);
 extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
index bb69d6b7d0227cdf82bd548baa0e1124a2368bca..3fbb5fe26f490507b455407a9dba55be5d41c040 100644 (file)
@@ -33,8 +33,8 @@ extern unsigned long uml_physmem;
          (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
           (under_task_size(addr, size) || is_stack(addr, size))))
 
-static inline int __deprecated verify_area_tt(int type, const void * addr,
-                                unsigned long size)
+static inline int verify_area_tt(int type, const void * addr,
+                                 unsigned long size)
 {
        return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
 }
index 92ec85d67c7c601706f2e35fafe25862aa00372c..84a9385a8fefbcc1048cedbc2a71edecaf9999e4 100644 (file)
@@ -12,6 +12,7 @@ EXPORT_SYMBOL(__do_copy_to_user);
 EXPORT_SYMBOL(__do_strncpy_from_user);
 EXPORT_SYMBOL(__do_strnlen_user); 
 EXPORT_SYMBOL(__do_clear_user);
+EXPORT_SYMBOL(clear_user_tt);
 
 EXPORT_SYMBOL(tracing_pid);
 EXPORT_SYMBOL(honeypot);
index 74346a04a2b287f5ecb3a8d86ac97f3c7e2ad0ab..bcb8796c3cb15386e03d424109807ac1bca31e1e 100644 (file)
@@ -21,14 +21,8 @@ void before_mem_tt(unsigned long brk_start)
        remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
 }
 
-#ifdef CONFIG_HOST_2G_2G
-#define TOP 0x80000000
-#else
-#define TOP 0xc0000000
-#endif
-
 #define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
-#define START (TOP - SIZE)
+#define START (CONFIG_TOP_ADDR - SIZE)
 
 unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
                                unsigned long *task_size_out)
index f19f7c18febe4a3257d4c6f30113337d4a1c1ba0..776310fd5b8b7e34d4b651b5fd2216a27b0a8935 100644 (file)
@@ -32,10 +32,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
        unsigned long flags;
        int err, vtalrm, alrm, prof, cpu;
        char c;
-       /* jailing and SMP are incompatible, so this doesn't need to be 
-        * made per-cpu 
-        */
-       static int reading;
 
        from = prev;
        to = next;
@@ -59,14 +55,11 @@ void *switch_to_tt(void *prev, void *next, void *last)
        c = 0;
        set_current(to);
 
-       reading = 0;
        err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
        if(err != sizeof(c))
                panic("write of switch_pipe failed, err = %d", -err);
 
-       reading = 1;
-       if((from->exit_state == EXIT_ZOMBIE) ||
-          (from->exit_state == EXIT_DEAD))
+       if(from->thread.mode.tt.switch_pipe[0] == -1)
                os_kill_process(os_getpid(), 0);
 
        err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
@@ -81,8 +74,7 @@ void *switch_to_tt(void *prev, void *next, void *last)
         * in case it has not already killed itself.
         */
        prev_sched = current->thread.prev_sched;
-       if((prev_sched->exit_state == EXIT_ZOMBIE) ||
-          (prev_sched->exit_state == EXIT_DEAD))
+        if(prev_sched->thread.mode.tt.switch_pipe[0] == -1)
                os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
 
        change_sig(SIGVTALRM, vtalrm);
@@ -101,14 +93,18 @@ void release_thread_tt(struct task_struct *task)
 {
        int pid = task->thread.mode.tt.extern_pid;
 
+       /*
+         * We first have to kill the other process, before
+         * closing its switch_pipe. Else it might wake up
+         * and receive "EOF" before we could kill it.
+         */
        if(os_getpid() != pid)
                os_kill_process(pid, 0);
-}
 
-void exit_thread_tt(void)
-{
-       os_close_file(current->thread.mode.tt.switch_pipe[0]);
-       os_close_file(current->thread.mode.tt.switch_pipe[1]);
+        os_close_file(task->thread.mode.tt.switch_pipe[0]);
+        os_close_file(task->thread.mode.tt.switch_pipe[1]);
+       /* use switch_pipe as flag: thread is released */
+        task->thread.mode.tt.switch_pipe[0] = -1;
 }
 
 void suspend_new_thread(int fd)
index e4e7e9c2224c9c536a19a0e1947b0ee47558e64b..b218316cfdb29aa169beb82ecdeca42d89a6407f 100644 (file)
@@ -63,6 +63,10 @@ void do_syscall(void *task, int pid, int local_using_sysemu)
 
        UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
 
+#ifdef UPT_ORIGGPR2
+        UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs);
+#endif
+
        if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
           ((unsigned long *) PT_IP(proc_regs) <= &_etext))
                tracer_panic("I'm tracing myself and I can't get out");
index 7b5d937e59559df70fc301f56edc0ee72dd276b9..d11e7399d7a1a894097ec0b0a45360803eae10b5 100644 (file)
@@ -26,6 +26,7 @@
 #include "kern_util.h"
 #include "chan_user.h"
 #include "ptrace_user.h"
+#include "irq_user.h"
 #include "mode.h"
 #include "tt.h"
 
@@ -33,7 +34,7 @@ static int tracer_winch[2];
 
 int is_tracer_winch(int pid, int fd, void *data)
 {
-       if(pid != tracing_pid)
+       if(pid != os_getpgrp())
                return(0);
 
        register_winch_irq(tracer_winch[0], fd, -1, data);
@@ -89,8 +90,10 @@ void tracer_panic(char *format, ...)
 
 static void tracer_segv(int sig, struct sigcontext sc)
 {
+        struct faultinfo fi;
+        GET_FAULTINFO_FROM_SC(fi, &sc);
        printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
-              SC_FAULT_ADDR(&sc), SC_IP(&sc));
+               FAULT_ADDRESS(fi), SC_IP(&sc));
        while(1)
                pause();
 }
@@ -117,6 +120,7 @@ static int signal_tramp(void *arg)
        signal(SIGSEGV, (__sighandler_t) sig_handler);
        set_cmdline("(idle thread)");
        set_init_pid(os_getpid());
+       init_irq_signals(0);
        proc = arg;
        return((*proc)(NULL));
 }
index 92a3820ca543908987143b6b9d8b5ef65ffbb488..fc108615beafbaf894f0fe3e4c2eb55338084030 100644 (file)
@@ -7,6 +7,7 @@
 #include <errno.h>
 #include <signal.h>
 #include "sysdep/ptrace.h"
+#include "sysdep/sigcontext.h"
 #include "signal_user.h"
 #include "user_util.h"
 #include "kern_util.h"
@@ -28,6 +29,11 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
                change_sig(SIGSEGV, 1);
 
        r = &TASK_REGS(get_current())->tt;
+        if ( sig == SIGFPE || sig == SIGSEGV ||
+             sig == SIGBUS || sig == SIGILL ||
+             sig == SIGTRAP ) {
+                GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
+        }
        save_regs = *r;
        is_user = user_context(SC_SP(sc));
        r->sc = sc;
index 5c49d88eed3d0701652dc03bffc80ade97d51201..8736d098f0eed6ce704b137a455c5a0aa5f4660e 100644 (file)
@@ -23,9 +23,9 @@
 #include "asm/ptrace.h"
 #include "asm/elf.h"
 #include "asm/user.h"
+#include "asm/setup.h"
 #include "ubd_user.h"
 #include "asm/current.h"
-#include "asm/setup.h"
 #include "user_util.h"
 #include "kern_util.h"
 #include "kern.h"
@@ -42,9 +42,9 @@
 #define DEFAULT_COMMAND_LINE "root=98:0"
 
 /* Changed in linux_main and setup_arch, which run before SMP is started */
-char command_line[COMMAND_LINE_SIZE] = { 0 };
+static char command_line[COMMAND_LINE_SIZE] = { 0 };
 
-void add_arg(char *arg)
+static void add_arg(char *arg)
 {
        if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
                printf("add_arg: Too many command line arguments!\n");
@@ -110,12 +110,6 @@ struct seq_operations cpuinfo_op = {
        .show   = show_cpuinfo,
 };
 
-pte_t * __bad_pagetable(void)
-{
-       panic("Someone should implement __bad_pagetable");
-       return(NULL);
-}
-
 /* Set in linux_main */
 unsigned long host_task_size;
 unsigned long task_size;
@@ -449,7 +443,7 @@ void __init setup_arch(char **cmdline_p)
 {
        notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
        paging_init();
-       strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+        strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
        *cmdline_p = command_line;
        setup_hostinfo();
 }
index 76eadb3091894d8058b571d235d02ac2ad0c01ad..dd5355500bdccdc66423761a0dd69ce88baca6bd 100644 (file)
@@ -73,6 +73,8 @@ SECTIONS
 
   .got           : { *(.got.plt) *(.got) }
   .dynamic       : { *(.dynamic) }
+  .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
   /* We want the small data sections together, so single-instruction offsets
      can access them all, and initialized data all before uninitialized, so
      we can shorten the on-disk segment size.  */
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S
new file mode 100644 (file)
index 0000000..1660a76
--- /dev/null
@@ -0,0 +1,6 @@
+#include <linux/config.h>
+#ifdef CONFIG_LD_SCRIPT_STATIC
+#include "uml.lds.S"
+#else
+#include "dyn.lds.S"
+#endif
index 9aee0b62ebca19c1551242c49c3e11ed17ad0baf..f0d6060e3e57f601dd5a861e31ca7b7a87a0cf61 100644 (file)
@@ -45,7 +45,11 @@ __init void scan_elf_aux( char **envp)
                                elf_aux_hwcap = auxv->a_un.a_val;
                                break;
                        case AT_PLATFORM:
-                               elf_aux_platform = auxv->a_un.a_ptr;
+                                /* elf.h removed the pointer elements from
+                                 * a_un, so we have to use a_val, which is
+                                 * all that's left.
+                                 */
+                               elf_aux_platform = (char *) auxv->a_un.a_val;
                                break;
                        case AT_PAGESZ:
                                page_size = auxv->a_un.a_val;
index 77d4066d1af8e371b6e8255f2920b94043e580a2..fd45bb2609079a3bd3f13339ec8154d6a168ef69 100644 (file)
@@ -363,7 +363,7 @@ int os_write_file(int fd, const void *buf, int len)
                       (int (*)(int, void *, int)) write, copy_to_user_proc));
 }
 
-int os_file_size(char *file, long long *size_out)
+int os_file_size(char *file, unsigned long long *size_out)
 {
        struct uml_stat buf;
        int err;
index ba9ca1cc790a52d6f7940fc9515d77e471f39328..1e126bfd31a7b89b5d9663ae4a1b7cefcb294422 100644 (file)
@@ -123,6 +123,11 @@ int os_getpid(void)
        return(getpid());
 }
 
+int os_getpgrp(void)
+{
+       return getpgrp();
+}
+
 int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
                  int r, int w, int x)
 {
index 7eac1baf597568890ae2a76531237e22e52482ad..c7bfd5ee392573b5a79c9eb8dc676b00306c7046 100644 (file)
@@ -8,7 +8,7 @@
 #include "mode.h"
 #include "sysdep/signal.h"
 
-void sig_handler(int sig)
+void sig_handler(ARCH_SIGHDLR_PARAM)
 {
        struct sigcontext *sc;
 
@@ -19,7 +19,7 @@ void sig_handler(int sig)
 
 extern int timer_irq_inited;
 
-void alarm_handler(int sig)
+void alarm_handler(ARCH_SIGHDLR_PARAM)
 {
        struct sigcontext *sc;
 
index fb00ddf969bd9a1c18d0725c339bdea2bd924c86..9778aed0c314a6a575b7522c74ceb73925567760 100644 (file)
@@ -1,4 +1,4 @@
 hostprogs-y            := mk_user_constants
 always                 := $(hostprogs-y)
 
-mk_user_constants-objs := mk_user_constants.o
+HOSTCFLAGS_mk_user_constants.o := -I$(objtree)/arch/um
index 0933518aa8bd2a6862533474b95a400b82a51341..4838f30eecf0f056fff89089fd6c85142564335e 100644 (file)
@@ -1,11 +1,5 @@
 #include <stdio.h>
-#include <asm/types.h>
-/* For some reason, x86_64 nowhere defines u64 and u32, even though they're
- * used throughout the headers.
- */
-typedef __u64 u64;
-typedef __u32 u32;
-#include <asm/user.h>
+#include <user-offsets.h>
 
 int main(int argc, char **argv)
 {
@@ -20,7 +14,7 @@ int main(int argc, char **argv)
    * x86_64 (216 vs 168 bytes).  user_regs_struct is the correct size on
    * both x86_64 and i386.
    */
-  printf("#define UM_FRAME_SIZE %d\n", (int) sizeof(struct user_regs_struct));
+  printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE);
 
   printf("\n");
   printf("#endif\n");
index 143f6fea076329058f427b764909488393e260cf..98346c71149346f31be5f367535eea9ee00ca242 100644 (file)
@@ -2,12 +2,27 @@
 # arch/um: Generic definitions
 # ===========================================================================
 
-USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
-USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
-
+USER_SINGLE_OBJS := \
+       $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
+USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m)  $(USER_SINGLE_OBJS))
 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
-$(USER_OBJS): c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@))
+$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
+       $(CFLAGS_$(notdir $@))
 
 quiet_cmd_make_link = SYMLINK $@
-cmd_make_link       = rm -f $@; ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
+cmd_make_link       = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
+
+# this needs to be before the foreach, because targets does not accept
+# complete paths like $(obj)/$(f). To make sure this works, use a := assignment
+# or we will get $(obj)/$(f) in the "targets" value.
+# Also, this forces you to use the := syntax when assigning to targets.
+# Otherwise the line below will cause an infinite loop (if you don't know why,
+# just do it).
+
+targets := $(targets) $(SYMLINKS)
+
+SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$(f))
+
+$(SYMLINKS): FORCE
+       $(call if_changed,make_link)
index 950781e354deca2255d2ab588fee1798307be818..4351e5605506edc13a059fadcf48c6abd1f9a3c8 100644 (file)
@@ -7,24 +7,13 @@ obj-$(CONFIG_MODULES) += module.o
 
 USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
 
-include arch/um/scripts/Makefile.rules
-
 SYMLINKS = bitops.c semaphore.c highmem.c module.c
 
-# this needs to be before the foreach, because clean-files does not accept
-# complete paths like $(src)/$f.
-clean-files := $(SYMLINKS)
-
-targets += $(SYMLINKS)
-
-SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f)
+include arch/um/scripts/Makefile.rules
 
 bitops.c-dir = lib
 semaphore.c-dir = kernel
 highmem.c-dir = mm
 module.c-dir = kernel
 
-$(SYMLINKS): FORCE
-       $(call if_changed,make_link)
-
 subdir- := util
index a11171fb62236d51119bc80dfef8aaab40772e6b..d98b2fff3d086416d10d6bdd5d56002211d0aa9f 100644 (file)
@@ -38,7 +38,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
                
 .text
 .align 4
-.globl arch_csum_partial                                                               
+.globl csum_partial
                
 #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
 
@@ -49,7 +49,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
           * Fortunately, it is easy to convert 2-byte alignment to 4-byte
           * alignment for the unrolled loop.
           */           
-arch_csum_partial:     
+csum_partial:
        pushl %esi
        pushl %ebx
        movl 20(%esp),%eax      # Function arg: unsigned int sum
@@ -119,7 +119,7 @@ arch_csum_partial:
 
 /* Version for PentiumII/PPro */
 
-arch_csum_partial:
+csum_partial:
        pushl %esi
        pushl %ebx
        movl 20(%esp),%eax      # Function arg: unsigned int sum
index 20d37dbbaf08be338ee74d4f909060d7aa78fb66..2c11b9770e8b351c3756864237ff27b9be721e41 100644 (file)
@@ -1,3 +1,8 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <asm/param.h>
+
 void __delay(unsigned long time)
 {
        /* Stolen from the i386 __loop_delay */
@@ -12,3 +17,24 @@ void __delay(unsigned long time)
                :"0" (time));
 }
 
+void __udelay(unsigned long usecs)
+{
+       int i, n;
+
+       n = (loops_per_jiffy * HZ * usecs) / MILLION;
+        for(i=0;i<n;i++)
+                cpu_relax();
+}
+
+EXPORT_SYMBOL(__udelay);
+
+void __const_udelay(unsigned long usecs)
+{
+       int i, n;
+
+       n = (loops_per_jiffy * HZ * usecs) / MILLION;
+        for(i=0;i<n;i++)
+                cpu_relax();
+}
+
+EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c
new file mode 100644 (file)
index 0000000..9f8ecd1
--- /dev/null
@@ -0,0 +1,25 @@
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <asm/page.h>
+
+#define DEFINE(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define STR(x) #x
+#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : )
+
+#define BLANK() asm volatile("\n->" : : )
+
+#define OFFSET(sym, str, mem) \
+       DEFINE(sym, offsetof(struct str, mem));
+
+void foo(void)
+{
+       OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
+#ifdef CONFIG_MODE_TT
+       OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+#endif
+#include <common-offsets.h>
+}
index 74f70a1204587bdccc988df852ba5e35b5b722d9..db524ab3f743a47f9d5a1b555c0efb48523dafc3 100644 (file)
@@ -2,6 +2,7 @@
 #include "linux/in6.h"
 #include "linux/rwsem.h"
 #include "asm/byteorder.h"
+#include "asm/delay.h"
 #include "asm/semaphore.h"
 #include "asm/uaccess.h"
 #include "asm/checksum.h"
@@ -13,5 +14,8 @@ EXPORT_SYMBOL(__down_failed_trylock);
 EXPORT_SYMBOL(__up_wakeup);
 
 /* Networking helper routines. */
-EXPORT_SYMBOL(csum_partial_copy_from);
-EXPORT_SYMBOL(csum_partial_copy_to);
+EXPORT_SYMBOL(csum_partial);
+
+/* delay core functions */
+EXPORT_SYMBOL(__const_udelay);
+EXPORT_SYMBOL(__udelay);
index 31bcb2f997d4ad4f796649e1f4ecd4e8f8b62611..dc755b0b9db8e6a6728ac82d1c1fc943909b9659 100644 (file)
@@ -25,7 +25,7 @@ int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)
 #endif
 
 #ifdef CONFIG_MODE_SKAS
-extern int userspace_pid;
+extern int userspace_pid[];
 
 #include "skas_ptrace.h"
 
@@ -56,7 +56,8 @@ int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)
        ldt = ((struct ptrace_ldt) { .func      = func,
                                     .ptr       = buf,
                                     .bytecount = bytecount });
-       res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
+#warning Need to look up userspace_pid by cpu
+       res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
        if(res < 0)
                goto out;
 
index e470d28cdf84efbccbd751bea77d6cb1cc573cd4..e839ce65ad287d2bfa172f58d6c2ceaae302e373 100644 (file)
@@ -73,6 +73,25 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
        return 0;
 }
 
+int poke_user(struct task_struct *child, long addr, long data)
+{
+        if ((addr & 3) || addr < 0)
+                return -EIO;
+
+        if (addr < MAX_REG_OFFSET)
+                return putreg(child, addr, data);
+
+        else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+                (addr <= offsetof(struct user, u_debugreg[7]))){
+                addr -= offsetof(struct user, u_debugreg[0]);
+                addr = addr >> 2;
+                if((addr == 4) || (addr == 5)) return -EIO;
+                child->thread.arch.debugregs[addr] = data;
+                return 0;
+        }
+        return -EIO;
+}
+
 unsigned long getreg(struct task_struct *child, int regno)
 {
        unsigned long retval = ~0UL;
@@ -93,6 +112,27 @@ unsigned long getreg(struct task_struct *child, int regno)
        return retval;
 }
 
+int peek_user(struct task_struct *child, long addr, long data)
+{
+/* read the word at location addr in the USER area. */
+        unsigned long tmp;
+
+        if ((addr & 3) || addr < 0)
+                return -EIO;
+
+        tmp = 0;  /* Default return condition */
+        if(addr < MAX_REG_OFFSET){
+                tmp = getreg(child, addr);
+        }
+        else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+                (addr <= offsetof(struct user, u_debugreg[7]))){
+                addr -= offsetof(struct user, u_debugreg[0]);
+                addr = addr >> 2;
+                tmp = child->thread.arch.debugregs[addr];
+        }
+        return put_user(tmp, (unsigned long *) data);
+}
+
 struct i387_fxsave_struct {
        unsigned short  cwd;
        unsigned short  swd;
index 76ba87254b251d7091ca919a9f8f2ec74bf87772..03913ca5d256ac2f7c699e57dde29523dd51b52b 100644 (file)
@@ -47,9 +47,6 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
        REGS_CS(regs->regs.skas.regs) = sc.cs;
        REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags;
        REGS_SS(regs->regs.skas.regs) = sc.ss;
-       regs->regs.skas.fault_addr = sc.cr2;
-       regs->regs.skas.fault_type = FAULT_WRITE(sc.err);
-       regs->regs.skas.trap_type = sc.trapno;
 
        err = restore_fp_registers(userspace_pid[0], fpregs);
        if(err < 0){
@@ -62,11 +59,11 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
 }
 
 int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
-                        struct pt_regs *regs, unsigned long fault_addr,
-                        int fault_type)
+                         struct pt_regs *regs)
 {
        struct sigcontext sc;
        unsigned long fpregs[HOST_FP_SIZE];
+       struct faultinfo * fi = &current->thread.arch.faultinfo;
        int err;
 
        sc.gs = REGS_GS(regs->regs.skas.regs);
@@ -86,9 +83,9 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
        sc.eflags = REGS_EFLAGS(regs->regs.skas.regs);
        sc.esp_at_signal = regs->regs.skas.regs[UESP];
        sc.ss = regs->regs.skas.regs[SS];
-       sc.cr2 = fault_addr;
-       sc.err = TO_SC_ERR(fault_type);
-       sc.trapno = regs->regs.skas.trap_type;
+        sc.cr2 = fi->cr2;
+        sc.err = fi->error_code;
+        sc.trapno = fi->trap_no;
 
        err = save_fp_registers(userspace_pid[0], fpregs);
        if(err < 0){
@@ -167,9 +164,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
 {
        return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
                                              sizeof(*fp)),
-                          copy_sc_to_user_skas(to, fp, from,
-                                               current->thread.cr2,
-                                               current->thread.err)));
+                           copy_sc_to_user_skas(to, fp, from)));
 }
 
 static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
index 281fc7b8ca00bbdfa9a9a892803e0365c600c3ec..e3706d15c4f51bfefe364ee37c45c5fe99375c12 100644 (file)
@@ -3,12 +3,15 @@
  * Licensed under the GPL
  */
 
+#include "linux/config.h"
 #include "linux/kernel.h"
 #include "linux/smp.h"
 #include "linux/sched.h"
+#include "linux/kallsyms.h"
 #include "asm/ptrace.h"
 #include "sysrq.h"
 
+/* This is declared by <linux/sched.h> */
 void show_regs(struct pt_regs *regs)
 {
         printk("\n");
@@ -31,5 +34,80 @@ void show_regs(struct pt_regs *regs)
               0xffff & PT_REGS_DS(regs), 
               0xffff & PT_REGS_ES(regs));
 
-        show_trace((unsigned long *) &regs);
+        show_trace(NULL, (unsigned long *) &regs);
 }
+
+/* Copied from i386. */
+static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
+{
+       return  p > (void *)tinfo &&
+               p < (void *)tinfo + THREAD_SIZE - 3;
+}
+
+/* Adapted from i386 (we also print the address we read from). */
+static inline unsigned long print_context_stack(struct thread_info *tinfo,
+                               unsigned long *stack, unsigned long ebp)
+{
+       unsigned long addr;
+
+#ifdef CONFIG_FRAME_POINTER
+       while (valid_stack_ptr(tinfo, (void *)ebp)) {
+               addr = *(unsigned long *)(ebp + 4);
+               printk("%08lx:  [<%08lx>]", ebp + 4, addr);
+               print_symbol(" %s", addr);
+               printk("\n");
+               ebp = *(unsigned long *)ebp;
+       }
+#else
+       while (valid_stack_ptr(tinfo, stack)) {
+               addr = *stack;
+               if (__kernel_text_address(addr)) {
+                       printk("%08lx:  [<%08lx>]", (unsigned long) stack, addr);
+                       print_symbol(" %s", addr);
+                       printk("\n");
+               }
+               stack++;
+       }
+#endif
+       return ebp;
+}
+
+void show_trace(struct task_struct* task, unsigned long * stack)
+{
+       unsigned long ebp;
+       struct thread_info *context;
+
+       /* Turn this into BUG_ON if possible. */
+       if (!stack) {
+               stack = (unsigned long*) &stack;
+               printk("show_trace: got NULL stack, implicit assumption task == current");
+               WARN_ON(1);
+       }
+
+       if (!task)
+               task = current;
+
+       if (task != current) {
+               //ebp = (unsigned long) KSTK_EBP(task);
+               /* Which one? No actual difference - just coding style.*/
+               ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
+       } else {
+               asm ("movl %%ebp, %0" : "=r" (ebp) : );
+       }
+
+       context = (struct thread_info *)
+               ((unsigned long)stack & (~(THREAD_SIZE - 1)));
+       print_context_stack(context, stack, ebp);
+
+       /*while (((long) stack & (THREAD_SIZE-1)) != 0) {
+               addr = *stack;
+               if (__kernel_text_address(addr)) {
+                       printk("%08lx:  [<%08lx>]", (unsigned long) stack, addr);
+                       print_symbol(" %s", addr);
+                       printk("\n");
+               }
+               stack++;
+       }*/
+       printk("\n");
+}
+
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
new file mode 100644 (file)
index 0000000..3ceaabc
--- /dev/null
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <signal.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <linux/stddef.h>
+
+#define DEFINE(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define OFFSET(sym, str, mem) \
+       DEFINE(sym, offsetof(struct str, mem));
+
+void foo(void)
+{
+       OFFSET(SC_IP, sigcontext, eip);
+       OFFSET(SC_SP, sigcontext, esp);
+       OFFSET(SC_FS, sigcontext, fs);
+       OFFSET(SC_GS, sigcontext, gs);
+       OFFSET(SC_DS, sigcontext, ds);
+       OFFSET(SC_ES, sigcontext, es);
+       OFFSET(SC_SS, sigcontext, ss);
+       OFFSET(SC_CS, sigcontext, cs);
+       OFFSET(SC_EFLAGS, sigcontext, eflags);
+       OFFSET(SC_EAX, sigcontext, eax);
+       OFFSET(SC_EBX, sigcontext, ebx);
+       OFFSET(SC_ECX, sigcontext, ecx);
+       OFFSET(SC_EDX, sigcontext, edx);
+       OFFSET(SC_EDI, sigcontext, edi);
+       OFFSET(SC_ESI, sigcontext, esi);
+       OFFSET(SC_EBP, sigcontext, ebp);
+       OFFSET(SC_TRAPNO, sigcontext, trapno);
+       OFFSET(SC_ERR, sigcontext, err);
+       OFFSET(SC_CR2, sigcontext, cr2);
+       OFFSET(SC_FPSTATE, sigcontext, fpstate);
+       OFFSET(SC_SIGMASK, sigcontext, oldmask);
+       OFFSET(SC_FP_CW, _fpstate, cw);
+       OFFSET(SC_FP_SW, _fpstate, sw);
+       OFFSET(SC_FP_TAG, _fpstate, tag);
+       OFFSET(SC_FP_IPOFF, _fpstate, ipoff);
+       OFFSET(SC_FP_CSSEL, _fpstate, cssel);
+       OFFSET(SC_FP_DATAOFF, _fpstate, dataoff);
+       OFFSET(SC_FP_DATASEL, _fpstate, datasel);
+       OFFSET(SC_FP_ST, _fpstate, _st);
+       OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env);
+
+       DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
+       DEFINE(HOST_FP_SIZE,
+               sizeof(struct user_i387_struct) / sizeof(unsigned long));
+       DEFINE(HOST_XFP_SIZE,
+              sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
+
+       DEFINE(HOST_IP, EIP);
+       DEFINE(HOST_SP, UESP);
+       DEFINE(HOST_EFLAGS, EFL);
+       DEFINE(HOST_EAX, EAX);
+       DEFINE(HOST_EBX, EBX);
+       DEFINE(HOST_ECX, ECX);
+       DEFINE(HOST_EDX, EDX);
+       DEFINE(HOST_ESI, ESI);
+       DEFINE(HOST_EDI, EDI);
+       DEFINE(HOST_EBP, EBP);
+       DEFINE(HOST_CS, CS);
+       DEFINE(HOST_SS, SS);
+       DEFINE(HOST_DS, DS);
+       DEFINE(HOST_FS, FS);
+       DEFINE(HOST_ES, ES);
+       DEFINE(HOST_GS, GS);
+       DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+}
index 34860f9ca7b0deafa3a41cd4dcdae247c1770521..bf61afd0b0456b6d5ebde119ca69007929173fad 100644 (file)
@@ -1,8 +1,5 @@
-
 hostprogs-y    := mk_sc mk_thread
 always         := $(hostprogs-y)
 
-mk_thread-objs := mk_thread_kern.o mk_thread_user.o
-
-HOSTCFLAGS_mk_thread_kern.o    := $(CFLAGS) $(CPPFLAGS)
-HOSTCFLAGS_mk_thread_user.o    := $(USER_CFLAGS)
+HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
+HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
index 85cbd30396f788465b25dac92b62e4af0d718ef3..04c0d73433aaff370238a15023869dd2686e645b 100644 (file)
@@ -1,52 +1,51 @@
 #include <stdio.h>
-#include <signal.h>
-#include <linux/stddef.h>
+#include <user-offsets.h>
 
 #define SC_OFFSET(name, field) \
-  printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
-        offsetof(struct sigcontext, field))
+  printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
+        name)
 
 #define SC_FP_OFFSET(name, field) \
-  printf("#define " name \
+  printf("#define " #name \
         "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
-        offsetof(struct _fpstate, field))
+        name)
 
 #define SC_FP_OFFSET_PTR(name, field, type) \
-  printf("#define " name \
+  printf("#define " #name \
         "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
-        offsetof(struct _fpstate, field))
+        name)
 
 int main(int argc, char **argv)
 {
-  SC_OFFSET("SC_IP", eip);
-  SC_OFFSET("SC_SP", esp);
-  SC_OFFSET("SC_FS", fs);
-  SC_OFFSET("SC_GS", gs);
-  SC_OFFSET("SC_DS", ds);
-  SC_OFFSET("SC_ES", es);
-  SC_OFFSET("SC_SS", ss);
-  SC_OFFSET("SC_CS", cs);
-  SC_OFFSET("SC_EFLAGS", eflags);
-  SC_OFFSET("SC_EAX", eax);
-  SC_OFFSET("SC_EBX", ebx);
-  SC_OFFSET("SC_ECX", ecx);
-  SC_OFFSET("SC_EDX", edx);
-  SC_OFFSET("SC_EDI", edi);
-  SC_OFFSET("SC_ESI", esi);
-  SC_OFFSET("SC_EBP", ebp);
-  SC_OFFSET("SC_TRAPNO", trapno);
-  SC_OFFSET("SC_ERR", err);
-  SC_OFFSET("SC_CR2", cr2);
-  SC_OFFSET("SC_FPSTATE", fpstate);
-  SC_OFFSET("SC_SIGMASK", oldmask);
-  SC_FP_OFFSET("SC_FP_CW", cw);
-  SC_FP_OFFSET("SC_FP_SW", sw);
-  SC_FP_OFFSET("SC_FP_TAG", tag);
-  SC_FP_OFFSET("SC_FP_IPOFF", ipoff);
-  SC_FP_OFFSET("SC_FP_CSSEL", cssel);
-  SC_FP_OFFSET("SC_FP_DATAOFF", dataoff);
-  SC_FP_OFFSET("SC_FP_DATASEL", datasel);
-  SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate");
-  SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void");
+  SC_OFFSET(SC_IP, eip);
+  SC_OFFSET(SC_SP, esp);
+  SC_OFFSET(SC_FS, fs);
+  SC_OFFSET(SC_GS, gs);
+  SC_OFFSET(SC_DS, ds);
+  SC_OFFSET(SC_ES, es);
+  SC_OFFSET(SC_SS, ss);
+  SC_OFFSET(SC_CS, cs);
+  SC_OFFSET(SC_EFLAGS, eflags);
+  SC_OFFSET(SC_EAX, eax);
+  SC_OFFSET(SC_EBX, ebx);
+  SC_OFFSET(SC_ECX, ecx);
+  SC_OFFSET(SC_EDX, edx);
+  SC_OFFSET(SC_EDI, edi);
+  SC_OFFSET(SC_ESI, esi);
+  SC_OFFSET(SC_EBP, ebp);
+  SC_OFFSET(SC_TRAPNO, trapno);
+  SC_OFFSET(SC_ERR, err);
+  SC_OFFSET(SC_CR2, cr2);
+  SC_OFFSET(SC_FPSTATE, fpstate);
+  SC_OFFSET(SC_SIGMASK, oldmask);
+  SC_FP_OFFSET(SC_FP_CW, cw);
+  SC_FP_OFFSET(SC_FP_SW, sw);
+  SC_FP_OFFSET(SC_FP_TAG, tag);
+  SC_FP_OFFSET(SC_FP_IPOFF, ipoff);
+  SC_FP_OFFSET(SC_FP_CSSEL, cssel);
+  SC_FP_OFFSET(SC_FP_DATAOFF, dataoff);
+  SC_FP_OFFSET(SC_FP_DATASEL, datasel);
+  SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate");
+  SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void");
   return(0);
 }
diff --git a/arch/um/sys-i386/util/mk_thread.c b/arch/um/sys-i386/util/mk_thread.c
new file mode 100644 (file)
index 0000000..7470d0d
--- /dev/null
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <kernel-offsets.h>
+
+int main(int argc, char **argv)
+{
+  printf("/*\n");
+  printf(" * Generated by mk_thread\n");
+  printf(" */\n");
+  printf("\n");
+  printf("#ifndef __UM_THREAD_H\n");
+  printf("#define __UM_THREAD_H\n");
+  printf("\n");
+  printf("#define TASK_DEBUGREGS(task) ((unsigned long *) "
+        "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS);
+#ifdef TASK_EXTERN_PID
+  printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
+        TASK_EXTERN_PID);
+#endif
+  printf("\n");
+  printf("#endif\n");
+  return(0);
+}
diff --git a/arch/um/sys-i386/util/mk_thread_kern.c b/arch/um/sys-i386/util/mk_thread_kern.c
deleted file mode 100644 (file)
index 948b1ce..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "linux/config.h"
-#include "linux/stddef.h"
-#include "linux/sched.h"
-
-extern void print_head(void);
-extern void print_constant_ptr(char *name, int value);
-extern void print_constant(char *name, char *type, int value);
-extern void print_tail(void);
-
-#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
-
-int main(int argc, char **argv)
-{
-  print_head();
-  print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
-#ifdef CONFIG_MODE_TT
-  print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
-#endif
-  print_tail();
-  return(0);
-}
-
diff --git a/arch/um/sys-i386/util/mk_thread_user.c b/arch/um/sys-i386/util/mk_thread_user.c
deleted file mode 100644 (file)
index 2620cd6..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdio.h>
-
-void print_head(void)
-{
-  printf("/*\n");
-  printf(" * Generated by mk_thread\n");
-  printf(" */\n");
-  printf("\n");
-  printf("#ifndef __UM_THREAD_H\n");
-  printf("#define __UM_THREAD_H\n");
-  printf("\n");
-}
-
-void print_constant_ptr(char *name, int value)
-{
-  printf("#define %s(task) ((unsigned long *) "
-        "&(((char *) (task))[%d]))\n", name, value);
-}
-
-void print_constant(char *name, char *type, int value)
-{
-  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, 
-        value);
-}
-
-void print_tail(void)
-{
-  printf("\n");
-  printf("#endif\n");
-}
index a971366d3277a4f8733c113262abf29e2bc6d13f..8e71b47f2b8ed86f9bee12696b773c3e99f011e8 100644 (file)
@@ -8,6 +8,25 @@ int putreg(struct task_struct *child, unsigned long regno,
        return 0;
 }
 
+int poke_user(struct task_struct *child, long addr, long data)
+{
+       if ((addr & 3) || addr < 0)
+               return -EIO;
+
+       if (addr < MAX_REG_OFFSET)
+               return putreg(child, addr, data);
+
+       else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+               (addr <= offsetof(struct user, u_debugreg[7]))){
+                 addr -= offsetof(struct user, u_debugreg[0]);
+                 addr = addr >> 2;
+                 if((addr == 4) || (addr == 5)) return -EIO;
+                 child->thread.arch.debugregs[addr] = data;
+                 return 0;
+       }
+       return -EIO;
+}
+
 unsigned long getreg(struct task_struct *child, unsigned long regno)
 {
        unsigned long retval = ~0UL;
@@ -16,6 +35,27 @@ unsigned long getreg(struct task_struct *child, unsigned long regno)
        return retval;
 }
 
+int peek_user(struct task_struct *child, long addr, long data)
+{
+       /* read the word at location addr in the USER area. */
+       unsigned long tmp;
+
+       if ((addr & 3) || addr < 0)
+               return -EIO;
+
+       tmp = 0;  /* Default return condition */
+       if(addr < MAX_REG_OFFSET){
+               tmp = getreg(child, addr);
+       }
+       else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+               (addr <= offsetof(struct user, u_debugreg[7]))){
+               addr -= offsetof(struct user, u_debugreg[0]);
+               addr = addr >> 2;
+               tmp = child->thread.arch.debugregs[addr];
+       }
+       return put_user(tmp, (unsigned long *) data);
+}
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
index 82d6e9335bb6bc9c8614c3e10c55e95e68516efa..2f816f1a0ff4d3ceae814f81e8aedd107b955430 100644 (file)
@@ -27,17 +27,5 @@ void show_regs(struct pt_regs_subarch *regs)
                 0xffff & regs->xds, 0xffff & regs->xes);
 #endif
 
-        show_trace(&regs->gpr[1]);
+        show_trace(current, &regs->gpr[1]);
 }
-
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index d7ed2f7908dfbe5d95121196f6991b20573db3ef..608466ad6b22309c802f2df4af9ffca71dc21d98 100644 (file)
@@ -4,24 +4,20 @@
 # Licensed under the GPL
 #
 
+#XXX: why into lib-y?
 lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
        ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \
        syscalls.o sysrq.o thunk.o syscall_table.o
 
-USER_OBJS := ptrace_user.o sigcontext.o
+obj-y := ksyms.o
+obj-$(CONFIG_MODULES) += module.o um_module.o
 
-include arch/um/scripts/Makefile.rules
+USER_OBJS := ptrace_user.o sigcontext.o
 
 SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
-       semaphore.c thunk.S
-
-# this needs to be before the foreach, because clean-files does not accept
-# complete paths like $(src)/$f.
-clean-files := $(SYMLINKS)
+       semaphore.c thunk.S module.c
 
-targets += $(SYMLINKS)
-
-SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f)
+include arch/um/scripts/Makefile.rules
 
 bitops.c-dir = lib
 csum-copy.S-dir = lib
@@ -30,8 +26,6 @@ csum-wrappers.c-dir = lib
 memcpy.S-dir = lib
 semaphore.c-dir = kernel
 thunk.S-dir = lib
+module.c-dir = kernel
 
-$(SYMLINKS): FORCE
-       $(call if_changed,make_link)
-
-CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial
+subdir- := util
index f3b5187942b4e65ef14dd27e869fecd50861c7be..137f4446b4390cfe49b7036de853b1fff05d350a 100644 (file)
@@ -5,22 +5,37 @@
  * Licensed under the GPL
  */
 
-#include "asm/processor.h"
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <asm/processor.h>
+#include <asm/param.h>
 
 void __delay(unsigned long loops)
 {
        unsigned long i;
 
-       for(i = 0; i < loops; i++) ;
+        for(i = 0; i < loops; i++)
+                cpu_relax();
 }
 
-/*
- * 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-file-style: "linux"
- * End:
- */
+void __udelay(unsigned long usecs)
+{
+       unsigned long i, n;
+
+       n = (loops_per_jiffy * HZ * usecs) / MILLION;
+        for(i=0;i<n;i++)
+                cpu_relax();
+}
+
+EXPORT_SYMBOL(__udelay);
+
+void __const_udelay(unsigned long usecs)
+{
+       unsigned long i, n;
+
+       n = (loops_per_jiffy * HZ * usecs) / MILLION;
+        for(i=0;i<n;i++)
+                cpu_relax();
+}
+
+EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c
new file mode 100644 (file)
index 0000000..220e875
--- /dev/null
@@ -0,0 +1,24 @@
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <asm/page.h>
+
+#define DEFINE(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define DEFINE_STR1(x) #x
+#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : )
+
+#define BLANK() asm volatile("\n->" : : )
+
+#define OFFSET(sym, str, mem) \
+       DEFINE(sym, offsetof(struct str, mem));
+
+void foo(void)
+{
+#ifdef CONFIG_MODE_TT
+       OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+#endif
+#include <common-offsets.h>
+}
diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c
new file mode 100644 (file)
index 0000000..8592738
--- /dev/null
@@ -0,0 +1,19 @@
+#include "linux/module.h"
+#include "linux/in6.h"
+#include "linux/rwsem.h"
+#include "asm/byteorder.h"
+#include "asm/semaphore.h"
+#include "asm/uaccess.h"
+#include "asm/checksum.h"
+#include "asm/errno.h"
+
+EXPORT_SYMBOL(__down_failed);
+EXPORT_SYMBOL(__down_failed_interruptible);
+EXPORT_SYMBOL(__down_failed_trylock);
+EXPORT_SYMBOL(__up_wakeup);
+
+/*XXX: we need them because they would be exported by x86_64 */
+EXPORT_SYMBOL(__memcpy);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(ip_compute_csum);
index 8c146b2a1e00aea210e9b5166b3b6b4753fc8406..74eee5c7c6dd7aa3b6b79d244bb54d2cda33439a 100644 (file)
@@ -5,10 +5,11 @@
  */
 
 #define __FRAME_OFFSETS
-#include "asm/ptrace.h"
-#include "linux/sched.h"
-#include "linux/errno.h"
-#include "asm/elf.h"
+#include <asm/ptrace.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+#include <asm/elf.h>
 
 /* XXX x86_64 */
 unsigned long not_ss;
@@ -62,6 +63,27 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
        return 0;
 }
 
+int poke_user(struct task_struct *child, long addr, long data)
+{
+        if ((addr & 3) || addr < 0)
+                return -EIO;
+
+        if (addr < MAX_REG_OFFSET)
+                return putreg(child, addr, data);
+
+#if 0 /* Need x86_64 debugregs handling */
+        else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+                (addr <= offsetof(struct user, u_debugreg[7]))){
+                addr -= offsetof(struct user, u_debugreg[0]);
+                addr = addr >> 2;
+                if((addr == 4) || (addr == 5)) return -EIO;
+                child->thread.arch.debugregs[addr] = data;
+                return 0;
+        }
+#endif
+        return -EIO;
+}
+
 unsigned long getreg(struct task_struct *child, int regno)
 {
        unsigned long retval = ~0UL;
@@ -84,6 +106,29 @@ unsigned long getreg(struct task_struct *child, int regno)
        return retval;
 }
 
+int peek_user(struct task_struct *child, long addr, long data)
+{
+       /* read the word at location addr in the USER area. */
+        unsigned long tmp;
+
+        if ((addr & 3) || addr < 0)
+                return -EIO;
+
+        tmp = 0;  /* Default return condition */
+        if(addr < MAX_REG_OFFSET){
+                tmp = getreg(child, addr);
+        }
+#if 0 /* Need x86_64 debugregs handling */
+        else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+                (addr <= offsetof(struct user, u_debugreg[7]))){
+                addr -= offsetof(struct user, u_debugreg[0]);
+                addr = addr >> 2;
+                tmp = child->thread.arch.debugregs[addr];
+        }
+#endif
+        return put_user(tmp, (unsigned long *) data);
+}
+
 void arch_switch(void)
 {
 /* XXX
index 5bc5a0d796e5d4fd518335724bc7ea7dd500e738..73a7926f73705d100809adc35b567cb0594cb712 100644 (file)
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
 int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
                         struct pt_regs *regs, unsigned long mask)
 {
-       unsigned long eflags;
+        struct faultinfo * fi = &current->thread.arch.faultinfo;
        int err = 0;
 
        err |= __put_user(0, &to->gs);
@@ -84,14 +84,16 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
        err |= PUTREG(regs, R14, to, r14);
        err |= PUTREG(regs, R15, to, r15);
        err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */
-       err |= __put_user(current->thread.err, &to->err);
-       err |= __put_user(current->thread.trap_no, &to->trapno);
+
+        err |= __put_user(fi->cr2, &to->cr2);
+        err |= __put_user(fi->error_code, &to->err);
+        err |= __put_user(fi->trap_no, &to->trapno);
+
        err |= PUTREG(regs, RIP, to, rip);
        err |= PUTREG(regs, EFLAGS, to, eflags);
 #undef PUTREG
 
        err |= __put_user(mask, &to->oldmask);
-       err |= __put_user(current->thread.cr2, &to->cr2);
 
        return(err);
 }
@@ -166,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 
        frame = (struct rt_sigframe __user *)
                round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
-       frame -= 128;
+       ((unsigned char *) frame) -= 128;
 
        if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
                goto out;
index ab4b0abf8af3fe528881a2f6a95429d6469d8f57..6f44f40204ed0947ffe93f6358a0a517649b6fd8 100644 (file)
@@ -7,12 +7,15 @@
 #include "linux/linkage.h"
 #include "linux/slab.h"
 #include "linux/shm.h"
+#include "linux/utsname.h"
+#include "linux/personality.h"
 #include "asm/uaccess.h"
 #define __FRAME_OFFSETS
 #include "asm/ptrace.h"
 #include "asm/unistd.h"
 #include "asm/prctl.h" /* XXX This should get the constants from libc */
 #include "choose-mode.h"
+#include "kern.h"
 
 asmlinkage long sys_uname64(struct new_utsname __user * name)
 {
@@ -42,6 +45,8 @@ long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
 #ifdef CONFIG_MODE_SKAS
 extern int userspace_pid[];
 
+#include "skas_ptrace.h"
+
 long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
 {
        struct ptrace_ldt ldt;
@@ -128,23 +133,27 @@ static long arch_prctl_tt(int code, unsigned long addr)
 
 #ifdef CONFIG_MODE_SKAS
 
+/* XXX: Must also call arch_prctl in the host, beside saving the segment bases! */
 static long arch_prctl_skas(int code, unsigned long addr)
 {
        long ret = 0;
 
        switch(code){
-       case ARCH_SET_GS:
-               current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
-               break;
        case ARCH_SET_FS:
                current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
                break;
+       case ARCH_SET_GS:
+               current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
+               break;
        case ARCH_GET_FS:
-               ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr);
+               ret = put_user(current->thread.regs.regs.skas.
+                               regs[FS_BASE / sizeof(unsigned long)],
+                               (unsigned long __user *)addr);
                break;
        case ARCH_GET_GS:
-               ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \
-long)], &addr);
+               ret = put_user(current->thread.regs.regs.skas.
+                               regs[GS_BASE / sizeof(unsigned long)],
+                               (unsigned long __user *)addr);
                break;
        default:
                ret = -EINVAL;
index ddf74691a6109cfb406123c01354cf6b20cd9a15..d0a25af19a5bd216dc2995807fb0ed410238b44e 100644 (file)
@@ -36,14 +36,5 @@ void __show_regs(struct pt_regs * regs)
 void show_regs(struct pt_regs *regs)
 {
        __show_regs(regs);
-       show_trace((unsigned long *) &regs);
+       show_trace(current, (unsigned long *) &regs);
 }
-
-/* 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-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/um_module.c b/arch/um/sys-x86_64/um_module.c
new file mode 100644 (file)
index 0000000..8b8eff1
--- /dev/null
@@ -0,0 +1,19 @@
+#include <linux/vmalloc.h>
+#include <linux/moduleloader.h>
+
+/*Copied from i386 arch/i386/kernel/module.c */
+void *module_alloc(unsigned long size)
+{
+       if (size == 0)
+               return NULL;
+       return vmalloc_exec(size);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+       vfree(module_region);
+       /* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
new file mode 100644 (file)
index 0000000..513d17c
--- /dev/null
@@ -0,0 +1,86 @@
+#include <stdio.h>
+#include <stddef.h>
+#include <signal.h>
+#define __FRAME_OFFSETS
+#include <asm/ptrace.h>
+#include <asm/types.h>
+/* For some reason, x86_64 defines u64 and u32 only in <pci/types.h>, which I
+ * refuse to include here, even though they're used throughout the headers.
+ * These are used in asm/user.h, and that include can't be avoided because of
+ * the sizeof(struct user_regs_struct) below.
+ */
+typedef __u64 u64;
+typedef __u32 u32;
+#include <asm/user.h>
+
+#define DEFINE(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define OFFSET(sym, str, mem) \
+       DEFINE(sym, offsetof(struct str, mem));
+
+void foo(void)
+{
+       OFFSET(SC_RBX, sigcontext, rbx);
+       OFFSET(SC_RCX, sigcontext, rcx);
+       OFFSET(SC_RDX, sigcontext, rdx);
+       OFFSET(SC_RSI, sigcontext, rsi);
+       OFFSET(SC_RDI, sigcontext, rdi);
+       OFFSET(SC_RBP, sigcontext, rbp);
+       OFFSET(SC_RAX, sigcontext, rax);
+       OFFSET(SC_R8, sigcontext, r8);
+       OFFSET(SC_R9, sigcontext, r9);
+       OFFSET(SC_R10, sigcontext, r10);
+       OFFSET(SC_R11, sigcontext, r11);
+       OFFSET(SC_R12, sigcontext, r12);
+       OFFSET(SC_R13, sigcontext, r13);
+       OFFSET(SC_R14, sigcontext, r14);
+       OFFSET(SC_R15, sigcontext, r15);
+       OFFSET(SC_IP, sigcontext, rip);
+       OFFSET(SC_SP, sigcontext, rsp);
+       OFFSET(SC_CR2, sigcontext, cr2);
+       OFFSET(SC_ERR, sigcontext, err);
+       OFFSET(SC_TRAPNO, sigcontext, trapno);
+       OFFSET(SC_CS, sigcontext, cs);
+       OFFSET(SC_FS, sigcontext, fs);
+       OFFSET(SC_GS, sigcontext, gs);
+       OFFSET(SC_EFLAGS, sigcontext, eflags);
+       OFFSET(SC_SIGMASK, sigcontext, oldmask);
+#if 0
+       OFFSET(SC_ORIG_RAX, sigcontext, orig_rax);
+       OFFSET(SC_DS, sigcontext, ds);
+       OFFSET(SC_ES, sigcontext, es);
+       OFFSET(SC_SS, sigcontext, ss);
+#endif
+
+       DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
+       DEFINE(HOST_RBX, RBX);
+       DEFINE(HOST_RCX, RCX);
+       DEFINE(HOST_RDI, RDI);
+       DEFINE(HOST_RSI, RSI);
+       DEFINE(HOST_RDX, RDX);
+       DEFINE(HOST_RBP, RBP);
+       DEFINE(HOST_RAX, RAX);
+       DEFINE(HOST_R8, R8);
+       DEFINE(HOST_R9, R9);
+       DEFINE(HOST_R10, R10);
+       DEFINE(HOST_R11, R11);
+       DEFINE(HOST_R12, R12);
+       DEFINE(HOST_R13, R13);
+       DEFINE(HOST_R14, R14);
+       DEFINE(HOST_R15, R15);
+       DEFINE(HOST_ORIG_RAX, ORIG_RAX);
+       DEFINE(HOST_CS, CS);
+       DEFINE(HOST_SS, SS);
+       DEFINE(HOST_EFLAGS, EFLAGS);
+#if 0
+       DEFINE(HOST_FS, FS);
+       DEFINE(HOST_GS, GS);
+       DEFINE(HOST_DS, DS);
+       DEFINE(HOST_ES, ES);
+#endif
+
+       DEFINE(HOST_IP, RIP);
+       DEFINE(HOST_SP, RSP);
+       DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+}
index 002607980864c4b5c2a9687be52633c53c414109..75b052cfc2066c4b4f915c51899bd94d5dd11915 100644 (file)
@@ -4,7 +4,5 @@
 hostprogs-y    := mk_sc mk_thread
 always         := $(hostprogs-y)
 
-mk_thread-objs := mk_thread_kern.o mk_thread_user.o
-
-HOSTCFLAGS_mk_thread_kern.o    := $(CFLAGS) $(CPPFLAGS)
-HOSTCFLAGS_mk_thread_user.o    := $(USER_CFLAGS)
+HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
+HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
index c236e213918db43c6097ad7cab9e694232a34674..7619bc377c1f43c030506f6756bfa90eaa1df8b7 100644 (file)
@@ -3,56 +3,45 @@
  */
 
 #include <stdio.h>
-#include <signal.h>
-#include <linux/stddef.h>
+#include <user-offsets.h>
 
-#define SC_OFFSET(name, field) \
-  printf("#define " name \
-        "(sc) *((unsigned long *) &(((char *) (sc))[%ld]))\n",\
-        offsetof(struct sigcontext, field))
-
-#define SC_FP_OFFSET(name, field) \
-  printf("#define " name \
-        "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%ld]))\n",\
-        offsetof(struct _fpstate, field))
-
-#define SC_FP_OFFSET_PTR(name, field, type) \
-  printf("#define " name \
-        "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
-        offsetof(struct _fpstate, field))
+#define SC_OFFSET(name) \
+  printf("#define " #name \
+        "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
+        name)
 
 int main(int argc, char **argv)
 {
-  SC_OFFSET("SC_RBX", rbx);
-  SC_OFFSET("SC_RCX", rcx);
-  SC_OFFSET("SC_RDX", rdx);
-  SC_OFFSET("SC_RSI", rsi);
-  SC_OFFSET("SC_RDI", rdi);
-  SC_OFFSET("SC_RBP", rbp);
-  SC_OFFSET("SC_RAX", rax);
-  SC_OFFSET("SC_R8", r8);
-  SC_OFFSET("SC_R9", r9);
-  SC_OFFSET("SC_R10", r10);
-  SC_OFFSET("SC_R11", r11);
-  SC_OFFSET("SC_R12", r12);
-  SC_OFFSET("SC_R13", r13);
-  SC_OFFSET("SC_R14", r14);
-  SC_OFFSET("SC_R15", r15);
-  SC_OFFSET("SC_IP", rip);
-  SC_OFFSET("SC_SP", rsp);
-  SC_OFFSET("SC_CR2", cr2);
-  SC_OFFSET("SC_ERR", err);
-  SC_OFFSET("SC_TRAPNO", trapno);
-  SC_OFFSET("SC_CS", cs);
-  SC_OFFSET("SC_FS", fs);
-  SC_OFFSET("SC_GS", gs);
-  SC_OFFSET("SC_EFLAGS", eflags);
-  SC_OFFSET("SC_SIGMASK", oldmask);
+  SC_OFFSET(SC_RBX);
+  SC_OFFSET(SC_RCX);
+  SC_OFFSET(SC_RDX);
+  SC_OFFSET(SC_RSI);
+  SC_OFFSET(SC_RDI);
+  SC_OFFSET(SC_RBP);
+  SC_OFFSET(SC_RAX);
+  SC_OFFSET(SC_R8);
+  SC_OFFSET(SC_R9);
+  SC_OFFSET(SC_R10);
+  SC_OFFSET(SC_R11);
+  SC_OFFSET(SC_R12);
+  SC_OFFSET(SC_R13);
+  SC_OFFSET(SC_R14);
+  SC_OFFSET(SC_R15);
+  SC_OFFSET(SC_IP);
+  SC_OFFSET(SC_SP);
+  SC_OFFSET(SC_CR2);
+  SC_OFFSET(SC_ERR);
+  SC_OFFSET(SC_TRAPNO);
+  SC_OFFSET(SC_CS);
+  SC_OFFSET(SC_FS);
+  SC_OFFSET(SC_GS);
+  SC_OFFSET(SC_EFLAGS);
+  SC_OFFSET(SC_SIGMASK);
 #if 0
-  SC_OFFSET("SC_ORIG_RAX", orig_rax);
-  SC_OFFSET("SC_DS", ds);
-  SC_OFFSET("SC_ES", es);
-  SC_OFFSET("SC_SS", ss);
+  SC_OFFSET(SC_ORIG_RAX);
+  SC_OFFSET(SC_DS);
+  SC_OFFSET(SC_ES);
+  SC_OFFSET(SC_SS);
 #endif
   return(0);
 }
diff --git a/arch/um/sys-x86_64/util/mk_thread.c b/arch/um/sys-x86_64/util/mk_thread.c
new file mode 100644 (file)
index 0000000..1551739
--- /dev/null
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <kernel-offsets.h>
+
+int main(int argc, char **argv)
+{
+  printf("/*\n");
+  printf(" * Generated by mk_thread\n");
+  printf(" */\n");
+  printf("\n");
+  printf("#ifndef __UM_THREAD_H\n");
+  printf("#define __UM_THREAD_H\n");
+  printf("\n");
+#ifdef TASK_EXTERN_PID
+  printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
+        TASK_EXTERN_PID);
+#endif
+  printf("\n");
+  printf("#endif\n");
+  return(0);
+}
diff --git a/arch/um/sys-x86_64/util/mk_thread_kern.c b/arch/um/sys-x86_64/util/mk_thread_kern.c
deleted file mode 100644 (file)
index a281673..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "linux/config.h"
-#include "linux/stddef.h"
-#include "linux/sched.h"
-
-extern void print_head(void);
-extern void print_constant_ptr(char *name, int value);
-extern void print_constant(char *name, char *type, int value);
-extern void print_tail(void);
-
-#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
-
-int main(int argc, char **argv)
-{
-  print_head();
-#ifdef CONFIG_MODE_TT
-  print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
-#endif
-  print_tail();
-  return(0);
-}
-
diff --git a/arch/um/sys-x86_64/util/mk_thread_user.c b/arch/um/sys-x86_64/util/mk_thread_user.c
deleted file mode 100644 (file)
index 7989725..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdio.h>
-
-void print_head(void)
-{
-  printf("/*\n");
-  printf(" * Generated by mk_thread\n");
-  printf(" */\n");
-  printf("\n");
-  printf("#ifndef __UM_THREAD_H\n");
-  printf("#define __UM_THREAD_H\n");
-  printf("\n");
-}
-
-void print_constant_ptr(char *name, int value)
-{
-  printf("#define %s(task) ((unsigned long *) "
-        "&(((char *) (task))[%d]))\n", name, value);
-}
-
-void print_constant(char *name, char *type, int value)
-{
-  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
-        value);
-}
-
-void print_tail(void)
-{
-  printf("\n");
-  printf("#endif\n");
-}
index e2ab71209f3f8acedb10b911af487ead0fa804be..4c7551c28033bf5c7c69409bcf11178c2db2d5b4 100644 (file)
@@ -1,8 +1,5 @@
 hostprogs-y            := mk_task mk_constants
 always                 := $(hostprogs-y)
 
-mk_task-objs           := mk_task_user.o mk_task_kern.o
-mk_constants-objs      := mk_constants_user.o mk_constants_kern.o
-
-HOSTCFLAGS_mk_task_kern.o      := $(CFLAGS) $(CPPFLAGS)
-HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS) $(CPPFLAGS)
+HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um
+HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c
new file mode 100644 (file)
index 0000000..ab217be
--- /dev/null
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <kernel-offsets.h>
+
+#define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym)
+#define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym)
+
+int main(int argc, char **argv)
+{
+  printf("/*\n");
+  printf(" * Generated by mk_constants\n");
+  printf(" */\n");
+  printf("\n");
+  printf("#ifndef __UM_CONSTANTS_H\n");
+  printf("#define __UM_CONSTANTS_H\n");
+  printf("\n");
+
+  SHOW_INT(UM_KERN_PAGE_SIZE);
+
+  SHOW_STR(UM_KERN_EMERG);
+  SHOW_STR(UM_KERN_ALERT);
+  SHOW_STR(UM_KERN_CRIT);
+  SHOW_STR(UM_KERN_ERR);
+  SHOW_STR(UM_KERN_WARNING);
+  SHOW_STR(UM_KERN_NOTICE);
+  SHOW_STR(UM_KERN_INFO);
+  SHOW_STR(UM_KERN_DEBUG);
+
+  SHOW_INT(UM_NSEC_PER_SEC);
+  printf("\n");
+  printf("#endif\n");
+  return(0);
+}
diff --git a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
deleted file mode 100644 (file)
index cdcb123..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "linux/kernel.h"
-#include "linux/stringify.h"
-#include "linux/time.h"
-#include "asm/page.h"
-
-extern void print_head(void);
-extern void print_constant_str(char *name, char *value);
-extern void print_constant_int(char *name, int value);
-extern void print_tail(void);
-
-int main(int argc, char **argv)
-{
-  print_head();
-  print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
-
-  print_constant_str("UM_KERN_EMERG", KERN_EMERG);
-  print_constant_str("UM_KERN_ALERT", KERN_ALERT);
-  print_constant_str("UM_KERN_CRIT", KERN_CRIT);
-  print_constant_str("UM_KERN_ERR", KERN_ERR);
-  print_constant_str("UM_KERN_WARNING", KERN_WARNING);
-  print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
-  print_constant_str("UM_KERN_INFO", KERN_INFO);
-  print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
-
-  print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
-  print_tail();
-  return(0);
-}
diff --git a/arch/um/util/mk_constants_user.c b/arch/um/util/mk_constants_user.c
deleted file mode 100644 (file)
index 8f4d7e5..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <stdio.h>
-
-void print_head(void)
-{
-  printf("/*\n");
-  printf(" * Generated by mk_constants\n");
-  printf(" */\n");
-  printf("\n");
-  printf("#ifndef __UM_CONSTANTS_H\n");
-  printf("#define __UM_CONSTANTS_H\n");
-  printf("\n");
-}
-
-void print_constant_str(char *name, char *value)
-{
-  printf("#define %s \"%s\"\n", name, value);
-}
-
-void print_constant_int(char *name, int value)
-{
-  printf("#define %s %d\n", name, value);
-}
-
-void print_tail(void)
-{
-  printf("\n");
-  printf("#endif\n");
-}
diff --git a/arch/um/util/mk_task.c b/arch/um/util/mk_task.c
new file mode 100644 (file)
index 0000000..36c9606
--- /dev/null
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <kernel-offsets.h>
+
+void print_ptr(char *name, char *type, int offset)
+{
+  printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
+        offset);
+}
+
+void print(char *name, char *type, int offset)
+{
+  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
+        offset);
+}
+
+int main(int argc, char **argv)
+{
+  printf("/*\n");
+  printf(" * Generated by mk_task\n");
+  printf(" */\n");
+  printf("\n");
+  printf("#ifndef __TASK_H\n");
+  printf("#define __TASK_H\n");
+  printf("\n");
+  print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS);
+  print("TASK_PID", "int", TASK_PID);
+  printf("\n");
+  printf("#endif\n");
+  return(0);
+}
diff --git a/arch/um/util/mk_task_kern.c b/arch/um/util/mk_task_kern.c
deleted file mode 100644 (file)
index c218103..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "linux/sched.h"
-#include "linux/stddef.h"
-
-extern void print(char *name, char *type, int offset);
-extern void print_ptr(char *name, char *type, int offset);
-extern void print_head(void);
-extern void print_tail(void);
-
-int main(int argc, char **argv)
-{
-  print_head();
-  print_ptr("TASK_REGS", "union uml_pt_regs", 
-           offsetof(struct task_struct, thread.regs));
-  print("TASK_PID", "int", offsetof(struct task_struct, pid));
-  print_tail();
-  return(0);
-}
diff --git a/arch/um/util/mk_task_user.c b/arch/um/util/mk_task_user.c
deleted file mode 100644 (file)
index 9db849f..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdio.h>
-
-void print(char *name, char *type, int offset)
-{
-  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
-        offset);
-}
-
-void print_ptr(char *name, char *type, int offset)
-{
-  printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
-        offset);
-}
-
-void print_head(void)
-{
-  printf("/*\n");
-  printf(" * Generated by mk_task\n");
-  printf(" */\n");
-  printf("\n");
-  printf("#ifndef __TASK_H\n");
-  printf("#define __TASK_H\n");
-  printf("\n");
-}
-
-void print_tail(void)
-{
-  printf("\n");
-  printf("#endif\n");
-}
index 80c38c5d71fe44f591753d7bcb174cfa37168a82..289f448ac89cc426dcb5fdb4d23aaf8bef7988bb 100644 (file)
@@ -303,6 +303,21 @@ config HPET_TIMER
          as it is off-chip.  You can find the HPET spec at
          <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>.
 
+config X86_PM_TIMER
+       bool "PM timer"
+       depends on ACPI
+       default y
+       help
+         Support the ACPI PM timer for time keeping. This is slow,
+         but is useful on some chipsets without HPET on systems with more
+         than one CPU. On a single processor or single socket multi core
+         system it is normally not required.
+         When the PM timer is active 64bit vsyscalls are disabled
+         and should not be enabled (/proc/sys/kernel/vsyscall64 should
+         not be changed).
+         The kernel selects the PM timer only as a last resort, so it is
+         useful to enable just in case.
+
 config HPET_EMULATE_RTC
        bool "Provide RTC interrupt"
        depends on HPET_TIMER && RTC=y
@@ -379,6 +394,11 @@ config GENERIC_IRQ_PROBE
        bool
        default y
 
+# we have no ISA slots, but we do have ISA-style DMA.
+config ISA_DMA_API
+       bool
+       default y
+
 menu "Power management options"
 
 source kernel/power/Kconfig
@@ -402,7 +422,7 @@ config PCI_DIRECT
 
 config PCI_MMCONFIG
        bool "Support mmconfig PCI config space access"
-       depends on PCI
+       depends on PCI && ACPI
        select ACPI_BOOT
 
 config UNORDERED_IO
index bb15d406ee9534b19c217964a0226eebb61221c0..011b7a4993d40eb27ad99d811abf5e26a482a6ea 100644 (file)
@@ -63,7 +63,7 @@ msg_loop:
        jz      die
        movb    $0xe, %ah
        movw    $7, %bx
-       int     $0x10
+       int     $0x10
        jmp     msg_loop
 
 die:
@@ -71,7 +71,7 @@ die:
        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
index 9ce51dee30b301972d6d5a8b160b8bef74d17049..569595b74c7ccfc5412053959f5cd68891122848 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-bk7
-# Sat Mar 12 23:43:44 2005
+# Linux kernel version: 2.6.12-rc4
+# Fri May 13 06:39:11 2005
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -11,8 +11,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_X86_CMPXCHG=y
 CONFIG_EARLY_PRINTK=y
-CONFIG_HPET_TIMER=y
-CONFIG_HPET_EMULATE_RTC=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_GENERIC_IOMAP=y
 
@@ -22,6 +20,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -33,7 +32,6 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=18
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
@@ -43,10 +41,11 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
@@ -93,6 +92,9 @@ CONFIG_DISCONTIGMEM=y
 CONFIG_NUMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_NR_CPUS=8
+CONFIG_HPET_TIMER=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
 CONFIG_GART_IOMMU=y
 CONFIG_SWIOTLB=y
 CONFIG_X86_MCE=y
@@ -100,6 +102,7 @@ CONFIG_X86_MCE_INTEL=y
 CONFIG_SECCOMP=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ISA_DMA_API=y
 
 #
 # Power management options
@@ -129,7 +132,7 @@ CONFIG_ACPI_NUMA=y
 # CONFIG_ACPI_IBM is not set
 CONFIG_ACPI_TOSHIBA=y
 CONFIG_ACPI_BLACKLIST_YEAR=2001
-CONFIG_ACPI_DEBUG=y
+# CONFIG_ACPI_DEBUG is not set
 CONFIG_ACPI_BUS=y
 CONFIG_ACPI_EC=y
 CONFIG_ACPI_POWER=y
@@ -141,6 +144,7 @@ CONFIG_ACPI_SYSTEM=y
 # CPU Frequency scaling
 #
 CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
@@ -150,7 +154,6 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_TABLE=y
 
 #
 # CPUFreq processor drivers
@@ -164,6 +167,7 @@ CONFIG_X86_ACPI_CPUFREQ=y
 # shared options
 #
 CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y
+# CONFIG_X86_SPEEDSTEP_LIB is not set
 
 #
 # Bus options (PCI etc.)
@@ -172,19 +176,17 @@ CONFIG_PCI=y
 CONFIG_PCI_DIRECT=y
 CONFIG_PCI_MMCONFIG=y
 CONFIG_UNORDERED_IO=y
+# CONFIG_PCIEPORTBUS is not set
 CONFIG_PCI_MSI=y
 # CONFIG_PCI_LEGACY_PROC is not set
 # CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -254,7 +256,7 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
@@ -308,7 +310,8 @@ CONFIG_BLK_DEV_AMD74XX=y
 CONFIG_BLK_DEV_PIIX=y
 # 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_PDC202XX_NEW=y
+# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIIMAGE is not set
 # CONFIG_BLK_DEV_SIS5513 is not set
@@ -353,7 +356,7 @@ CONFIG_BLK_DEV_SD=y
 #
 # SCSI low-level drivers
 #
-CONFIG_BLK_DEV_3W_XXXX_RAID=y
+# 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
@@ -384,7 +387,6 @@ CONFIG_SCSI_SATA_VIA=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -392,7 +394,6 @@ CONFIG_SCSI_SATA_VIA=y
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -401,6 +402,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -437,7 +439,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -502,7 +503,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
+CONFIG_TUN=y
 
 #
 # ARCnet devices
@@ -525,8 +526,7 @@ CONFIG_MII=y
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
-CONFIG_AMD8111_ETH=y
-# CONFIG_AMD8111E_NAPI is not set
+# CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 CONFIG_FORCEDETH=y
@@ -536,7 +536,7 @@ CONFIG_FORCEDETH=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
-CONFIG_8139CP=m
+CONFIG_8139CP=y
 CONFIG_8139TOO=y
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
@@ -671,6 +671,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 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
@@ -696,6 +697,7 @@ CONFIG_RTC=y
 #
 CONFIG_AGP=y
 CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
 # CONFIG_DRM is not set
 # CONFIG_MWAVE is not set
 CONFIG_RAW_DRIVER=y
@@ -703,7 +705,7 @@ CONFIG_HPET=y
 # CONFIG_HPET_RTC_IRQ is not set
 CONFIG_HPET_MMAP=y
 CONFIG_MAX_RAW_DEVS=256
-CONFIG_HANGCHECK_TIMER=y
+# CONFIG_HANGCHECK_TIMER is not set
 
 #
 # TPM devices
@@ -786,6 +788,8 @@ CONFIG_SOUND_ICH=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -797,8 +801,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -826,7 +828,6 @@ CONFIG_USB_PRINTER=y
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
@@ -965,7 +966,7 @@ CONFIG_AUTOFS_FS=y
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
+CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
 # CONFIG_UDF_FS is not set
 
@@ -1092,9 +1093,10 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_PRINTK_TIME is not set
+CONFIG_LOG_BUF_SHIFT=18
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
index 0a3318e08ab6f123e5a015f4c9cd2198c932b821..5ca4a4598fdad807b5aa0e8143c2aa55525fced2 100644 (file)
@@ -28,6 +28,7 @@ obj-$(CONFIG_GART_IOMMU)      += pci-gart.o aperture.o
 obj-$(CONFIG_DUMMY_IOMMU)      += pci-nommu.o pci-dma.o
 obj-$(CONFIG_SWIOTLB)          += swiotlb.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
+obj-$(CONFIG_X86_PM_TIMER)     += pmtimer.o
 
 obj-$(CONFIG_MODULES)          += module.o
 
index a491f72cc96663a79bf26a5e8f642cbab55dac26..504e634749938dcba3775cffb1bad10ecee7d848 100644 (file)
@@ -33,12 +33,10 @@ int fallback_aper_force __initdata = 0;
 
 int fix_aperture __initdata = 1;
 
-#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
+/* This code runs before the PCI subsystem is initialized, so just
+   access the northbridge directly. */
 
-static struct resource aper_res = {
-       .name = "Aperture",
-       .flags = IORESOURCE_MEM,
-};
+#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
 
 static u32 __init allocate_aperture(void) 
 {
@@ -55,24 +53,11 @@ static u32 __init allocate_aperture(void)
        aper_size = (32 * 1024 * 1024) << fallback_aper_order; 
 
        /* 
-        * Aperture has to be naturally aligned. This means an 2GB
-        * aperture won't have much chances to find a place in the
-        * lower 4GB of memory.  Unfortunately we cannot move it up
-        * because that would make the IOMMU useless.
+        * Aperture has to be naturally aligned. This means an 2GB aperture won't
+        * have much chances to find a place in the lower 4GB of memory.
+        * Unfortunately we cannot move it up because that would make the
+        * IOMMU useless.
         */
-
-       /* First try to find some free unused space */
-       if (!allocate_resource(&iomem_resource, &aper_res,
-                              aper_size,
-                              0, 0xffffffff,
-                              aper_size,
-                              NULL, NULL)) {
-               printk(KERN_INFO "Putting aperture at %lx-%lx\n",
-                      aper_res.start, aper_res.end);
-               return aper_res.start;
-       }
-
-       /* No free space found. Go on to waste some memory... */
        p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
        if (!p || __pa(p)+aper_size > 0xffffffff) {
                printk("Cannot allocate aperture memory hole (%p,%uK)\n",
@@ -81,7 +66,7 @@ static u32 __init allocate_aperture(void)
                        free_bootmem_node(nd0, (unsigned long)p, aper_size); 
                return 0;
        }
-       printk("Mapping aperture over %d KB of precious RAM @ %lx\n",
+       printk("Mapping aperture over %d KB of RAM @ %lx\n",
               aper_size >> 10, __pa(p)); 
        return (u32)__pa(p); 
 }
@@ -102,16 +87,10 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size)
                printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
                return 0; 
        } 
-       /* Don't check the resource here because the aperture is usually
-          in an e820 reserved area, and we allocated these earlier. */
        return 1;
 } 
 
-/*
- * Find a PCI capability.
- * This code runs before the PCI subsystem is initialized, so just
- * access the northbridge directly.
- */
+/* Find a PCI capability */
 static __u32 __init find_cap(int num, int slot, int func, int cap) 
 { 
        u8 pos;
@@ -276,6 +255,8 @@ void __init iommu_hole_init(void)
                   fallback_aper_force) { 
                printk("Your BIOS doesn't leave a aperture memory hole\n");
                printk("Please enable the IOMMU option in the BIOS setup\n");
+               printk("This costs you %d MB of RAM\n",
+                      32 << fallback_aper_order);
 
                aper_order = fallback_aper_order;
                aper_alloc = allocate_aperture();
index 7e13545748e0ef3378c87a23c401ba25f34d6c65..f8e6cc4fecd4887acc244fee292f401a96aac59b 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/mpspec.h>
 #include <asm/pgalloc.h>
 #include <asm/mach_apic.h>
+#include <asm/nmi.h>
 
 int apic_verbosity;
 
@@ -925,7 +926,7 @@ __init int oem_force_hpet_timer(void)
        unsigned id;
        DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
 
-       bitmap_empty(clustermap, NUM_APIC_CLUSTERS);
+       bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
 
        for (i = 0; i < NR_CPUS; i++) {
                id = bios_cpu_apicid[i];
@@ -1056,7 +1057,7 @@ int __init APIC_init_uniprocessor (void)
                nr_ioapics = 0;
 #endif
        setup_boot_APIC_clock();
-
+       check_nmi_watchdog();
        return 0;
 }
 
index 1086b5fcac21c51ad8acb01a02c6c8a6a971a8c7..28817490fdc69510a527c9974be8bb550aa2a5b6 100644 (file)
@@ -220,13 +220,18 @@ sysret_careful:
        jmp sysret_check
 
        /* Handle a signal */ 
-       /* edx: work flags (arg3) */
 sysret_signal:
        sti
+       testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
+       jz    1f
+
+       /* Really a signal */
+       /* edx: work flags (arg3) */
        leaq do_notify_resume(%rip),%rax
        leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
        xorl %esi,%esi # oldset -> arg2
        call ptregscall_common
+1:     movl $_TIF_NEED_RESCHED,%edi
        jmp sysret_check
        
        /* Do syscall tracing */
@@ -484,6 +489,8 @@ retint_careful:
        jmp retint_check
        
 retint_signal:
+       testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
+       jz    retint_swapgs
        sti
        SAVE_REST
        movq $-1,ORIG_RAX(%rsp)                         
@@ -492,8 +499,8 @@ retint_signal:
        call do_notify_resume
        RESTORE_REST
        cli
+       movl $_TIF_NEED_RESCHED,%edi
        GET_THREAD_INFO(%rcx)
-       movl $_TIF_WORK_MASK,%edi
        jmp retint_check
 
 #ifdef CONFIG_PREEMPT
index 60be58617eb977e1620beda8e363ba9cfd9fc17c..afd87e64d0a870c43eaab0a6a99882c9d1c12281 100644 (file)
 #include <asm/desc.h>
 #include <asm/proto.h>
 #include <asm/mach_apic.h>
+#include <asm/acpi.h>
 
 #define __apicdebuginit  __init
 
 int sis_apic_bug; /* not actually supported, dummy for compile */
 
+static int no_timer_check;
+
 static DEFINE_SPINLOCK(ioapic_lock);
 
 /*
@@ -1601,7 +1604,7 @@ static inline void check_timer(void)
                 * Ok, does IRQ0 through the IOAPIC work?
                 */
                unmask_IO_APIC_irq(0);
-               if (timer_irq_works()) {
+               if (!no_timer_check && timer_irq_works()) {
                        nmi_watchdog_default();
                        if (nmi_watchdog == NMI_IO_APIC) {
                                disable_8259A_irq(0);
@@ -1671,6 +1674,13 @@ static inline void check_timer(void)
        panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n");
 }
 
+static int __init notimercheck(char *s)
+{
+       no_timer_check = 1;
+       return 1;
+}
+__setup("no_timer_check", notimercheck);
+
 /*
  *
  * IRQ's that are handled by the PIC in the MPS IOAPIC case.
@@ -1804,76 +1814,6 @@ device_initcall(ioapic_init_sysfs);
 
 #define IO_APIC_MAX_ID         0xFE
 
-int __init io_apic_get_unique_id (int ioapic, int apic_id)
-{
-       union IO_APIC_reg_00 reg_00;
-       static physid_mask_t apic_id_map;
-       unsigned long flags;
-       int i = 0;
-
-       /*
-        * The P4 platform supports up to 256 APIC IDs on two separate APIC 
-        * buses (one for LAPICs, one for IOAPICs), where predecessors only 
-        * supports up to 16 on one shared APIC bus.
-        * 
-        * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
-        *      advantage of new APIC bus architecture.
-        */
-
-       if (physids_empty(apic_id_map))
-               apic_id_map = phys_cpu_present_map;
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       reg_00.raw = io_apic_read(ioapic, 0);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-
-       if (apic_id >= IO_APIC_MAX_ID) {
-               apic_printk(APIC_QUIET, KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
-                       "%d\n", ioapic, apic_id, reg_00.bits.ID);
-               apic_id = reg_00.bits.ID;
-       }
-
-       /*
-        * Every APIC in a system must have a unique ID or we get lots of nice 
-        * 'stuck on smp_invalidate_needed IPI wait' messages.
-        */
-       if (physid_isset(apic_id, apic_id_map)) {
-
-               for (i = 0; i < IO_APIC_MAX_ID; i++) {
-                       if (!physid_isset(i, apic_id_map))
-                               break;
-               }
-
-               if (i == IO_APIC_MAX_ID)
-                       panic("Max apic_id exceeded!\n");
-
-               apic_printk(APIC_VERBOSE, KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
-                       "trying %d\n", ioapic, apic_id, i);
-
-               apic_id = i;
-       } 
-
-       physid_set(apic_id, apic_id_map);
-
-       if (reg_00.bits.ID != apic_id) {
-               reg_00.bits.ID = apic_id;
-
-               spin_lock_irqsave(&ioapic_lock, flags);
-               io_apic_write(ioapic, 0, reg_00.raw);
-               reg_00.raw = io_apic_read(ioapic, 0);
-               spin_unlock_irqrestore(&ioapic_lock, flags);
-
-               /* Sanity check */
-               if (reg_00.bits.ID != apic_id)
-                       panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic);
-       }
-
-       apic_printk(APIC_VERBOSE,KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
-
-       return apic_id;
-}
-
-
 int __init io_apic_get_version (int ioapic)
 {
        union IO_APIC_reg_01    reg_01;
index 4f2a852299b63dc97cebbda101c9d4092e7da430..f77f8a0ff1873bdc1717d473f74eb4116874eae7 100644 (file)
@@ -355,6 +355,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
                *tos &= ~(TF_MASK | IF_MASK);
                *tos |= kprobe_old_rflags;
                break;
+       case 0xc3:              /* ret/lret */
+       case 0xcb:
+       case 0xc2:
+       case 0xca:
+               regs->eflags &= ~TF_MASK;
+               /* rip is already adjusted, no more changes required*/
+               return;
        case 0xe8:              /* call relative - Fix return addr */
                *tos = orig_rip + (*tos - copy_rip);
                break;
index c2ffea8845edeb5bc74e183a7ca5eef9ea5e3206..bac195c74bccfce81033da6d473fefea1a2cabba 100644 (file)
 
 #define DEBUGP(fmt...) 
 
+#ifndef CONFIG_UML
 void module_free(struct module *mod, void *module_region)
 {
        vfree(module_region);
+       /* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
 }
 
 void *module_alloc(unsigned long size)
@@ -51,6 +54,7 @@ void *module_alloc(unsigned long size)
 
        return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
 }
+#endif
 
 /* We don't need anything special. */
 int module_frob_arch_sections(Elf_Ehdr *hdr,
index 7ec031c6ca10fe566e444fcafcb3b1b4995887b9..61a63be6b294adf3f0716ad8bcd27c13b7028c36 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/pgalloc.h>
 #include <asm/io_apic.h>
 #include <asm/proto.h>
+#include <asm/acpi.h>
 
 /* Have we found an MP table */
 int smp_found_config;
@@ -107,6 +108,7 @@ static int __init mpf_checksum(unsigned char *mp, int len)
 static void __init MP_processor_info (struct mpc_config_processor *m)
 {
        int ver;
+       static int found_bsp=0;
 
        if (!(m->mpc_cpuflag & CPU_ENABLED))
                return;
@@ -126,11 +128,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
                        " Processor ignored.\n", NR_CPUS);
                return;
        }
-       if (num_processors >= maxcpus) {
-               printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
-                       " Processor ignored.\n", maxcpus);
-               return;
-       }
 
        num_processors++;
 
@@ -150,7 +147,19 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
                ver = 0x10;
        }
        apic_version[m->mpc_apicid] = ver;
-       bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
+       if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
+               /*
+                * bios_cpu_apicid is required to have processors listed
+                * in same order as logical cpu numbers. Hence the first
+                * entry is BSP, and so on.
+                */
+               bios_cpu_apicid[0] = m->mpc_apicid;
+               x86_cpu_to_apicid[0] = m->mpc_apicid;
+               found_bsp = 1;
+       } else {
+               bios_cpu_apicid[num_processors - found_bsp] = m->mpc_apicid;
+               x86_cpu_to_apicid[num_processors - found_bsp] = m->mpc_apicid;
+       }
 }
 
 static void __init MP_bus_info (struct mpc_config_bus *m)
@@ -759,7 +768,7 @@ void __init mp_register_ioapic (
        mp_ioapics[idx].mpc_apicaddr = address;
 
        set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-       mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
+       mp_ioapics[idx].mpc_apicid = id;
        mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
        
        /* 
index 61de0b34a01e850fedb824115b2e0560ed98ff59..31c0f2e6ac916c8f1cd93f025cf3182b92f1fa3e 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/msr.h>
 #include <asm/proto.h>
 #include <asm/kdebug.h>
+#include <asm/local.h>
 
 /*
  * lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
@@ -59,7 +60,8 @@ int panic_on_timeout;
 
 unsigned int nmi_watchdog = NMI_DEFAULT;
 static unsigned int nmi_hz = HZ;
-unsigned int nmi_perfctr_msr;  /* the MSR to reset in NMI handler */
+static unsigned int nmi_perfctr_msr;   /* the MSR to reset in NMI handler */
+static unsigned int nmi_p4_cccr_val;
 
 /* Note that these events don't tick when the CPU idles. This means
    the frequency varies with CPU load. */
@@ -71,61 +73,87 @@ unsigned int nmi_perfctr_msr;       /* the MSR to reset in NMI handler */
 #define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING   0x76
 #define K7_NMI_EVENT           K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
 
-#define P6_EVNTSEL0_ENABLE     (1 << 22)
-#define P6_EVNTSEL_INT         (1 << 20)
-#define P6_EVNTSEL_OS          (1 << 17)
-#define P6_EVNTSEL_USR         (1 << 16)
-#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79
-#define P6_NMI_EVENT           P6_EVENT_CPU_CLOCKS_NOT_HALTED
+#define MSR_P4_MISC_ENABLE     0x1A0
+#define MSR_P4_MISC_ENABLE_PERF_AVAIL  (1<<7)
+#define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL        (1<<12)
+#define MSR_P4_PERFCTR0                0x300
+#define MSR_P4_CCCR0           0x360
+#define P4_ESCR_EVENT_SELECT(N)        ((N)<<25)
+#define P4_ESCR_OS             (1<<3)
+#define P4_ESCR_USR            (1<<2)
+#define P4_CCCR_OVF_PMI0       (1<<26)
+#define P4_CCCR_OVF_PMI1       (1<<27)
+#define P4_CCCR_THRESHOLD(N)   ((N)<<20)
+#define P4_CCCR_COMPLEMENT     (1<<19)
+#define P4_CCCR_COMPARE                (1<<18)
+#define P4_CCCR_REQUIRED       (3<<16)
+#define P4_CCCR_ESCR_SELECT(N) ((N)<<13)
+#define P4_CCCR_ENABLE         (1<<12)
+/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
+   CRU_ESCR0 (with any non-null event selector) through a complemented
+   max threshold. [IA32-Vol3, Section 14.9.9] */
+#define MSR_P4_IQ_COUNTER0     0x30C
+#define P4_NMI_CRU_ESCR0       (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR)
+#define P4_NMI_IQ_CCCR0        \
+       (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT|     \
+        P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
+
+static __init inline int nmi_known_cpu(void)
+{
+       switch (boot_cpu_data.x86_vendor) {
+       case X86_VENDOR_AMD:
+               return boot_cpu_data.x86 == 15;
+       case X86_VENDOR_INTEL:
+               return boot_cpu_data.x86 == 15;
+       }
+       return 0;
+}
 
 /* Run after command line and cpu_init init, but before all other checks */
 void __init nmi_watchdog_default(void)
 {
        if (nmi_watchdog != NMI_DEFAULT)
                return;
-
-       /* For some reason the IO APIC watchdog doesn't work on the AMD
-          8111 chipset. For now switch to local APIC mode using
-          perfctr0 there.  On Intel CPUs we don't have code to handle
-          the perfctr and the IO-APIC seems to work, so use that.  */
-
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
-               nmi_watchdog = NMI_LOCAL_APIC; 
-               printk(KERN_INFO 
-              "Using local APIC NMI watchdog using perfctr0\n");
-       } else {
-               printk(KERN_INFO "Using IO APIC NMI watchdog\n");
+       if (nmi_known_cpu())
+               nmi_watchdog = NMI_LOCAL_APIC;
+       else
                nmi_watchdog = NMI_IO_APIC;
-       }
 }
 
-/* Why is there no CPUID flag for this? */
-static __init int cpu_has_lapic(void)
+#ifdef CONFIG_SMP
+/* The performance counters used by NMI_LOCAL_APIC don't trigger when
+ * the CPU is idle. To make sure the NMI watchdog really ticks on all
+ * CPUs during the test make them busy.
+ */
+static __init void nmi_cpu_busy(void *data)
 {
-       switch (boot_cpu_data.x86_vendor) { 
-       case X86_VENDOR_INTEL:
-       case X86_VENDOR_AMD: 
-               return boot_cpu_data.x86 >= 6; 
-       /* .... add more cpus here or find a different way to figure this out. */       
-       default:
-               return 0;
-       }       
+       volatile int *endflag = data;
+       local_irq_enable();
+       /* Intentionally don't use cpu_relax here. This is
+          to make sure that the performance counter really ticks,
+          even if there is a simulator or similar that catches the
+          pause instruction. On a real HT machine this is fine because
+          all other CPUs are busy with "useless" delay loops and don't
+          care if they get somewhat less cycles. */
+       while (*endflag == 0)
+               barrier();
 }
+#endif
 
-static int __init check_nmi_watchdog (void)
+int __init check_nmi_watchdog (void)
 {
-       int counts[NR_CPUS];
+       volatile int endflag = 0;
+       int *counts;
        int cpu;
 
-       if (nmi_watchdog == NMI_NONE)
-               return 0;
+       counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
+       if (!counts)
+               return -1;
 
-       if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic())  {
-               nmi_watchdog = NMI_NONE;
-               return -1; 
-       }       
+       printk(KERN_INFO "testing NMI watchdog ... ");
 
-       printk(KERN_INFO "Testing NMI watchdog ... ");
+       if (nmi_watchdog == NMI_LOCAL_APIC)
+               smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
 
        for (cpu = 0; cpu < NR_CPUS; cpu++)
                counts[cpu] = cpu_pda[cpu].__nmi_count; 
@@ -133,15 +161,22 @@ static int __init check_nmi_watchdog (void)
        mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
        for (cpu = 0; cpu < NR_CPUS; cpu++) {
+               if (!cpu_online(cpu))
+                       continue;
                if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) {
-                       printk("CPU#%d: NMI appears to be stuck (%d)!\n", 
+                       endflag = 1;
+                       printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
                               cpu,
+                              counts[cpu],
                               cpu_pda[cpu].__nmi_count);
                        nmi_active = 0;
                        lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
+                       nmi_perfctr_msr = 0;
+                       kfree(counts);
                        return -1;
                }
        }
+       endflag = 1;
        printk("OK.\n");
 
        /* now that we know it works we can reduce NMI frequency to
@@ -149,10 +184,9 @@ static int __init check_nmi_watchdog (void)
        if (nmi_watchdog == NMI_LOCAL_APIC)
                nmi_hz = 1;
 
+       kfree(counts);
        return 0;
 }
-/* Have this called later during boot so counters are updating */
-late_initcall(check_nmi_watchdog);
 
 int __init setup_nmi_watchdog(char *str)
 {
@@ -170,7 +204,7 @@ int __init setup_nmi_watchdog(char *str)
 
        if (nmi >= NMI_INVALID)
                return 0;
-               nmi_watchdog = nmi;
+       nmi_watchdog = nmi;
        return 1;
 }
 
@@ -185,7 +219,10 @@ static void disable_lapic_nmi_watchdog(void)
                wrmsr(MSR_K7_EVNTSEL0, 0, 0);
                break;
        case X86_VENDOR_INTEL:
-               wrmsr(MSR_IA32_EVNTSEL0, 0, 0);
+               if (boot_cpu_data.x86 == 15) {
+                       wrmsr(MSR_P4_IQ_CCCR0, 0, 0);
+                       wrmsr(MSR_P4_CRU_ESCR0, 0, 0);
+               }
                break;
        }
        nmi_active = -1;
@@ -253,7 +290,7 @@ void enable_timer_nmi_watchdog(void)
 
 static int nmi_pm_active; /* nmi_active before suspend */
 
-static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
+static int lapic_nmi_suspend(struct sys_device *dev, u32 state)
 {
        nmi_pm_active = nmi_active;
        disable_lapic_nmi_watchdog();
@@ -300,22 +337,27 @@ late_initcall(init_lapic_nmi_sysfs);
  * Original code written by Keith Owens.
  */
 
+static void clear_msr_range(unsigned int base, unsigned int n)
+{
+       unsigned int i;
+
+       for(i = 0; i < n; ++i)
+               wrmsr(base+i, 0, 0);
+}
+
 static void setup_k7_watchdog(void)
 {
        int i;
        unsigned int evntsel;
 
-       /* No check, so can start with slow frequency */
-       nmi_hz = 1; 
-
-       /* XXX should check these in EFER */
-
        nmi_perfctr_msr = MSR_K7_PERFCTR0;
 
        for(i = 0; i < 4; ++i) {
                /* Simulator may not support it */
-               if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL))
+               if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) {
+                       nmi_perfctr_msr = 0;
                        return;
+               }
                wrmsrl(MSR_K7_PERFCTR0+i, 0UL);
        }
 
@@ -325,12 +367,54 @@ static void setup_k7_watchdog(void)
                | K7_NMI_EVENT;
 
        wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
-       wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz*1000) / nmi_hz);
+       wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
        apic_write(APIC_LVTPC, APIC_DM_NMI);
        evntsel |= K7_EVNTSEL_ENABLE;
        wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
 }
 
+
+static int setup_p4_watchdog(void)
+{
+       unsigned int misc_enable, dummy;
+
+       rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy);
+       if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL))
+               return 0;
+
+       nmi_perfctr_msr = MSR_P4_IQ_COUNTER0;
+       nmi_p4_cccr_val = P4_NMI_IQ_CCCR0;
+#ifdef CONFIG_SMP
+       if (smp_num_siblings == 2)
+               nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1;
+#endif
+
+       if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL))
+               clear_msr_range(0x3F1, 2);
+       /* MSR 0x3F0 seems to have a default value of 0xFC00, but current
+          docs doesn't fully define it, so leave it alone for now. */
+       if (boot_cpu_data.x86_model >= 0x3) {
+               /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */
+               clear_msr_range(0x3A0, 26);
+               clear_msr_range(0x3BC, 3);
+       } else {
+               clear_msr_range(0x3A0, 31);
+       }
+       clear_msr_range(0x3C0, 6);
+       clear_msr_range(0x3C8, 6);
+       clear_msr_range(0x3E0, 2);
+       clear_msr_range(MSR_P4_CCCR0, 18);
+       clear_msr_range(MSR_P4_PERFCTR0, 18);
+
+       wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
+       wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0);
+       Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000));
+       wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1);
+       apic_write(APIC_LVTPC, APIC_DM_NMI);
+       wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
+       return 1;
+}
+
 void setup_apic_nmi_watchdog(void)
 {
        switch (boot_cpu_data.x86_vendor) {
@@ -341,6 +425,13 @@ void setup_apic_nmi_watchdog(void)
                        return;
                setup_k7_watchdog();
                break;
+       case X86_VENDOR_INTEL:
+               if (boot_cpu_data.x86 != 15)
+                       return;
+               if (!setup_p4_watchdog())
+                       return;
+               break;
+
        default:
                return;
        }
@@ -355,56 +446,67 @@ void setup_apic_nmi_watchdog(void)
  *
  * as these watchdog NMI IRQs are generated on every CPU, we only
  * have to check the current processor.
- *
- * since NMIs don't listen to _any_ locks, we have to be extremely
- * careful not to rely on unsafe variables. The printk might lock
- * up though, so we have to break up any console locks first ...
- * [when there will be more tty-related locks, break them up
- *  here too!]
  */
 
-static unsigned int
-       last_irq_sums [NR_CPUS],
-       alert_counter [NR_CPUS];
+static DEFINE_PER_CPU(unsigned, last_irq_sum);
+static DEFINE_PER_CPU(local_t, alert_counter);
+static DEFINE_PER_CPU(int, nmi_touch);
 
 void touch_nmi_watchdog (void)
 {
        int i;
 
        /*
-        * Just reset the alert counters, (other CPUs might be
-        * spinning on locks we hold):
+        * Tell other CPUs to reset their alert counters. We cannot
+        * do it ourselves because the alert count increase is not
+        * atomic.
         */
        for (i = 0; i < NR_CPUS; i++)
-               alert_counter[i] = 0;
+               per_cpu(nmi_touch, i) = 1;
 }
 
 void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason)
 {
-       int sum, cpu;
+       int sum;
+       int touched = 0;
 
-       cpu = safe_smp_processor_id();
        sum = read_pda(apic_timer_irqs);
-       if (last_irq_sums[cpu] == sum) {
+       if (__get_cpu_var(nmi_touch)) {
+               __get_cpu_var(nmi_touch) = 0;
+               touched = 1;
+       }
+       if (!touched && __get_cpu_var(last_irq_sum) == sum) {
                /*
                 * Ayiee, looks like this CPU is stuck ...
                 * wait a few IRQs (5 seconds) before doing the oops ...
                 */
-               alert_counter[cpu]++;
-               if (alert_counter[cpu] == 5*nmi_hz) {
+               local_inc(&__get_cpu_var(alert_counter));
+               if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) {
                        if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
                                                        == NOTIFY_STOP) {
-                               alert_counter[cpu] = 0; 
+                               local_set(&__get_cpu_var(alert_counter), 0);
                                return;
                        } 
                        die_nmi("NMI Watchdog detected LOCKUP on CPU%d", regs);
                }
        } else {
-               last_irq_sums[cpu] = sum;
-               alert_counter[cpu] = 0;
+               __get_cpu_var(last_irq_sum) = sum;
+               local_set(&__get_cpu_var(alert_counter), 0);
        }
-       if (nmi_perfctr_msr)
+       if (nmi_perfctr_msr) {
+               if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) {
+                       /*
+                        * P4 quirks:
+                        * - An overflown perfctr will assert its interrupt
+                        *   until the OVF flag in its CCCR is cleared.
+                        * - LVTPC is masked on interrupt and must be
+                        *   unmasked by the LVTPC handler.
+                        */
+                       wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
+                       apic_write(APIC_LVTPC, APIC_DM_NMI);
+               }
                wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
+       }
 }
 
 static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c
new file mode 100644 (file)
index 0000000..feb5f10
--- /dev/null
@@ -0,0 +1,101 @@
+/* Ported over from i386 by AK, original copyright was:
+ *
+ * (C) Dominik Brodowski <linux@brodo.de> 2003
+ *
+ * Driver to use the Power Management Timer (PMTMR) available in some
+ * southbridges as primary timing source for the Linux kernel.
+ *
+ * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c,
+ * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4.
+ *
+ * This file is licensed under the GPL v2.
+ *
+ * Dropped all the hardware bug workarounds for now. Hopefully they
+ * are not needed on 64bit chipsets.
+ */
+
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/cpumask.h>
+#include <asm/io.h>
+#include <asm/proto.h>
+#include <asm/msr.h>
+#include <asm/vsyscall.h>
+
+/* The I/O port the PMTMR resides at.
+ * The location is detected during setup_arch(),
+ * in arch/i386/kernel/acpi/boot.c */
+u32 pmtmr_ioport;
+
+/* value of the Power timer at last timer interrupt */
+static u32 offset_delay;
+static u32 last_pmtmr_tick;
+
+#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
+
+static inline u32 cyc2us(u32 cycles)
+{
+       /* The Power Management Timer ticks at 3.579545 ticks per microsecond.
+        * 1 / PM_TIMER_FREQUENCY == 0.27936511 =~ 286/1024 [error: 0.024%]
+        *
+        * Even with HZ = 100, delta is at maximum 35796 ticks, so it can
+        * easily be multiplied with 286 (=0x11E) without having to fear
+        * u32 overflows.
+        */
+       cycles *= 286;
+       return (cycles >> 10);
+}
+
+int pmtimer_mark_offset(void)
+{
+       static int first_run = 1;
+       unsigned long tsc;
+       u32 lost;
+
+       u32 tick = inl(pmtmr_ioport);
+       u32 delta;
+
+       delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK);
+
+       last_pmtmr_tick = tick;
+       monotonic_base += delta * NSEC_PER_USEC;
+
+       delta += offset_delay;
+
+       lost = delta / (USEC_PER_SEC / HZ);
+       offset_delay = delta % (USEC_PER_SEC / HZ);
+
+       rdtscll(tsc);
+       vxtime.last_tsc = tsc - offset_delay * cpu_khz;
+
+       /* don't calculate delay for first run,
+          or if we've got less then a tick */
+       if (first_run || (lost < 1)) {
+               first_run = 0;
+               offset_delay = 0;
+       }
+
+       return lost - 1;
+}
+
+unsigned int do_gettimeoffset_pm(void)
+{
+       u32 now, offset, delta = 0;
+
+       offset = last_pmtmr_tick;
+       now = inl(pmtmr_ioport);
+       delta = (now - offset) & ACPI_PM_MASK;
+
+       return offset_delay + cyc2us(delta);
+}
+
+
+static int __init nopmtimer_setup(char *s)
+{
+       pmtmr_ioport = 0;
+       return 0;
+}
+
+__setup("nopmtimer", nopmtimer_setup);
index c64b9c97c7459d035c3e4852d7d2e18508010ce7..525f6a128a279c0f559392af0b962de4101e46e8 100644 (file)
@@ -257,13 +257,13 @@ static int putreg(struct task_struct *child,
                        value &= 0xffff;
                        return 0;
                case offsetof(struct user_regs_struct,fs_base):
-                       if (!((value >> 48) == 0 || (value >> 48) == 0xffff))
-                               return -EIO; 
+                       if (value >= TASK_SIZE)
+                               return -EIO;
                        child->thread.fs = value;
                        return 0;
                case offsetof(struct user_regs_struct,gs_base):
-                       if (!((value >> 48) == 0 || (value >> 48) == 0xffff))
-                               return -EIO; 
+                       if (value >= TASK_SIZE)
+                               return -EIO;
                        child->thread.gs = value;
                        return 0;
                case offsetof(struct user_regs_struct, eflags):
@@ -277,6 +277,11 @@ static int putreg(struct task_struct *child,
                                return -EIO;
                        value &= 0xffff;
                        break;
+               case offsetof(struct user_regs_struct, rip):
+                       /* Check if the new RIP address is canonical */
+                       if (value >= TASK_SIZE)
+                               return -EIO;
+                       break;
        }
        put_stack_long(child, regno - sizeof(struct pt_regs), value);
        return 0;
@@ -375,7 +380,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
                        break;
 
                switch (addr) { 
-               case 0 ... sizeof(struct user_regs_struct):
+               case 0 ... sizeof(struct user_regs_struct) - sizeof(long):
                        tmp = getreg(child, addr);
                        break;
                case offsetof(struct user, u_debugreg[0]):
@@ -420,7 +425,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
                        break;
 
                switch (addr) { 
-               case 0 ... sizeof(struct user_regs_struct)
+               case 0 ... sizeof(struct user_regs_struct) - sizeof(long):
                        ret = putreg(child, addr, data);
                        break;
                /* Disallows to set a breakpoint into the vsyscall */
@@ -635,20 +640,29 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
        /* do the secure computing check first */
        secure_computing(regs->orig_rax);
 
-       if (unlikely(current->audit_context))
-               audit_syscall_entry(current, regs->orig_rax,
-                                   regs->rdi, regs->rsi,
-                                   regs->rdx, regs->r10);
-
        if (test_thread_flag(TIF_SYSCALL_TRACE)
            && (current->ptrace & PT_PTRACED))
                syscall_trace(regs);
+
+       if (unlikely(current->audit_context)) {
+               if (test_thread_flag(TIF_IA32)) {
+                       audit_syscall_entry(current, AUDIT_ARCH_I386,
+                                           regs->orig_rax,
+                                           regs->rbx, regs->rcx,
+                                           regs->rdx, regs->rsi);
+               } else {
+                       audit_syscall_entry(current, AUDIT_ARCH_X86_64,
+                                           regs->orig_rax,
+                                           regs->rdi, regs->rsi,
+                                           regs->rdx, regs->r10);
+               }
+       }
 }
 
 asmlinkage void syscall_trace_leave(struct pt_regs *regs)
 {
        if (unlikely(current->audit_context))
-               audit_syscall_exit(current, regs->rax);
+               audit_syscall_exit(current, AUDITSC_RESULT(regs->rax), regs->rax);
 
        if ((test_thread_flag(TIF_SYSCALL_TRACE)
             || test_thread_flag(TIF_SINGLESTEP))
index 2129cf9ba6b2fc066194474c058f821eefe22f4c..99f038ede23c323d98eca770b17344f4bc97838d 100644 (file)
@@ -719,7 +719,6 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
        }
 }
 
-#ifdef CONFIG_SMP
 /*
  * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
  * Assumes number of cores is a power of two.
@@ -727,17 +726,26 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
 static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
-       int cpu = c->x86_apicid;
+       int cpu = smp_processor_id();
        int node = 0;
+       unsigned bits;
        if (c->x86_num_cores == 1)
                return;
-       cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
+
+       bits = 0;
+       while ((1 << bits) < c->x86_num_cores)
+               bits++;
+
+       /* Low order bits define the core id (index of core in socket) */
+       cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1);
+       /* Convert the APIC ID into the socket ID */
+       phys_proc_id[cpu] >>= bits;
 
 #ifdef CONFIG_NUMA
        /* When an ACPI SRAT table is available use the mappings from SRAT
           instead. */
        if (acpi_numa <= 0) {
-               node = cpu_core_id[cpu];
+               node = phys_proc_id[cpu];
                if (!node_online(node))
                        node = first_node(node_online_map);
                cpu_to_node[cpu] = node;
@@ -745,15 +753,11 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
                node = cpu_to_node[cpu];
        }
 #endif
+
        printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
                        cpu, c->x86_num_cores, node, cpu_core_id[cpu]);
 #endif
 }
-#else
-static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
-{
-}
-#endif
 
 static int __init init_amd(struct cpuinfo_x86 *c)
 {
@@ -925,7 +929,6 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c)
        c->x86_clflush_size = 64;
        c->x86_cache_alignment = c->x86_clflush_size;
        c->x86_num_cores = 1;
-       c->x86_apicid = c == &boot_cpu_data ? 0 : c - cpu_data;
        c->extended_cpuid_level = 0;
        memset(&c->x86_capability, 0, sizeof c->x86_capability);
 
@@ -954,11 +957,14 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c)
                } 
                if (c->x86_capability[0] & (1<<19)) 
                        c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
-               c->x86_apicid = misc >> 24;
        } else {
                /* Have CPUID level 0 only - unheard of */
                c->x86 = 4;
        }
+
+#ifdef CONFIG_SMP
+       phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
+#endif
 }
 
 /*
@@ -1088,7 +1094,7 @@ 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", "k8c+",
+               "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
                "constant_tsc", NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
index d439ced150c603c33cbc2220bec5532654822b86..429c0269dc4e300abcf8efcb3c7a806c7ffb86a6 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/uaccess.h>
 #include <asm/i387.h>
 #include <asm/proto.h>
+#include <asm/ia32_unistd.h>
 
 /* #define DEBUG_SIG 1 */
 
@@ -452,7 +453,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                        regs->rip -= 2;
                }
                if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) {
-                       regs->rax = __NR_restart_syscall;
+                       regs->rax = test_thread_flag(TIF_IA32) ?
+                                       __NR_ia32_restart_syscall :
+                                       __NR_restart_syscall;
                        regs->rip -= 2;
                }
        }
index 73f7e8b9543aa55051e6a912e231db6ad6c8aa3b..f1ec0f34594124f73feb76dcf0f270dc420dfca5 100644 (file)
@@ -56,6 +56,7 @@
 #include <asm/kdebug.h>
 #include <asm/tlbflush.h>
 #include <asm/proto.h>
+#include <asm/nmi.h>
 
 /* Change for real CPU hotplug. Note other files need to be fixed
    first too. */
@@ -93,6 +94,7 @@ int smp_threads_ready;
 
 cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
 cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_core_map);
 
 /*
  * Trampoline 80x86 program as an array.
@@ -125,96 +127,210 @@ static void __cpuinit smp_store_cpu_info(int id)
 
        *c = boot_cpu_data;
        identify_cpu(c);
+       print_cpu_info(c);
 }
 
 /*
- * Synchronize TSCs of CPUs
+ * New Funky TSC sync algorithm borrowed from IA64.
+ * Main advantage is that it doesn't reset the TSCs fully and
+ * in general looks more robust and it works better than my earlier
+ * attempts. I believe it was written by David Mosberger. Some minor
+ * adjustments for x86-64 by me -AK
  *
- * This new algorithm is less accurate than the old "zero TSCs"
- * one, but we cannot zero TSCs anymore in the new hotplug CPU
- * model.
+ * Original comment reproduced below.
+ *
+ * Synchronize TSC of the current (slave) CPU with the TSC of the
+ * MASTER CPU (normally the time-keeper CPU).  We use a closed loop to
+ * eliminate the possibility of unaccounted-for errors (such as
+ * getting a machine check in the middle of a calibration step).  The
+ * basic idea is for the slave to ask the master what itc value it has
+ * and to read its own itc before and after the master responds.  Each
+ * iteration gives us three timestamps:
+ *
+ *     slave           master
+ *
+ *     t0 ---\
+ *             ---\
+ *                --->
+ *                     tm
+ *                /---
+ *            /---
+ *     t1 <---
+ *
+ *
+ * The goal is to adjust the slave's TSC such that tm falls exactly
+ * half-way between t0 and t1.  If we achieve this, the clocks are
+ * synchronized provided the interconnect between the slave and the
+ * master is symmetric.  Even if the interconnect were asymmetric, we
+ * would still know that the synchronization error is smaller than the
+ * roundtrip latency (t0 - t1).
+ *
+ * When the interconnect is quiet and symmetric, this lets us
+ * synchronize the TSC to within one or two cycles.  However, we can
+ * only *guarantee* that the synchronization is accurate to within a
+ * round-trip time, which is typically in the range of several hundred
+ * cycles (e.g., ~500 cycles).  In practice, this means that the TSCs
+ * are usually almost perfectly synchronized, but we shouldn't assume
+ * that the accuracy is much better than half a micro second or so.
+ *
+ * [there are other errors like the latency of RDTSC and of the
+ * WRMSR. These can also account to hundreds of cycles. So it's
+ * probably worse. It claims 153 cycles error on a dual Opteron,
+ * but I suspect the numbers are actually somewhat worse -AK]
  */
 
-static atomic_t __cpuinitdata tsc_flag;
+#define MASTER 0
+#define SLAVE  (SMP_CACHE_BYTES/8)
+
+/* Intentionally don't use cpu_relax() while TSC synchronization
+   because we don't want to go into funky power save modi or cause
+   hypervisors to schedule us away.  Going to sleep would likely affect
+   latency and low latency is the primary objective here. -AK */
+#define no_cpu_relax() barrier()
+
 static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock);
-static unsigned long long __cpuinitdata bp_tsc, ap_tsc;
+static volatile __cpuinitdata unsigned long go[SLAVE + 1];
+static int notscsync __cpuinitdata;
+
+#undef DEBUG_TSC_SYNC
 
-#define NR_LOOPS 5
+#define NUM_ROUNDS     64      /* magic value */
+#define NUM_ITERS      5       /* likewise */
 
-static void __cpuinit sync_tsc_bp_init(int init)
+/* Callback on boot CPU */
+static __cpuinit void sync_master(void *arg)
 {
-       if (init)
-               _raw_spin_lock(&tsc_sync_lock);
-       else
-               _raw_spin_unlock(&tsc_sync_lock);
-       atomic_set(&tsc_flag, 0);
+       unsigned long flags, i;
+
+       if (smp_processor_id() != boot_cpu_id)
+               return;
+
+       go[MASTER] = 0;
+
+       local_irq_save(flags);
+       {
+               for (i = 0; i < NUM_ROUNDS*NUM_ITERS; ++i) {
+                       while (!go[MASTER])
+                               no_cpu_relax();
+                       go[MASTER] = 0;
+                       rdtscll(go[SLAVE]);
+               }
+       }
+       local_irq_restore(flags);
 }
 
 /*
- * Synchronize TSC on AP with BP.
+ * Return the number of cycles by which our tsc differs from the tsc
+ * on the master (time-keeper) CPU.  A positive number indicates our
+ * tsc is ahead of the master, negative that it is behind.
  */
-static void __cpuinit __sync_tsc_ap(void)
+static inline long
+get_delta(long *rt, long *master)
 {
-       if (!cpu_has_tsc)
-               return;
-       Dprintk("AP %d syncing TSC\n", smp_processor_id());
+       unsigned long best_t0 = 0, best_t1 = ~0UL, best_tm = 0;
+       unsigned long tcenter, t0, t1, tm;
+       int i;
 
-       while (atomic_read(&tsc_flag) != 0)
-               cpu_relax();
-       atomic_inc(&tsc_flag);
-       mb();
-       _raw_spin_lock(&tsc_sync_lock);
-       wrmsrl(MSR_IA32_TSC, bp_tsc);
-       _raw_spin_unlock(&tsc_sync_lock);
-       rdtscll(ap_tsc);
-       mb();
-       atomic_inc(&tsc_flag);
-       mb();
+       for (i = 0; i < NUM_ITERS; ++i) {
+               rdtscll(t0);
+               go[MASTER] = 1;
+               while (!(tm = go[SLAVE]))
+                       no_cpu_relax();
+               go[SLAVE] = 0;
+               rdtscll(t1);
+
+               if (t1 - t0 < best_t1 - best_t0)
+                       best_t0 = t0, best_t1 = t1, best_tm = tm;
+       }
+
+       *rt = best_t1 - best_t0;
+       *master = best_tm - best_t0;
+
+       /* average best_t0 and best_t1 without overflow: */
+       tcenter = (best_t0/2 + best_t1/2);
+       if (best_t0 % 2 + best_t1 % 2 == 2)
+               ++tcenter;
+       return tcenter - best_tm;
 }
 
-static void __cpuinit sync_tsc_ap(void)
+static __cpuinit void sync_tsc(void)
 {
-       int i;
-       for (i = 0; i < NR_LOOPS; i++)
-               __sync_tsc_ap();
+       int i, done = 0;
+       long delta, adj, adjust_latency = 0;
+       unsigned long flags, rt, master_time_stamp, bound;
+#if DEBUG_TSC_SYNC
+       static struct syncdebug {
+               long rt;        /* roundtrip time */
+               long master;    /* master's timestamp */
+               long diff;      /* difference between midpoint and master's timestamp */
+               long lat;       /* estimate of tsc adjustment latency */
+       } t[NUM_ROUNDS] __cpuinitdata;
+#endif
+
+       go[MASTER] = 1;
+
+       smp_call_function(sync_master, NULL, 1, 0);
+
+       while (go[MASTER])      /* wait for master to be ready */
+               no_cpu_relax();
+
+       spin_lock_irqsave(&tsc_sync_lock, flags);
+       {
+               for (i = 0; i < NUM_ROUNDS; ++i) {
+                       delta = get_delta(&rt, &master_time_stamp);
+                       if (delta == 0) {
+                               done = 1;       /* let's lock on to this... */
+                               bound = rt;
+                       }
+
+                       if (!done) {
+                               unsigned long t;
+                               if (i > 0) {
+                                       adjust_latency += -delta;
+                                       adj = -delta + adjust_latency/4;
+                               } else
+                                       adj = -delta;
+
+                               rdtscll(t);
+                               wrmsrl(MSR_IA32_TSC, t + adj);
+                       }
+#if DEBUG_TSC_SYNC
+                       t[i].rt = rt;
+                       t[i].master = master_time_stamp;
+                       t[i].diff = delta;
+                       t[i].lat = adjust_latency/4;
+#endif
+               }
+       }
+       spin_unlock_irqrestore(&tsc_sync_lock, flags);
+
+#if DEBUG_TSC_SYNC
+       for (i = 0; i < NUM_ROUNDS; ++i)
+               printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ld\n",
+                      t[i].rt, t[i].master, t[i].diff, t[i].lat);
+#endif
+
+       printk(KERN_INFO
+              "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, "
+              "maxerr %lu cycles)\n",
+              smp_processor_id(), boot_cpu_id, delta, rt);
 }
 
-/*
- * Synchronize TSC from BP to AP.
- */
-static void __cpuinit __sync_tsc_bp(int cpu)
+static void __cpuinit tsc_sync_wait(void)
 {
-       if (!cpu_has_tsc)
+       if (notscsync || !cpu_has_tsc)
                return;
-
-       /* Wait for AP */
-       while (atomic_read(&tsc_flag) == 0)
-               cpu_relax();
-       /* Save BPs TSC */
-       sync_core();
-       rdtscll(bp_tsc);
-       /* Don't do the sync core here to avoid too much latency. */
-       mb();
-       /* Start the AP */
-       _raw_spin_unlock(&tsc_sync_lock);
-       /* Wait for AP again */
-       while (atomic_read(&tsc_flag) < 2)
-               cpu_relax();
-       rdtscl(bp_tsc);
-       barrier();
+       printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(),
+                       boot_cpu_id);
+       sync_tsc();
 }
 
-static void __cpuinit sync_tsc_bp(int cpu)
+static __init int notscsync_setup(char *s)
 {
-       int i;
-       for (i = 0; i < NR_LOOPS - 1; i++) {
-               __sync_tsc_bp(cpu);
-               sync_tsc_bp_init(1);
-       }
-       __sync_tsc_bp(cpu);
-       printk(KERN_INFO "Synced TSC of CPU %d difference %Ld\n",
-              cpu, ap_tsc - bp_tsc);
+       notscsync = 1;
+       return 0;
 }
+__setup("notscsync", notscsync_setup);
 
 static atomic_t init_deasserted __cpuinitdata;
 
@@ -315,11 +431,6 @@ void __cpuinit start_secondary(void)
        cpu_init();
        smp_callin();
 
-       /*
-        * Synchronize the TSC with the BP
-        */
-       sync_tsc_ap();
-
        /* otherwise gcc will move up the smp_processor_id before the cpu_init */
        barrier();
 
@@ -334,7 +445,6 @@ void __cpuinit start_secondary(void)
                enable_8259A_irq(0);
        }
 
-
        enable_APIC_timer();
 
        /*
@@ -343,6 +453,11 @@ void __cpuinit start_secondary(void)
        cpu_set(smp_processor_id(), cpu_online_map);
        mb();
 
+       /* Wait for TSC sync to not schedule things before.
+          We still process interrupts, which could see an inconsistent
+          time in that window unfortunately. */
+       tsc_sync_wait();
+
        cpu_idle();
 }
 
@@ -531,7 +646,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
                printk("failed fork for CPU %d\n", cpu);
                return PTR_ERR(idle);
        }
-       x86_cpu_to_apicid[cpu] = apicid;
 
        cpu_pda[cpu].pcurrent = idle;
 
@@ -600,8 +714,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
 
                if (cpu_isset(cpu, cpu_callin_map)) {
                        /* number CPUs logically, starting from 1 (BSP is 0) */
-                       Dprintk("OK.\n");
-                       print_cpu_info(&cpu_data[cpu]);
                        Dprintk("CPU has booted.\n");
                } else {
                        boot_error = 1;
@@ -842,7 +954,6 @@ void __cpuinit smp_prepare_cpus(unsigned int max_cpus)
                      GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id);
                /* Or can we switch back to PIC here? */
        }
-       x86_cpu_to_apicid[0] = boot_cpu_id;
 
        /*
         * Now start the IO-APICs
@@ -889,18 +1000,14 @@ int __cpuinit __cpu_up(unsigned int cpu)
                printk("__cpu_up: bad cpu %d\n", cpu);
                return -EINVAL;
        }
-       sync_tsc_bp_init(1);
 
        /* Boot it! */
        err = do_boot_cpu(cpu, apicid);
        if (err < 0) {
-               sync_tsc_bp_init(0);
                Dprintk("do_boot_cpu failed %d\n", err);
                return err;
        }
 
-       sync_tsc_bp(cpu);
-
        /* Unleash the CPU! */
        Dprintk("waiting for cpu %d\n", cpu);
 
@@ -923,4 +1030,6 @@ void __cpuinit smp_cpus_done(unsigned int max_cpus)
 
        detect_siblings();
        time_init_gtod();
+
+       check_nmi_watchdog();
 }
index 0e3b60e1ac5b54f60d4a2a7cff4492c8ddef9774..fb8c809b4cd94fb817b7d04b6db140423e80cf30 100644 (file)
 #include <linux/sysdev.h>
 #include <linux/bcd.h>
 #include <linux/kallsyms.h>
+#include <linux/acpi.h>
+#ifdef CONFIG_ACPI
+#include <acpi/achware.h>      /* for PM timer frequency */
+#endif
 #include <asm/8253pit.h>
 #include <asm/pgtable.h>
 #include <asm/vsyscall.h>
@@ -396,6 +400,10 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick;
 
                vxtime.last = offset;
+#ifdef CONFIG_X86_PM_TIMER
+       } else if (vxtime.mode == VXTIME_PMTMR) {
+               lost = pmtimer_mark_offset();
+#endif
        } else {
                offset = (((tsc - vxtime.last_tsc) *
                           vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ);
@@ -898,6 +906,13 @@ void __init time_init(void)
                        hpet_period;
                cpu_khz = hpet_calibrate_tsc();
                timename = "HPET";
+#ifdef CONFIG_X86_PM_TIMER
+       } else if (pmtmr_ioport) {
+               vxtime_hz = PM_TIMER_FREQUENCY;
+               timename = "PM";
+               pit_init();
+               cpu_khz = pit_calibrate_tsc();
+#endif
        } else {
                pit_init();
                cpu_khz = pit_calibrate_tsc();
@@ -922,6 +937,27 @@ void __init time_init(void)
 #endif
 }
 
+/*
+ * Make an educated guess if the TSC is trustworthy and synchronized
+ * over all CPUs.
+ */
+static __init int unsynchronized_tsc(void)
+{
+#ifdef CONFIG_SMP
+       if (oem_force_hpet_timer())
+               return 1;
+       /* Intel systems are normally all synchronized. Exceptions
+          are handled in the OEM check above. */
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+               return 0;
+       /* All in a single socket - should be synchronized */
+       if (cpus_weight(cpu_core_map[0]) == num_online_cpus())
+               return 0;
+#endif
+       /* Assume multi socket systems are not synchronized */
+       return num_online_cpus() > 1;
+}
+
 /*
  * Decide after all CPUs are booted what mode gettimeofday should use.
  */
@@ -929,29 +965,23 @@ void __init time_init_gtod(void)
 {
        char *timetype;
 
-       /*
-        * AMD systems with more than one CPU don't have fully synchronized
-        * TSCs. Always use HPET gettimeofday for these, although it is slower.
-        * Intel SMP systems usually have synchronized TSCs, so use always
-        * the TSC.
-        *
-        * Exceptions:
-        * IBM Summit2 checked by oem_force_hpet_timer().
-        * AMD dual core may also not need HPET. Check me.
-        *
-        * Can be turned off with "notsc".
-        */
-       if (num_online_cpus() > 1 &&
-           boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
-               notsc = 1;
-       /* Some systems will want to disable TSC and use HPET. */
-       if (oem_force_hpet_timer())
+       if (unsynchronized_tsc())
                notsc = 1;
        if (vxtime.hpet_address && notsc) {
                timetype = "HPET";
                vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
                vxtime.mode = VXTIME_HPET;
                do_gettimeoffset = do_gettimeoffset_hpet;
+#ifdef CONFIG_X86_PM_TIMER
+       /* Using PM for gettimeofday is quite slow, but we have no other
+          choice because the TSC is too unreliable on some systems. */
+       } else if (pmtmr_ioport && !vxtime.hpet_address && notsc) {
+               timetype = "PM";
+               do_gettimeoffset = do_gettimeoffset_pm;
+               vxtime.mode = VXTIME_PMTMR;
+               sysctl_vsyscall = 0;
+               printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n");
+#endif
        } else {
                timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC";
                vxtime.mode = VXTIME_TSC;
index 65a37f52c56ef2c0760f2e3db9dfec9312a74d88..3dfec8fdabcdd35799cf014d08fc89d6bf1a7701 100644 (file)
@@ -332,10 +332,12 @@ void handle_BUG(struct pt_regs *regs)
        printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", f.filename, f.line);
 } 
 
+#ifdef CONFIG_BUG
 void out_of_line_bug(void)
 { 
        BUG(); 
 } 
+#endif
 
 static DEFINE_SPINLOCK(die_lock);
 static int die_owner = -1;
index b4b8dc59663ad447f6228fff15209067928b642e..2e5734425949648ea92bd8d7fd9e65e6f99a8ed5 100644 (file)
@@ -65,7 +65,7 @@ static force_inline void do_vgettimeofday(struct timeval * tv)
                usec = (__xtime.tv_nsec / 1000) +
                        (__jiffies - __wall_jiffies) * (1000000 / HZ);
 
-               if (__vxtime.mode == VXTIME_TSC) {
+               if (__vxtime.mode != VXTIME_HPET) {
                        sync_core();
                        rdtscll(t);
                        if (t < __vxtime.last_tsc)
@@ -217,8 +217,9 @@ static int __init vsyscall_init(void)
        BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime));
        BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE)));
        map_vsyscall();
-       sysctl_vsyscall = 1;
+#ifdef CONFIG_SYSCTL
        register_sysctl_table(kernel_root_table2, 0);
+#endif
        return 0;
 }
 
index 88626e626886e60a51a23834721a31617f060d68..68ec03070e5adbe82925dba26772a688cecd1b9b 100644 (file)
@@ -139,35 +139,23 @@ EXPORT_SYMBOL_GPL(unset_nmi_callback);
 #undef memmove
 #undef memchr
 #undef strlen
-#undef strcpy
 #undef strncmp
 #undef strncpy
 #undef strchr  
-#undef strcmp 
-#undef strcpy 
-#undef strcat
-#undef memcmp
 
 extern void * memset(void *,int,__kernel_size_t);
 extern size_t strlen(const char *);
 extern void * memmove(void * dest,const void *src,size_t count);
-extern char * strcpy(char * dest,const char *src);
-extern int strcmp(const char * cs,const char * ct);
 extern void *memchr(const void *s, int c, size_t n);
 extern void * memcpy(void *,const void *,__kernel_size_t);
 extern void * __memcpy(void *,const void *,__kernel_size_t);
-extern char * strcat(char *, const char *);
-extern int memcmp(const void * cs,const void * ct,size_t count);
 
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(strlen);
 EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(strcpy);
 EXPORT_SYMBOL(strncmp);
 EXPORT_SYMBOL(strncpy);
 EXPORT_SYMBOL(strchr);
-EXPORT_SYMBOL(strcmp);
-EXPORT_SYMBOL(strcat);
 EXPORT_SYMBOL(strncat);
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(strrchr);
@@ -175,7 +163,6 @@ EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(memscan);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(__memcpy);
-EXPORT_SYMBOL(memcmp);
 
 #ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
 /* prototypes are wrong, these are assembly with custom calling functions */
@@ -206,8 +193,9 @@ EXPORT_SYMBOL(smp_num_siblings);
 extern void do_softirq_thunk(void);
 EXPORT_SYMBOL(do_softirq_thunk);
 
-void out_of_line_bug(void);
+#ifdef CONFIG_BUG
 EXPORT_SYMBOL(out_of_line_bug);
+#endif
 
 EXPORT_SYMBOL(init_level4_pgt);
 
index e0330921676413d100b6a1f2cf2c6f579133e3d8..5d6b2114cc9a4e5d30b9736a339dad5bc03839fc 100644 (file)
@@ -234,6 +234,8 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
 
 /*
  * Handle a fault on the vmalloc or module mapping area
+ *
+ * This assumes no large pages in there.
  */
 static int vmalloc_fault(unsigned long address)
 {
@@ -272,7 +274,10 @@ static int vmalloc_fault(unsigned long address)
        if (!pte_present(*pte_ref))
                return -1;
        pte = pte_offset_kernel(pmd, address);
-       if (!pte_present(*pte) || pte_page(*pte) != pte_page(*pte_ref))
+       /* Don't use pte_page here, because the mappings can point
+          outside mem_map, and the NUMA hash lookup cannot handle
+          that. */
+       if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
                BUG();
        __flush_tlb_all();
        return 0;
@@ -346,7 +351,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
         * protection error (error_code & 1) == 0.
         */
        if (unlikely(address >= TASK_SIZE)) {
-               if (!(error_code & 5)) {
+               if (!(error_code & 5) &&
+                     ((address >= VMALLOC_START && address < VMALLOC_END) ||
+                      (address >= MODULES_VADDR && address < MODULES_END))) {
                        if (vmalloc_fault(address) < 0)
                                goto bad_area_nosemaphore;
                        return;
index 74ec8554b195de6c5a9b87ce5d39f08d9c5da544..58aac23760efeb3e37aa76ab888e3e900b7ac667 100644 (file)
@@ -133,7 +133,7 @@ ioremap_change_attr(unsigned long phys_addr, unsigned long size,
                                        unsigned long flags)
 {
        int err = 0;
-       if (flags && phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) {
+       if (phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) {
                unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
                unsigned long vaddr = (unsigned long) __va(phys_addr);
 
@@ -214,7 +214,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
                remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
                return NULL;
        }
-       if (ioremap_change_attr(phys_addr, size, flags) < 0) {
+       if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) {
                area->flags &= 0xffffff;
                vunmap(addr);
                return NULL;
@@ -251,7 +251,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
 
 void iounmap(volatile void __iomem *addr)
 {
-       struct vm_struct *p, **pprev;
+       struct vm_struct *p;
 
        if (addr <= high_memory) 
                return; 
@@ -260,24 +260,11 @@ void iounmap(volatile void __iomem *addr)
                return;
 
        write_lock(&vmlist_lock);
-       for (p = vmlist, pprev = &vmlist; p != NULL; pprev = &p->next, p = *pprev)
-               if (p->addr == (void *)(PAGE_MASK & (unsigned long)addr))
-                       break;
-       if (!p) { 
-               printk("__iounmap: bad address %p\n", addr);
-               goto out_unlock;
-       }
-       *pprev = p->next;
-       unmap_vm_area(p);
-       if ((p->flags >> 20) &&
-               p->phys_addr + p->size - 1 < virt_to_phys(high_memory)) {
-               /* p->size includes the guard page, but cpa doesn't like that */
-               change_page_attr(virt_to_page(__va(p->phys_addr)),
-                                p->size >> PAGE_SHIFT,
-                                PAGE_KERNEL);
-               global_flush_tlb();
-       } 
-out_unlock:
+       p = __remove_vm_area((void *)((unsigned long)addr & PAGE_MASK));
+       if (!p)
+               printk("iounmap: bad address %p\n", addr);
+       else if (p->flags >> 20)
+               ioremap_change_attr(p->phys_addr, p->size, 0);
        write_unlock(&vmlist_lock);
        kfree(p); 
 }
index f691d31fa9ee0cbe7a1817408ea845584bd2a8b9..3fcf6e887e87d7280a9765450b237e9933af035a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mm.h>
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/string.h>
 
 #define NULL_KEY_SIZE          0
 #define NULL_BLOCK_SIZE                1
 
 static int null_compress(void *ctx, const u8 *src, unsigned int slen,
                          u8 *dst, unsigned int *dlen)
-{ return 0; }
-
-static int null_decompress(void *ctx, const u8 *src, unsigned int slen,
-                           u8 *dst, unsigned int *dlen)
-{ return 0; }
+{
+       if (slen > *dlen)
+               return -EINVAL;
+       memcpy(dst, src, slen);
+       *dlen = slen;
+       return 0;
+}
 
 static void null_init(void *ctx)
 { }
@@ -47,11 +50,10 @@ static int null_setkey(void *ctx, const u8 *key,
                        unsigned int keylen, u32 *flags)
 { return 0; }
 
-static void null_encrypt(void *ctx, u8 *dst, const u8 *src)
-{ }
-
-static void null_decrypt(void *ctx, u8 *dst, const u8 *src)
-{ }
+static void null_crypt(void *ctx, u8 *dst, const u8 *src)
+{
+       memcpy(dst, src, NULL_BLOCK_SIZE);
+}
 
 static struct crypto_alg compress_null = {
        .cra_name               =       "compress_null",
@@ -62,7 +64,7 @@ static struct crypto_alg compress_null = {
        .cra_list               =       LIST_HEAD_INIT(compress_null.cra_list),
        .cra_u                  =       { .compress = {
        .coa_compress           =       null_compress,
-       .coa_decompress         =       null_decompress } }
+       .coa_decompress         =       null_compress } }
 };
 
 static struct crypto_alg digest_null = {
@@ -90,8 +92,8 @@ static struct crypto_alg cipher_null = {
        .cia_min_keysize        =       NULL_KEY_SIZE,
        .cia_max_keysize        =       NULL_KEY_SIZE,
        .cia_setkey             =       null_setkey,
-       .cia_encrypt            =       null_encrypt,
-       .cia_decrypt            =       null_decrypt } }
+       .cia_encrypt            =       null_crypt,
+       .cia_decrypt            =       null_crypt } }
 };
 
 MODULE_ALIAS("compress_null");
index e68e43886d3cc23439f30210e88b517911bf395e..964b9a60ca24413f07b1fe8410f7ac3198642135 100644 (file)
@@ -38,7 +38,7 @@ static inline void crypto_kunmap(void *vaddr, int out)
 
 static inline void crypto_yield(struct crypto_tfm *tfm)
 {
-       if (!in_softirq())
+       if (!in_atomic())
                cond_resched();
 }
 
index 0400a52d50855744a0a23d331db4a1928263789f..670fdb5142d17d3da59717b844560c861bbad8a5 100644 (file)
@@ -40,13 +40,12 @@ config ACPI
          available at:
          <http://www.acpi.info>
 
+if ACPI
+
 config ACPI_BOOT
        bool
-       depends on ACPI || X86_HT
        default y
 
-if ACPI
-
 config ACPI_INTERPRETER
        bool
        depends on !IA64_SGI_SN
index 12b0eea634073399d5f219e460dbf88acde98b34..8093f2e003215156d376c9a8c086e8d9dfaf9d30 100644 (file)
@@ -391,7 +391,6 @@ acpi_pci_irq_enable (
        u8                      pin = 0;
        int                     edge_level = ACPI_LEVEL_SENSITIVE;
        int                     active_high_low = ACPI_ACTIVE_LOW;
-       extern int              via_interrupt_line_quirk;
        char                    *link = NULL;
 
        ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
@@ -444,9 +443,6 @@ acpi_pci_irq_enable (
                }
        }
 
-       if (via_interrupt_line_quirk)
-               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq & 15);
-
        dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
 
        printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
index d1dcd8eae3c901c3bacb00f08875ebb770141e44..5b77188527a9ad91f8d3f70691ba9c2d4393f4a1 100644 (file)
@@ -39,7 +39,8 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
   fore_200e-objs               += fore200e_pca_fw.o
   # guess the target endianess to choose the right PCA-200E firmware image
   ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y)
-    CONFIG_ATM_FORE200E_PCA_FW = $(shell if test -n "`$(CC) -E -dM $(src)/../../include/asm/byteorder.h | grep ' __LITTLE_ENDIAN '`"; then echo $(obj)/pca200e.bin; else echo $(obj)/pca200e_ecd.bin2; fi)
+    byteorder.h                        := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h
+    CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2)
   endif
 endif
 
index 9e65bfb85ba325285f299dcaf82388146bcafebb..5f702199543ac043eec3905b6231e119e421ba7c 100644 (file)
@@ -383,8 +383,7 @@ fore200e_shutdown(struct fore200e* fore200e)
     switch(fore200e->state) {
 
     case FORE200E_STATE_COMPLETE:
-       if (fore200e->stats)
-           kfree(fore200e->stats);
+       kfree(fore200e->stats);
 
     case FORE200E_STATE_IRQ:
        free_irq(fore200e->irq, fore200e->atm_dev);
@@ -963,8 +962,7 @@ fore200e_tx_irq(struct fore200e* fore200e)
                entry, txq->tail, entry->vc_map, entry->skb);
 
        /* free copy of misaligned data */
-       if (entry->data)
-           kfree(entry->data);
+       kfree(entry->data);
        
        /* remove DMA mapping */
        fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
index 3022c548a132317e4b8c9334b0cd520b63bde32e..df2c83fd5496015ac64025ea9762e90e80c5093f 100644 (file)
@@ -412,8 +412,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
 init_one_failure:
        if (atm_dev)
                atm_dev_deregister(atm_dev);
-       if (he_dev)
-               kfree(he_dev);
+       kfree(he_dev);
        pci_disable_device(pci_dev);
        return err;
 }
@@ -2534,8 +2533,7 @@ he_open(struct atm_vcc *vcc)
 open_failed:
 
        if (err) {
-               if (he_vcc)
-                       kfree(he_vcc);
+               kfree(he_vcc);
                clear_bit(ATM_VF_ADDR, &vcc->flags);
        }
        else
index 85bf5c8442b000917465b56fb9ce12d2b0e68a14..b2a7b754fd1403a4c7dbd4ffe5ab47cd3de70b5e 100644 (file)
@@ -676,10 +676,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
    PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base);
       
    /* Initialize SCQ0, the only VBR SCQ used */
-   card->scq1 = (scq_info *) NULL;
-   card->scq2 = (scq_info *) NULL;
+   card->scq1 = NULL;
+   card->scq2 = NULL;
    card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0);
-   if (card->scq0 == (scq_info *) NULL)
+   if (card->scq0 == NULL)
    {
       printk("nicstar%d: can't get SCQ0.\n", i);
       error = 12;
@@ -993,24 +993,24 @@ static scq_info *get_scq(int size, u32 scd)
    int i;
 
    if (size != VBR_SCQSIZE && size != CBR_SCQSIZE)
-      return (scq_info *) NULL;
+      return NULL;
 
    scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL);
-   if (scq == (scq_info *) NULL)
-      return (scq_info *) NULL;
+   if (scq == NULL)
+      return NULL;
    scq->org = kmalloc(2 * size, GFP_KERNEL);
    if (scq->org == NULL)
    {
       kfree(scq);
-      return (scq_info *) NULL;
+      return NULL;
    }
    scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) *
                                           (size / NS_SCQE_SIZE), GFP_KERNEL);
-   if (scq->skb == (struct sk_buff **) NULL)
+   if (scq->skb == NULL)
    {
       kfree(scq->org);
       kfree(scq);
-      return (scq_info *) NULL;
+      return NULL;
    }
    scq->num_entries = size / NS_SCQE_SIZE;
    scq->base = (ns_scqe *) ALIGN_ADDRESS(scq->org, size);
@@ -1498,7 +1498,7 @@ static int ns_open(struct atm_vcc *vcc)
          vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE;
 
          scq = get_scq(CBR_SCQSIZE, vc->cbr_scd);
-         if (scq == (scq_info *) NULL)
+         if (scq == NULL)
          {
             PRINTK("nicstar%d: can't get fixed rate SCQ.\n", card->index);
             card->scd2vc[frscdi] = NULL;
index 47a800519ad01ed87638b329f1fd4a1213c6a641..8d5e65cb975528203ebb5b951044d9eaf73c91ad 100644 (file)
@@ -902,7 +902,7 @@ static void close_tx(struct atm_vcc *vcc)
                zatm_dev->tx_bw += vcc->qos.txtp.min_pcr;
                dealloc_shaper(vcc->dev,zatm_vcc->shaper);
        }
-       if (zatm_vcc->ring) kfree(zatm_vcc->ring);
+       kfree(zatm_vcc->ring);
 }
 
 
@@ -1339,12 +1339,9 @@ static int __init zatm_start(struct atm_dev *dev)
        return 0;
     out:
        for (i = 0; i < NR_MBX; i++)
-               if (zatm_dev->mbx_start[i] != 0)
-                       kfree((void *) zatm_dev->mbx_start[i]);
-       if (zatm_dev->rx_map != NULL)
-               kfree(zatm_dev->rx_map);
-       if (zatm_dev->tx_map != NULL)
-               kfree(zatm_dev->tx_map);
+               kfree(zatm_dev->mbx_start[i]);
+       kfree(zatm_dev->rx_map);
+       kfree(zatm_dev->tx_map);
        free_irq(zatm_dev->irq, dev);
        return error;
 }
index 6662b545e0a910cde8cccee988efe337b54fd2a6..a47928a2e57508a30bb527143d3c503201592f00 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for the Linux device tree
 
-obj-y                  := core.o sys.o interface.o bus.o \
+obj-y                  := core.o sys.o bus.o \
                           driver.o class.o class_simple.o platform.o \
                           cpu.o firmware.o init.o map.o dmapool.o \
                           attribute_container.o transport_class.o
index f4fa27315fb4b69841ecf2a551d58d9a241c5546..3cb04bb04c2b8e0d80ad910f8b6e94935be1c089 100644 (file)
@@ -390,7 +390,6 @@ void device_release_driver(struct device * dev)
                sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
                sysfs_remove_link(&dev->kobj, "driver");
                list_del_init(&dev->driver_list);
-               device_detach_shutdown(dev);
                if (drv->remove)
                        drv->remove(dev);
                dev->driver = NULL;
@@ -405,9 +404,8 @@ void device_release_driver(struct device * dev)
 
 static void driver_detach(struct device_driver * drv)
 {
-       struct list_head * entry, * next;
-       list_for_each_safe(entry, next, &drv->devices) {
-               struct device * dev = container_of(entry, struct device, driver_list);
+       while (!list_empty(&drv->devices)) {
+               struct device * dev = container_of(drv->devices.next, struct device, driver_list);
                device_release_driver(dev);
        }
 }
index a7cedd8cefe5385a8d2eb6f334c8661454c443d7..fbc223486f81b2b8380b0e157a81e429986ff73c 100644 (file)
@@ -31,8 +31,6 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
 #define to_dev(obj) container_of(obj, struct device, kobj)
 #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
 
-extern struct attribute * dev_default_attrs[];
-
 static ssize_t
 dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
 {
@@ -89,7 +87,6 @@ static void device_release(struct kobject * kobj)
 static struct kobj_type ktype_device = {
        .release        = device_release,
        .sysfs_ops      = &dev_sysfs_ops,
-       .default_attrs  = dev_default_attrs,
 };
 
 
@@ -139,7 +136,7 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
        buffer = &buffer[length];
        buffer_size -= length;
 
-       if (dev->bus->hotplug) {
+       if (dev->bus && dev->bus->hotplug) {
                /* have the bus specific function add its stuff */
                retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size);
                        if (retval) {
@@ -248,6 +245,7 @@ int device_add(struct device *dev)
 
        if ((error = kobject_add(&dev->kobj)))
                goto Error;
+       kobject_hotplug(&dev->kobj, KOBJ_ADD);
        if ((error = device_pm_add(dev)))
                goto PMError;
        if ((error = bus_add_device(dev)))
@@ -260,14 +258,13 @@ int device_add(struct device *dev)
        /* notify platform of device entry */
        if (platform_notify)
                platform_notify(dev);
-
-       kobject_hotplug(&dev->kobj, KOBJ_ADD);
  Done:
        put_device(dev);
        return error;
  BusError:
        device_pm_remove(dev);
  PMError:
+       kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
        kobject_del(&dev->kobj);
  Error:
        if (parent)
diff --git a/drivers/base/interface.c b/drivers/base/interface.c
deleted file mode 100644 (file)
index bd51584..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * drivers/base/interface.c - common driverfs interface that's exported to
- *     the world for all devices.
- *
- * Copyright (c) 2002-3 Patrick Mochel
- * Copyright (c) 2002-3 Open Source Development Labs
- *
- * This file is released under the GPLv2
- *
- */
-
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/stat.h>
-#include <linux/string.h>
-
-/**
- *     detach_state - control the default power state for the device.
- *
- *     This is the state the device enters when it's driver module is
- *     unloaded. The value is an unsigned integer, in the range of 0-4.
- *     '0' indicates 'On', so no action will be taken when the driver is
- *     unloaded. This is the default behavior.
- *     '4' indicates 'Off', meaning the driver core will call the driver's
- *     shutdown method to quiesce the device.
- *     1-3 indicate a low-power state for the device to enter via the
- *     driver's suspend method.
- */
-
-static ssize_t detach_show(struct device * dev, char * buf)
-{
-       return sprintf(buf, "%u\n", dev->detach_state);
-}
-
-static ssize_t detach_store(struct device * dev, const char * buf, size_t n)
-{
-       u32 state;
-       state = simple_strtoul(buf, NULL, 10);
-       if (state > 4)
-               return -EINVAL;
-       dev->detach_state = state;
-       return n;
-}
-
-static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store);
-
-
-struct attribute * dev_default_attrs[] = {
-       &dev_attr_detach_state.attr,
-       NULL,
-};
index e5eda746f2a6d1f2a543e017665d2dac90f0fe5c..2e700d795cf15033c933e4a1a71a4d73afa59a14 100644 (file)
@@ -1,18 +1,7 @@
-
-
-enum {
-       DEVICE_PM_ON,
-       DEVICE_PM1,
-       DEVICE_PM2,
-       DEVICE_PM3,
-       DEVICE_PM_OFF,
-};
-
 /*
  * shutdown.c
  */
 
-extern int device_detach_shutdown(struct device *);
 extern void device_shutdown(void);
 
 
index f8f5055754d65b3fd1c41348dade1e1092b9bc5e..26468971ef5a7711179e87f0d500cdc680888157 100644 (file)
@@ -22,8 +22,17 @@ extern int sysdev_resume(void);
 
 int resume_device(struct device * dev)
 {
-       if (dev->bus && dev->bus->resume)
+       if (dev->power.pm_parent
+                       && dev->power.pm_parent->power.power_state) {
+               dev_err(dev, "PM: resume from %d, parent %s still %d\n",
+                       dev->power.power_state,
+                       dev->power.pm_parent->bus_id,
+                       dev->power.pm_parent->power.power_state);
+       }
+       if (dev->bus && dev->bus->resume) {
+               dev_dbg(dev,"resuming\n");
                return dev->bus->resume(dev);
+       }
        return 0;
 }
 
index d1e023fbe16939051739c8424dc7515d9f965f42..f50a08be424b1c524122b19ba769342f38caf02b 100644 (file)
 extern struct subsystem devices_subsys;
 
 
-int device_detach_shutdown(struct device * dev)
-{
-       if (!dev->detach_state)
-               return 0;
-
-       if (dev->detach_state == DEVICE_PM_OFF) {
-               if (dev->driver && dev->driver->shutdown)
-                       dev->driver->shutdown(dev);
-               return 0;
-       }
-       return dpm_runtime_suspend(dev, dev->detach_state);
-}
-
-
 /**
  * We handle system devices differently - we suspend and shut them
  * down last and resume them first. That way, we don't do anything stupid like
@@ -52,13 +38,12 @@ void device_shutdown(void)
        struct device * dev;
 
        down_write(&devices_subsys.rwsem);
-       list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) {
-               pr_debug("shutting down %s: ", dev->bus_id);
+       list_for_each_entry_reverse(dev, &devices_subsys.kset.list,
+                               kobj.entry) {
                if (dev->driver && dev->driver->shutdown) {
-                       pr_debug("Ok\n");
+                       dev_dbg(dev, "shutdown\n");
                        dev->driver->shutdown(dev);
-               } else
-                       pr_debug("Ignored.\n");
+               }
        }
        up_write(&devices_subsys.rwsem);
 
index a0b5cf689e6398422be2db4c1e37119d97856be1..0ec44ef840beaf42c89d2fdb897be5f60685a369 100644 (file)
@@ -39,12 +39,25 @@ int suspend_device(struct device * dev, pm_message_t state)
 {
        int error = 0;
 
-       dev_dbg(dev, "suspending\n");
+       if (dev->power.power_state) {
+               dev_dbg(dev, "PM: suspend %d-->%d\n",
+                       dev->power.power_state, state);
+       }
+       if (dev->power.pm_parent
+                       && dev->power.pm_parent->power.power_state) {
+               dev_err(dev,
+                       "PM: suspend %d->%d, parent %s already %d\n",
+                       dev->power.power_state, state,
+                       dev->power.pm_parent->bus_id,
+                       dev->power.pm_parent->power.power_state);
+       }
 
        dev->power.prev_state = dev->power.power_state;
 
-       if (dev->bus && dev->bus->suspend && !dev->power.power_state)
+       if (dev->bus && dev->bus->suspend && !dev->power.power_state) {
+               dev_dbg(dev, "suspending\n");
                error = dev->bus->suspend(dev, state);
+       }
 
        return error;
 }
index 423bbf2000d2f6187e9a41b11d8154b8a000f9a7..3760edfdc65cc54f9cb6525eb2d26ebd0833b1e4 100644 (file)
@@ -3,6 +3,7 @@
   Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 
   Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com>
+  Portions Copyright 2002 by Mylex (An IBM Business Unit)
 
   This program is free software; you may redistribute and/or modify it under
   the terms of the GNU General Public License Version 2 as published by the
@@ -532,6 +533,34 @@ static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
   spin_lock_irq(&Controller->queue_lock);
 }
 
+/*
+  DAC960_GEM_QueueCommand queues Command for DAC960 GEM Series Controllers.
+*/
+
+static void DAC960_GEM_QueueCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void __iomem *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandMailbox_T *NextCommandMailbox =
+      Controller->V2.NextCommandMailbox;
+
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_GEM_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+
+  if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
+      DAC960_GEM_MemoryMailboxNewCommand(ControllerBaseAddress);
+
+  Controller->V2.PreviousCommandMailbox2 =
+      Controller->V2.PreviousCommandMailbox1;
+  Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
+
+  if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
+      NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+
+  Controller->V2.NextCommandMailbox = NextCommandMailbox;
+}
 
 /*
   DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
@@ -1464,6 +1493,17 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
                                        Controller->V2.FirstStatusMailboxDMA;
   switch (Controller->HardwareType)
     {
+    case DAC960_GEM_Controller:
+      while (DAC960_GEM_HardwareMailboxFullP(ControllerBaseAddress))
+       udelay(1);
+      DAC960_GEM_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA);
+      DAC960_GEM_HardwareMailboxNewCommand(ControllerBaseAddress);
+      while (!DAC960_GEM_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
+       udelay(1);
+      CommandStatus = DAC960_GEM_ReadCommandStatus(ControllerBaseAddress);
+      DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+      DAC960_GEM_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
+      break;
     case DAC960_BA_Controller:
       while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
        udelay(1);
@@ -2627,6 +2667,9 @@ static void DAC960_DetectCleanup(DAC960_Controller_T *Controller)
   if (Controller->MemoryMappedAddress) {
        switch(Controller->HardwareType)
        {
+               case DAC960_GEM_Controller:
+                       DAC960_GEM_DisableInterrupts(Controller->BaseAddress);
+                       break;
                case DAC960_BA_Controller:
                        DAC960_BA_DisableInterrupts(Controller->BaseAddress);
                        break;
@@ -2705,6 +2748,9 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
 
   switch (Controller->HardwareType)
   {
+       case DAC960_GEM_Controller:
+         Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
+         break;
        case DAC960_BA_Controller:
          Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
          break;
@@ -2756,6 +2802,36 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
   BaseAddress = Controller->BaseAddress;
   switch (Controller->HardwareType)
   {
+       case DAC960_GEM_Controller:
+         DAC960_GEM_DisableInterrupts(BaseAddress);
+         DAC960_GEM_AcknowledgeHardwareMailboxStatus(BaseAddress);
+         udelay(1000);
+         while (DAC960_GEM_InitializationInProgressP(BaseAddress))
+           {
+             if (DAC960_GEM_ReadErrorStatus(BaseAddress, &ErrorStatus,
+                                           &Parameter0, &Parameter1) &&
+                 DAC960_ReportErrorStatus(Controller, ErrorStatus,
+                                          Parameter0, Parameter1))
+               goto Failure;
+             udelay(10);
+           }
+         if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
+           {
+             DAC960_Error("Unable to Enable Memory Mailbox Interface "
+                          "for Controller at\n", Controller);
+             goto Failure;
+           }
+         DAC960_GEM_EnableInterrupts(BaseAddress);
+         Controller->QueueCommand = DAC960_GEM_QueueCommand;
+         Controller->ReadControllerConfiguration =
+           DAC960_V2_ReadControllerConfiguration;
+         Controller->ReadDeviceConfiguration =
+           DAC960_V2_ReadDeviceConfiguration;
+         Controller->ReportDeviceConfiguration =
+           DAC960_V2_ReportDeviceConfiguration;
+         Controller->QueueReadWriteCommand =
+           DAC960_V2_QueueReadWriteCommand;
+         break;
        case DAC960_BA_Controller:
          DAC960_BA_DisableInterrupts(BaseAddress);
          DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
@@ -5189,6 +5265,47 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
   wake_up(&Controller->CommandWaitQueue);
 }
 
+/*
+  DAC960_GEM_InterruptHandler handles hardware interrupts from DAC960 GEM Series
+  Controllers.
+*/
+
+static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel,
+                                      void *DeviceIdentifier,
+                                      struct pt_regs *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void __iomem *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+  unsigned long flags;
+
+  spin_lock_irqsave(&Controller->queue_lock, flags);
+  DAC960_GEM_AcknowledgeInterrupt(ControllerBaseAddress);
+  NextStatusMailbox = Controller->V2.NextStatusMailbox;
+  while (NextStatusMailbox->Fields.CommandIdentifier > 0)
+    {
+       DAC960_V2_CommandIdentifier_T CommandIdentifier =
+           NextStatusMailbox->Fields.CommandIdentifier;
+       DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+       Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+       Command->V2.RequestSenseLength =
+           NextStatusMailbox->Fields.RequestSenseLength;
+       Command->V2.DataTransferResidue =
+           NextStatusMailbox->Fields.DataTransferResidue;
+       NextStatusMailbox->Words[0] = 0;
+       if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
+           NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+       DAC960_V2_ProcessCompletedCommand(Command);
+    }
+  Controller->V2.NextStatusMailbox = NextStatusMailbox;
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  DAC960_ProcessRequest(Controller);
+  spin_unlock_irqrestore(&Controller->queue_lock, flags);
+  return IRQ_HANDLED;
+}
 
 /*
   DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
@@ -6962,6 +7079,14 @@ static void DAC960_gam_cleanup(void)
 
 #endif /* DAC960_GAM_MINOR */
 
+static struct DAC960_privdata DAC960_GEM_privdata = {
+       .HardwareType =         DAC960_GEM_Controller,
+       .FirmwareType   =       DAC960_V2_Controller,
+       .InterruptHandler =     DAC960_GEM_InterruptHandler,
+       .MemoryWindowSize =     DAC960_GEM_RegisterWindowSize,
+};
+
+
 static struct DAC960_privdata DAC960_BA_privdata = {
        .HardwareType =         DAC960_BA_Controller,
        .FirmwareType   =       DAC960_V2_Controller,
@@ -7005,6 +7130,13 @@ static struct DAC960_privdata DAC960_P_privdata = {
 };
 
 static struct pci_device_id DAC960_id_table[] = {
+       {
+               .vendor         = PCI_VENDOR_ID_MYLEX,
+               .device         = PCI_DEVICE_ID_MYLEX_DAC960_GEM,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (unsigned long) &DAC960_GEM_privdata,
+       },
        {
                .vendor         = PCI_VENDOR_ID_MYLEX,
                .device         = PCI_DEVICE_ID_MYLEX_DAC960_BA,
index d5e8e7190c90e3c5f06192eaed625b7d900ea018..a82f37f749a5c2e265dd96c4d2abb88e84a7d329 100644 (file)
@@ -2114,7 +2114,8 @@ typedef enum
   DAC960_LA_Controller =                       3,      /* DAC1164P */
   DAC960_PG_Controller =                       4,      /* DAC960PTL/PJ/PG */
   DAC960_PD_Controller =                       5,      /* DAC960PU/PD/PL/P */
-  DAC960_P_Controller =                                6       /* DAC960PU/PD/PL/P */
+  DAC960_P_Controller =                                6,      /* DAC960PU/PD/PL/P */
+  DAC960_GEM_Controller =                      7,      /* AcceleRAID 4/5/600 */
 }
 DAC960_HardwareType_T;
 
@@ -2540,6 +2541,320 @@ void dma_addr_writeql(dma_addr_t addr, void __iomem *write_address)
        writel(u.wl[1], write_address + 4);
 }
 
+/*
+  Define the DAC960 GEM Series Controller Interface Register Offsets.
+ */
+
+#define DAC960_GEM_RegisterWindowSize  0x600
+
+typedef enum
+{
+  DAC960_GEM_InboundDoorBellRegisterReadSetOffset   =   0x214,
+  DAC960_GEM_InboundDoorBellRegisterClearOffset     =   0x218,
+  DAC960_GEM_OutboundDoorBellRegisterReadSetOffset  =   0x224,
+  DAC960_GEM_OutboundDoorBellRegisterClearOffset    =   0x228,
+  DAC960_GEM_InterruptStatusRegisterOffset          =   0x208,
+  DAC960_GEM_InterruptMaskRegisterReadSetOffset     =   0x22C,
+  DAC960_GEM_InterruptMaskRegisterClearOffset       =   0x230,
+  DAC960_GEM_CommandMailboxBusAddressOffset         =   0x510,
+  DAC960_GEM_CommandStatusOffset                    =   0x518,
+  DAC960_GEM_ErrorStatusRegisterReadSetOffset       =   0x224,
+  DAC960_GEM_ErrorStatusRegisterClearOffset         =   0x228,
+}
+DAC960_GEM_RegisterOffsets_T;
+
+/*
+  Define the structure of the DAC960 GEM Series Inbound Door Bell
+ */
+
+typedef union DAC960_GEM_InboundDoorBellRegister
+{
+  unsigned int All;
+  struct {
+    unsigned int :24;
+    boolean HardwareMailboxNewCommand:1;
+    boolean AcknowledgeHardwareMailboxStatus:1;
+    boolean GenerateInterrupt:1;
+    boolean ControllerReset:1;
+    boolean MemoryMailboxNewCommand:1;
+    unsigned int :3;
+  } Write;
+  struct {
+    unsigned int :24;
+    boolean HardwareMailboxFull:1;
+    boolean InitializationInProgress:1;
+    unsigned int :6;
+  } Read;
+}
+DAC960_GEM_InboundDoorBellRegister_T;
+
+/*
+  Define the structure of the DAC960 GEM Series Outbound Door Bell Register.
+ */
+typedef union DAC960_GEM_OutboundDoorBellRegister
+{
+  unsigned int All;
+  struct {
+    unsigned int :24;
+    boolean AcknowledgeHardwareMailboxInterrupt:1;
+    boolean AcknowledgeMemoryMailboxInterrupt:1;
+    unsigned int :6;
+  } Write;
+  struct {
+    unsigned int :24;
+    boolean HardwareMailboxStatusAvailable:1;
+    boolean MemoryMailboxStatusAvailable:1;
+    unsigned int :6;
+  } Read;
+}
+DAC960_GEM_OutboundDoorBellRegister_T;
+
+/*
+  Define the structure of the DAC960 GEM Series Interrupt Mask Register.
+ */
+typedef union DAC960_GEM_InterruptMaskRegister
+{
+  unsigned int All;
+  struct {
+    unsigned int :16;
+    unsigned int :8;
+    unsigned int HardwareMailboxInterrupt:1;
+    unsigned int MemoryMailboxInterrupt:1;
+    unsigned int :6;
+  } Bits;
+}
+DAC960_GEM_InterruptMaskRegister_T;
+
+/*
+  Define the structure of the DAC960 GEM Series Error Status Register.
+ */
+
+typedef union DAC960_GEM_ErrorStatusRegister
+{
+  unsigned int All;
+  struct {
+    unsigned int :24;
+    unsigned int :5;
+    boolean ErrorStatusPending:1;
+    unsigned int :2;
+  } Bits;
+}
+DAC960_GEM_ErrorStatusRegister_T;
+
+/*
+  Define inline functions to provide an abstraction for reading and writing the
+  DAC960 GEM Series Controller Interface Registers.
+*/
+
+static inline
+void DAC960_GEM_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
+  writel(InboundDoorBellRegister.All,
+        ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+}
+
+static inline
+void DAC960_GEM_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
+  writel(InboundDoorBellRegister.All,
+        ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterClearOffset);
+}
+
+static inline
+void DAC960_GEM_GenerateInterrupt(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.GenerateInterrupt = true;
+  writel(InboundDoorBellRegister.All,
+        ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+}
+
+static inline
+void DAC960_GEM_ControllerReset(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.ControllerReset = true;
+  writel(InboundDoorBellRegister.All,
+        ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+}
+
+static inline
+void DAC960_GEM_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
+  writel(InboundDoorBellRegister.All,
+        ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+}
+
+static inline
+boolean DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readl(ControllerBaseAddress +
+          DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+  return InboundDoorBellRegister.Read.HardwareMailboxFull;
+}
+
+static inline
+boolean DAC960_GEM_InitializationInProgressP(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readl(ControllerBaseAddress +
+          DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
+  return InboundDoorBellRegister.Read.InitializationInProgress;
+}
+
+static inline
+void DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  writel(OutboundDoorBellRegister.All,
+        ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset);
+}
+
+static inline
+void DAC960_GEM_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writel(OutboundDoorBellRegister.All,
+        ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset);
+}
+
+static inline
+void DAC960_GEM_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writel(OutboundDoorBellRegister.All,
+        ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset);
+}
+
+static inline
+boolean DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readl(ControllerBaseAddress +
+          DAC960_GEM_OutboundDoorBellRegisterReadSetOffset);
+  return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
+}
+
+static inline
+boolean DAC960_GEM_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readl(ControllerBaseAddress +
+          DAC960_GEM_OutboundDoorBellRegisterReadSetOffset);
+  return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
+}
+
+static inline
+void DAC960_GEM_EnableInterrupts(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0;
+  InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true;
+  InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true;
+  writel(InterruptMaskRegister.All,
+        ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterClearOffset);
+}
+
+static inline
+void DAC960_GEM_DisableInterrupts(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0;
+  InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true;
+  InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true;
+  writel(InterruptMaskRegister.All,
+        ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterReadSetOffset);
+}
+
+static inline
+boolean DAC960_GEM_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
+{
+  DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All =
+    readl(ControllerBaseAddress +
+          DAC960_GEM_InterruptMaskRegisterReadSetOffset);
+  return !(InterruptMaskRegister.Bits.HardwareMailboxInterrupt ||
+           InterruptMaskRegister.Bits.MemoryMailboxInterrupt);
+}
+
+static inline
+void DAC960_GEM_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
+                                    *MemoryCommandMailbox,
+                                  DAC960_V2_CommandMailbox_T
+                                    *CommandMailbox)
+{
+  memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
+        sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
+  wmb();
+  MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
+  mb();
+}
+
+static inline
+void DAC960_GEM_WriteHardwareMailbox(void __iomem *ControllerBaseAddress,
+                                   dma_addr_t CommandMailboxDMA)
+{
+       dma_addr_writeql(CommandMailboxDMA,
+               ControllerBaseAddress +
+               DAC960_GEM_CommandMailboxBusAddressOffset);
+}
+
+static inline DAC960_V2_CommandIdentifier_T
+DAC960_GEM_ReadCommandIdentifier(void __iomem *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset);
+}
+
+static inline DAC960_V2_CommandStatus_T
+DAC960_GEM_ReadCommandStatus(void __iomem *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset + 2);
+}
+
+static inline boolean
+DAC960_GEM_ReadErrorStatus(void __iomem *ControllerBaseAddress,
+                         unsigned char *ErrorStatus,
+                         unsigned char *Parameter0,
+                         unsigned char *Parameter1)
+{
+  DAC960_GEM_ErrorStatusRegister_T ErrorStatusRegister;
+  ErrorStatusRegister.All =
+    readl(ControllerBaseAddress + DAC960_GEM_ErrorStatusRegisterReadSetOffset);
+  if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
+  ErrorStatusRegister.Bits.ErrorStatusPending = false;
+  *ErrorStatus = ErrorStatusRegister.All;
+  *Parameter0 =
+    readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 0);
+  *Parameter1 =
+    readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 1);
+  writel(0x03000000, ControllerBaseAddress +
+         DAC960_GEM_ErrorStatusRegisterClearOffset);
+  return true;
+}
+
 /*
   Define the DAC960 BA Series Controller Interface Register Offsets.
 */
index e43e02328968728a5f9da232f69ea1ed2edc5770..b594768b0241f3d198d802ada4d192b356677310 100644 (file)
@@ -105,7 +105,7 @@ config ATARI_SLM
 
 config BLK_DEV_XD
        tristate "XT hard disk support"
-       depends on ISA
+       depends on ISA && ISA_DMA_API
        help
          Very old 8 bit hard disk controllers used in the IBM XT computer
          will be supported if you say Y here.
index aa8b547ffafa669f7cd3d547e4ac025203d799af..721ba8086043bd714c06e5353f60a348e7989f50 100644 (file)
@@ -1,5 +1,5 @@
 /* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
-#define VERSION "6"
+#define VERSION "10"
 #define AOE_MAJOR 152
 #define DEVICE_NAME "aoe"
 
index 4780f7926d4292bc8150e2712ea18d8a11204ec2..0e97fcb9f3a15b3bbe5b4a0bb8bd085c20e05b2b 100644 (file)
@@ -37,6 +37,13 @@ static ssize_t aoedisk_show_netif(struct gendisk * disk, char *page)
 
        return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name);
 }
+/* firmware version */
+static ssize_t aoedisk_show_fwver(struct gendisk * disk, char *page)
+{
+       struct aoedev *d = disk->private_data;
+
+       return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver);
+}
 
 static struct disk_attribute disk_attr_state = {
        .attr = {.name = "state", .mode = S_IRUGO },
@@ -50,6 +57,10 @@ static struct disk_attribute disk_attr_netif = {
        .attr = {.name = "netif", .mode = S_IRUGO },
        .show = aoedisk_show_netif
 };
+static struct disk_attribute disk_attr_fwver = {
+       .attr = {.name = "firmware-version", .mode = S_IRUGO },
+       .show = aoedisk_show_fwver
+};
 
 static void
 aoedisk_add_sysfs(struct aoedev *d)
@@ -57,6 +68,7 @@ aoedisk_add_sysfs(struct aoedev *d)
        sysfs_create_file(&d->gd->kobj, &disk_attr_state.attr);
        sysfs_create_file(&d->gd->kobj, &disk_attr_mac.attr);
        sysfs_create_file(&d->gd->kobj, &disk_attr_netif.attr);
+       sysfs_create_file(&d->gd->kobj, &disk_attr_fwver.attr);
 }
 void
 aoedisk_rm_sysfs(struct aoedev *d)
@@ -64,6 +76,7 @@ aoedisk_rm_sysfs(struct aoedev *d)
        sysfs_remove_link(&d->gd->kobj, "state");
        sysfs_remove_link(&d->gd->kobj, "mac");
        sysfs_remove_link(&d->gd->kobj, "netif");
+       sysfs_remove_link(&d->gd->kobj, "firmware-version");
 }
 
 static int
index ec16c64dd114c37b30f2f97bb5e8f895c0a6e9bb..6e231c5a119958dd3549e5d825f4706f9d04f9ec 100644 (file)
@@ -109,25 +109,22 @@ aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bu
        spin_lock_irqsave(&devlist_lock, flags);
 
        for (d=devlist; d; d=d->next)
-               if (d->sysminor == sysminor
-               || memcmp(d->addr, addr, sizeof d->addr) == 0)
+               if (d->sysminor == sysminor)
                        break;
 
        if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) {
                spin_unlock_irqrestore(&devlist_lock, flags);
                printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
                return NULL;
-       }
+       } /* if newdev, (d->flags & DEVFL_UP) == 0 for below */
 
        spin_unlock_irqrestore(&devlist_lock, flags);
        spin_lock_irqsave(&d->lock, flags);
 
        d->ifp = ifp;
-
-       if (d->sysminor != sysminor
-       || (d->flags & DEVFL_UP) == 0) {
+       memcpy(d->addr, addr, sizeof d->addr);
+       if ((d->flags & DEVFL_UP) == 0) {
                aoedev_downdev(d); /* flushes outstanding frames */
-               memcpy(d->addr, addr, sizeof d->addr);
                d->sysminor = sysminor;
                d->aoemajor = AOEMAJOR(sysminor);
                d->aoeminor = AOEMINOR(sysminor);
index bc92aacb6dadad9f2bff4145d237acd35856526d..9e6f51c528b094684c2b709c55be738c3d361225 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/hdreg.h>
 #include <linux/blkdev.h>
 #include <linux/netdevice.h>
+#include <linux/moduleparam.h>
 #include "aoe.h"
 
 #define NECODES 5
@@ -26,6 +27,19 @@ enum {
 };
 
 static char aoe_iflist[IFLISTSZ];
+module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600);
+MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\"\n");
+
+#ifndef MODULE
+static int __init aoe_iflist_setup(char *str)
+{
+       strncpy(aoe_iflist, str, IFLISTSZ);
+       aoe_iflist[IFLISTSZ - 1] = '\0';
+       return 1;
+}
+
+__setup("aoe_iflist=", aoe_iflist_setup);
+#endif
 
 int
 is_aoe_netif(struct net_device *ifp)
@@ -36,7 +50,8 @@ is_aoe_netif(struct net_device *ifp)
        if (aoe_iflist[0] == '\0')
                return 1;
 
-       for (p = aoe_iflist; *p; p = q + strspn(q, WHITESPACE)) {
+       p = aoe_iflist + strspn(aoe_iflist, WHITESPACE);
+       for (; *p; p = q + strspn(q, WHITESPACE)) {
                q = p + strcspn(p, WHITESPACE);
                if (q != p)
                        len = q - p;
index 42dfa281a880f684ba6b187cbb57712f752e6afe..f0c1084b840fd9fceb465521b1bb8cbbc7198529 100644 (file)
@@ -3345,7 +3345,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
                        struct block_device *bdev = opened_bdev[cnt];
                        if (!bdev || ITYPE(drive_state[cnt].fd_device) != type)
                                continue;
-                       __invalidate_device(bdev, 0);
+                       __invalidate_device(bdev);
                }
                up(&open_lock);
        } else {
index ab4db71375e08e41c13e4049efe1cd3cef5cbc8a..8bbe01d4b487cf5c9a03b474e8ffd2e57bbf1e8f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/kobj_map.h>
+#include <linux/buffer_head.h>
 
 #define MAX_PROBE_HASH 255     /* random */
 
@@ -676,7 +677,8 @@ int invalidate_partition(struct gendisk *disk, int index)
        int res = 0;
        struct block_device *bdev = bdget_disk(disk, index);
        if (bdev) {
-               res = __invalidate_device(bdev, 1);
+               fsync_bdev(bdev);
+               res = __invalidate_device(bdev);
                bdput(bdev);
        }
        return res;
index 5e03f5157ef93b2d2b3bc447a36ceba566a2336d..6d7bcc9da9e72f806d0c3fe77aacca8c1ec896e3 100644 (file)
@@ -237,3 +237,5 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
        }
        return ret;
 }
+
+EXPORT_SYMBOL_GPL(blkdev_ioctl);
index 1a1fa3ccb91375031556815e71fa858cdc48ab60..bc56770bcc90889338810134bba163530e9f72d1 100644 (file)
@@ -914,8 +914,10 @@ static int pkt_handle_queue(struct pktcdvd_device *pd)
                bio = node->bio;
                zone = ZONE(bio->bi_sector, pd);
                list_for_each_entry(p, &pd->cdrw.pkt_active_list, list) {
-                       if (p->sector == zone)
+                       if (p->sector == zone) {
+                               bio = NULL;
                                goto try_next_bio;
+                       }
                }
                break;
 try_next_bio:
@@ -2019,7 +2021,13 @@ static int pkt_open(struct inode *inode, struct file *file)
        BUG_ON(pd->refcnt < 0);
 
        pd->refcnt++;
-       if (pd->refcnt == 1) {
+       if (pd->refcnt > 1) {
+               if ((file->f_mode & FMODE_WRITE) &&
+                   !test_bit(PACKET_WRITABLE, &pd->flags)) {
+                       ret = -EBUSY;
+                       goto out_dec;
+               }
+       } else {
                if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) {
                        ret = -EIO;
                        goto out_dec;
@@ -2406,7 +2414,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
        case CDROM_LAST_WRITTEN:
        case CDROM_SEND_PACKET:
        case SCSI_IOCTL_SEND_COMMAND:
-               return ioctl_by_bdev(pd->bdev, cmd, arg);
+               return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
 
        case CDROMEJECT:
                /*
@@ -2414,7 +2422,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                 * have to unlock it or else the eject command fails.
                 */
                pkt_lock_door(pd, 0);
-               return ioctl_by_bdev(pd->bdev, cmd, arg);
+               return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
 
        default:
                printk("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd);
index ce42889f98fbdac287a2af1d50a8c66346a5433a..19c5e59bcfa826966d433c2edd6f921592a7f40f 100644 (file)
@@ -8,13 +8,12 @@
  * and is not licensed separately. See file COPYING for details.
  *
  * TODO (sorted by decreasing priority)
+ *  -- Kill first_open (Al Viro fixed the block layer now)
  *  -- Do resets with usb_device_reset (needs a thread context, use khubd)
  *  -- set readonly flag for CDs, set removable flag for CF readers
  *  -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
- *  -- support pphaneuf's SDDR-75 with two LUNs (also broken capacity...)
  *  -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
  *  -- verify the 13 conditions and do bulk resets
- *  -- normal pool of commands instead of cmdv[]?
  *  -- kill last_pipe and simply do two-state clearing on both pipes
  *  -- verify protocol (bulk) from USB descriptors (maybe...)
  *  -- highmem and sg
 #define US_SC_SCSI     0x06            /* Transparent */
 
 /*
+ * This many LUNs per USB device.
+ * Every one of them takes a host, see UB_MAX_HOSTS.
  */
+#define UB_MAX_LUNS   9
+
+/*
+ */
+
 #define UB_MINORS_PER_MAJOR    8
 
 #define UB_MAX_CDB_SIZE      16                /* Corresponds to Bulk */
@@ -65,7 +71,7 @@ struct bulk_cb_wrap {
        u32     Tag;                    /* unique per command id */
        __le32  DataTransferLength;     /* size of data */
        u8      Flags;                  /* direction in bit 0 */
-       u8      Lun;                    /* LUN normally 0 */
+       u8      Lun;                    /* LUN */
        u8      Length;                 /* of of the CDB */
        u8      CDB[UB_MAX_CDB_SIZE];   /* max command */
 };
@@ -168,6 +174,7 @@ struct ub_scsi_cmd {
        unsigned int len;               /* Requested length */
        // struct scatterlist sgv[UB_MAX_REQ_SG];
 
+       struct ub_lun *lun;
        void (*done)(struct ub_dev *, struct ub_scsi_cmd *);
        void *back;
 };
@@ -252,25 +259,47 @@ struct ub_scsi_cmd_queue {
 };
 
 /*
- * The UB device instance.
+ * The block device instance (one per LUN).
+ */
+struct ub_lun {
+       struct ub_dev *udev;
+       struct list_head link;
+       struct gendisk *disk;
+       int id;                         /* Host index */
+       int num;                        /* LUN number */
+       char name[16];
+
+       int changed;                    /* Media was changed */
+       int removable;
+       int readonly;
+       int first_open;                 /* Kludge. See ub_bd_open. */
+
+       /* Use Ingo's mempool if or when we have more than one command. */
+       /*
+        * Currently we never need more than one command for the whole device.
+        * However, giving every LUN a command is a cheap and automatic way
+        * to enforce fairness between them.
+        */
+       int cmda[1];
+       struct ub_scsi_cmd cmdv[1];
+
+       struct ub_capacity capacity; 
+};
+
+/*
+ * The USB device instance.
  */
 struct ub_dev {
        spinlock_t lock;
-       int id;                         /* Number among ub's */
        atomic_t poison;                /* The USB device is disconnected */
        int openc;                      /* protected by ub_lock! */
                                        /* kref is too implicit for our taste */
        unsigned int tagcnt;
-       int changed;                    /* Media was changed */
-       int removable;
-       int readonly;
-       int first_open;                 /* Kludge. See ub_bd_open. */
-       char name[8];
+       char name[12];
        struct usb_device *dev;
        struct usb_interface *intf;
 
-       struct ub_capacity capacity; 
-       struct gendisk *disk;
+       struct list_head luns;
 
        unsigned int send_bulk_pipe;    /* cached pipe values */
        unsigned int recv_bulk_pipe;
@@ -279,10 +308,6 @@ struct ub_dev {
 
        struct tasklet_struct tasklet;
 
-       /* XXX Use Ingo's mempool (once we have more than one) */
-       int cmda[1];
-       struct ub_scsi_cmd cmdv[1];
-
        struct ub_scsi_cmd_queue cmd_queue;
        struct ub_scsi_cmd top_rqs_cmd; /* REQUEST SENSE */
        unsigned char top_sense[UB_SENSE_SIZE];
@@ -301,9 +326,9 @@ struct ub_dev {
 /*
  */
 static void ub_cleanup(struct ub_dev *sc);
-static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq);
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
-    struct request *rq);
+static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq);
+static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct request *rq);
 static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
     struct request *rq);
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -320,8 +345,10 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
     int stalled_pipe);
 static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
-static int ub_sync_tur(struct ub_dev *sc);
-static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret);
+static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
+static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_capacity *ret);
+static int ub_probe_lun(struct ub_dev *sc, int lnum);
 
 /*
  */
@@ -342,6 +369,7 @@ MODULE_DEVICE_TABLE(usb, ub_usb_ids);
  */
 #define UB_MAX_HOSTS  26
 static char ub_hostv[UB_MAX_HOSTS];
+
 static DEFINE_SPINLOCK(ub_lock);       /* Locks globals and ->openc */
 
 /*
@@ -406,6 +434,8 @@ static ssize_t ub_diag_show(struct device *dev, char *page)
 {
        struct usb_interface *intf;
        struct ub_dev *sc;
+       struct list_head *p;
+       struct ub_lun *lun;
        int cnt;
        unsigned long flags;
        int nc, nh;
@@ -421,9 +451,15 @@ static ssize_t ub_diag_show(struct device *dev, char *page)
        spin_lock_irqsave(&sc->lock, flags);
 
        cnt += sprintf(page + cnt,
-           "qlen %d qmax %d changed %d removable %d readonly %d\n",
-           sc->cmd_queue.qlen, sc->cmd_queue.qmax,
-           sc->changed, sc->removable, sc->readonly);
+           "qlen %d qmax %d\n",
+           sc->cmd_queue.qlen, sc->cmd_queue.qmax);
+
+       list_for_each (p, &sc->luns) {
+               lun = list_entry(p, struct ub_lun, link);
+               cnt += sprintf(page + cnt,
+                   "lun %u changed %d removable %d readonly %d\n",
+                   lun->num, lun->changed, lun->removable, lun->readonly);
+       }
 
        if ((nc = sc->tr.cur + 1) == SCMD_TRACE_SZ) nc = 0;
        for (j = 0; j < SCMD_TRACE_SZ; j++) {
@@ -523,53 +559,63 @@ static void ub_put(struct ub_dev *sc)
  */
 static void ub_cleanup(struct ub_dev *sc)
 {
+       struct list_head *p;
+       struct ub_lun *lun;
        request_queue_t *q;
 
-       /* I don't think queue can be NULL. But... Stolen from sx8.c */
-       if ((q = sc->disk->queue) != NULL)
-               blk_cleanup_queue(q);
+       while (!list_empty(&sc->luns)) {
+               p = sc->luns.next;
+               lun = list_entry(p, struct ub_lun, link);
+               list_del(p);
 
-       /*
-        * If we zero disk->private_data BEFORE put_disk, we have to check
-        * for NULL all over the place in open, release, check_media and
-        * revalidate, because the block level semaphore is well inside the
-        * put_disk. But we cannot zero after the call, because *disk is gone.
-        * The sd.c is blatantly racy in this area.
-        */
-       /* disk->private_data = NULL; */
-       put_disk(sc->disk);
-       sc->disk = NULL;
+               /* I don't think queue can be NULL. But... Stolen from sx8.c */
+               if ((q = lun->disk->queue) != NULL)
+                       blk_cleanup_queue(q);
+               /*
+                * If we zero disk->private_data BEFORE put_disk, we have
+                * to check for NULL all over the place in open, release,
+                * check_media and revalidate, because the block level
+                * semaphore is well inside the put_disk.
+                * But we cannot zero after the call, because *disk is gone.
+                * The sd.c is blatantly racy in this area.
+                */
+               /* disk->private_data = NULL; */
+               put_disk(lun->disk);
+               lun->disk = NULL;
+
+               ub_id_put(lun->id);
+               kfree(lun);
+       }
 
-       ub_id_put(sc->id);
        kfree(sc);
 }
 
 /*
  * The "command allocator".
  */
-static struct ub_scsi_cmd *ub_get_cmd(struct ub_dev *sc)
+static struct ub_scsi_cmd *ub_get_cmd(struct ub_lun *lun)
 {
        struct ub_scsi_cmd *ret;
 
-       if (sc->cmda[0])
+       if (lun->cmda[0])
                return NULL;
-       ret = &sc->cmdv[0];
-       sc->cmda[0] = 1;
+       ret = &lun->cmdv[0];
+       lun->cmda[0] = 1;
        return ret;
 }
 
-static void ub_put_cmd(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
+static void ub_put_cmd(struct ub_lun *lun, struct ub_scsi_cmd *cmd)
 {
-       if (cmd != &sc->cmdv[0]) {
+       if (cmd != &lun->cmdv[0]) {
                printk(KERN_WARNING "%s: releasing a foreign cmd %p\n",
-                   sc->name, cmd);
+                   lun->name, cmd);
                return;
        }
-       if (!sc->cmda[0]) {
-               printk(KERN_WARNING "%s: releasing a free cmd\n", sc->name);
+       if (!lun->cmda[0]) {
+               printk(KERN_WARNING "%s: releasing a free cmd\n", lun->name);
                return;
        }
-       sc->cmda[0] = 0;
+       lun->cmda[0] = 0;
 }
 
 /*
@@ -630,29 +676,30 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc)
 
 static void ub_bd_rq_fn(request_queue_t *q)
 {
-       struct ub_dev *sc = q->queuedata;
+       struct ub_lun *lun = q->queuedata;
        struct request *rq;
 
        while ((rq = elv_next_request(q)) != NULL) {
-               if (ub_bd_rq_fn_1(sc, rq) != 0) {
+               if (ub_bd_rq_fn_1(lun, rq) != 0) {
                        blk_stop_queue(q);
                        break;
                }
        }
 }
 
-static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq)
+static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
 {
+       struct ub_dev *sc = lun->udev;
        struct ub_scsi_cmd *cmd;
        int rc;
 
-       if (atomic_read(&sc->poison) || sc->changed) {
+       if (atomic_read(&sc->poison) || lun->changed) {
                blkdev_dequeue_request(rq);
                ub_end_rq(rq, 0);
                return 0;
        }
 
-       if ((cmd = ub_get_cmd(sc)) == NULL)
+       if ((cmd = ub_get_cmd(lun)) == NULL)
                return -1;
        memset(cmd, 0, sizeof(struct ub_scsi_cmd));
 
@@ -661,32 +708,30 @@ static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq)
        if (blk_pc_request(rq)) {
                rc = ub_cmd_build_packet(sc, cmd, rq);
        } else {
-               rc = ub_cmd_build_block(sc, cmd, rq);
+               rc = ub_cmd_build_block(sc, lun, cmd, rq);
        }
        if (rc != 0) {
-               ub_put_cmd(sc, cmd);
+               ub_put_cmd(lun, cmd);
                ub_end_rq(rq, 0);
-               blk_start_queue(sc->disk->queue);
                return 0;
        }
-
        cmd->state = UB_CMDST_INIT;
+       cmd->lun = lun;
        cmd->done = ub_rw_cmd_done;
        cmd->back = rq;
 
        cmd->tag = sc->tagcnt++;
        if ((rc = ub_submit_scsi(sc, cmd)) != 0) {
-               ub_put_cmd(sc, cmd);
+               ub_put_cmd(lun, cmd);
                ub_end_rq(rq, 0);
-               blk_start_queue(sc->disk->queue);
                return 0;
        }
 
        return 0;
 }
 
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
-    struct request *rq)
+static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct request *rq)
 {
        int ub_dir;
 #if 0 /* We use rq->buffer for now */
@@ -707,7 +752,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
        sg = &cmd->sgv[0];
        n_elem = blk_rq_map_sg(q, rq, sg);
        if (n_elem <= 0) {
-               ub_put_cmd(sc, cmd);
+               ub_put_cmd(lun, cmd);
                ub_end_rq(rq, 0);
                blk_start_queue(q);
                return 0;               /* request with no s/g entries? */
@@ -716,7 +761,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
        if (n_elem != 1) {              /* Paranoia */
                printk(KERN_WARNING "%s: request with %d segments\n",
                    sc->name, n_elem);
-               ub_put_cmd(sc, cmd);
+               ub_put_cmd(lun, cmd);
                ub_end_rq(rq, 0);
                blk_start_queue(q);
                return 0;
@@ -748,8 +793,8 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
         * The call to blk_queue_hardsect_size() guarantees that request
         * is aligned, but it is given in terms of 512 byte units, always.
         */
-       block = rq->sector >> sc->capacity.bshift;
-       nblks = rq->nr_sectors >> sc->capacity.bshift;
+       block = rq->sector >> lun->capacity.bshift;
+       nblks = rq->nr_sectors >> lun->capacity.bshift;
 
        cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10;
        /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */
@@ -803,7 +848,8 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
        struct request *rq = cmd->back;
-       struct gendisk *disk = sc->disk;
+       struct ub_lun *lun = cmd->lun;
+       struct gendisk *disk = lun->disk;
        request_queue_t *q = disk->queue;
        int uptodate;
 
@@ -818,7 +864,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        else
                uptodate = 0;
 
-       ub_put_cmd(sc, cmd);
+       ub_put_cmd(lun, cmd);
        ub_end_rq(rq, uptodate);
        blk_start_queue(q);
 }
@@ -887,7 +933,7 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        bcb->Tag = cmd->tag;            /* Endianness is not important */
        bcb->DataTransferLength = cpu_to_le32(cmd->len);
        bcb->Flags = (cmd->dir == UB_DIR_READ) ? 0x80 : 0;
-       bcb->Lun = 0;                   /* No multi-LUN yet */
+       bcb->Lun = (cmd->lun != NULL) ? cmd->lun->num : 0;
        bcb->Length = cmd->cdb_len;
 
        /* copy the command payload */
@@ -1002,9 +1048,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                         * The control pipe clears itself - nothing to do.
                         * XXX Might try to reset the device here and retry.
                         */
-                       printk(KERN_NOTICE "%s: "
-                           "stall on control pipe for device %u\n",
-                           sc->name, sc->dev->devnum);
+                       printk(KERN_NOTICE "%s: stall on control pipe\n",
+                           sc->name);
                        goto Bad_End;
                }
 
@@ -1025,9 +1070,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                         * The control pipe clears itself - nothing to do.
                         * XXX Might try to reset the device here and retry.
                         */
-                       printk(KERN_NOTICE "%s: "
-                           "stall on control pipe for device %u\n",
-                           sc->name, sc->dev->devnum);
+                       printk(KERN_NOTICE "%s: stall on control pipe\n",
+                           sc->name);
                        goto Bad_End;
                }
 
@@ -1046,9 +1090,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
                        if (rc != 0) {
                                printk(KERN_NOTICE "%s: "
-                                   "unable to submit clear for device %u"
-                                   " (code %d)\n",
-                                   sc->name, sc->dev->devnum, rc);
+                                   "unable to submit clear (%d)\n",
+                                   sc->name, rc);
                                /*
                                 * This is typically ENOMEM or some other such shit.
                                 * Retrying is pointless. Just do Bad End on it...
@@ -1107,9 +1150,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
                        if (rc != 0) {
                                printk(KERN_NOTICE "%s: "
-                                   "unable to submit clear for device %u"
-                                   " (code %d)\n",
-                                   sc->name, sc->dev->devnum, rc);
+                                   "unable to submit clear (%d)\n",
+                                   sc->name, rc);
                                /*
                                 * This is typically ENOMEM or some other such shit.
                                 * Retrying is pointless. Just do Bad End on it...
@@ -1140,9 +1182,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
                        if (rc != 0) {
                                printk(KERN_NOTICE "%s: "
-                                   "unable to submit clear for device %u"
-                                   " (code %d)\n",
-                                   sc->name, sc->dev->devnum, rc);
+                                   "unable to submit clear (%d)\n",
+                                   sc->name, rc);
                                /*
                                 * This is typically ENOMEM or some other such shit.
                                 * Retrying is pointless. Just do Bad End on it...
@@ -1164,9 +1205,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                         * encounter such a thing, try to read the CSW again.
                         */
                        if (++cmd->stat_count >= 4) {
-                               printk(KERN_NOTICE "%s: "
-                                   "unable to get CSW on device %u\n",
-                                   sc->name, sc->dev->devnum);
+                               printk(KERN_NOTICE "%s: unable to get CSW\n",
+                                   sc->name);
                                goto Bad_End;
                        }
                        __ub_state_stat(sc, cmd);
@@ -1207,10 +1247,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                         */
                        if (++cmd->stat_count >= 4) {
                                printk(KERN_NOTICE "%s: "
-                                   "tag mismatch orig 0x%x reply 0x%x "
-                                   "on device %u\n",
-                                   sc->name, cmd->tag, bcs->Tag,
-                                   sc->dev->devnum);
+                                   "tag mismatch orig 0x%x reply 0x%x\n",
+                                   sc->name, cmd->tag, bcs->Tag);
                                goto Bad_End;
                        }
                        __ub_state_stat(sc, cmd);
@@ -1244,8 +1282,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 
        } else {
                printk(KERN_WARNING "%s: "
-                   "wrong command state %d on device %u\n",
-                   sc->name, cmd->state, sc->dev->devnum);
+                   "wrong command state %d\n",
+                   sc->name, cmd->state);
                goto Bad_End;
        }
        return;
@@ -1288,7 +1326,6 @@ static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 
        if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
                /* XXX Clear stalls */
-               printk("%s: CSW #%d submit failed (%d)\n", sc->name, cmd->tag, rc); /* P3 */
                ub_complete(&sc->work_done);
                ub_state_done(sc, cmd, rc);
                return;
@@ -1333,6 +1370,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        scmd->state = UB_CMDST_INIT;
        scmd->data = sc->top_sense;
        scmd->len = UB_SENSE_SIZE;
+       scmd->lun = cmd->lun;
        scmd->done = ub_top_sense_done;
        scmd->back = cmd;
 
@@ -1411,14 +1449,14 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
        }
        if (cmd != scmd->back) {
                printk(KERN_WARNING "%s: "
-                   "sense done for wrong command 0x%x on device %u\n",
-                   sc->name, cmd->tag, sc->dev->devnum);
+                   "sense done for wrong command 0x%x\n",
+                   sc->name, cmd->tag);
                return;
        }
        if (cmd->state != UB_CMDST_SENSE) {
                printk(KERN_WARNING "%s: "
-                   "sense done with bad cmd state %d on device %u\n",
-                   sc->name, cmd->state, sc->dev->devnum);
+                   "sense done with bad cmd state %d\n",
+                   sc->name, cmd->state);
                return;
        }
 
@@ -1429,68 +1467,32 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
        ub_scsi_urb_compl(sc, cmd);
 }
 
-#if 0
-/* Determine what the maximum LUN supported is */
-int usb_stor_Bulk_max_lun(struct us_data *us)
-{
-       int result;
-
-       /* issue the command */
-       result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
-                                US_BULK_GET_MAX_LUN, 
-                                USB_DIR_IN | USB_TYPE_CLASS | 
-                                USB_RECIP_INTERFACE,
-                                0, us->ifnum, us->iobuf, 1, HZ);
-
-       /* 
-        * Some devices (i.e. Iomega Zip100) need this -- apparently
-        * the bulk pipes get STALLed when the GetMaxLUN request is
-        * processed.   This is, in theory, harmless to all other devices
-        * (regardless of if they stall or not).
-        */
-       if (result < 0) {
-               usb_stor_clear_halt(us, us->recv_bulk_pipe);
-               usb_stor_clear_halt(us, us->send_bulk_pipe);
-       }
-
-       US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", 
-                 result, us->iobuf[0]);
-
-       /* if we have a successful request, return the result */
-       if (result == 1)
-               return us->iobuf[0];
-
-       /* return the default -- no LUNs */
-       return 0;
-}
-#endif
-
 /*
  * This is called from a process context.
  */
-static void ub_revalidate(struct ub_dev *sc)
+static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun)
 {
 
-       sc->readonly = 0;       /* XXX Query this from the device */
+       lun->readonly = 0;      /* XXX Query this from the device */
 
-       sc->capacity.nsec = 0;
-       sc->capacity.bsize = 512;
-       sc->capacity.bshift = 0;
+       lun->capacity.nsec = 0;
+       lun->capacity.bsize = 512;
+       lun->capacity.bshift = 0;
 
-       if (ub_sync_tur(sc) != 0)
+       if (ub_sync_tur(sc, lun) != 0)
                return;                 /* Not ready */
-       sc->changed = 0;
+       lun->changed = 0;
 
-       if (ub_sync_read_cap(sc, &sc->capacity) != 0) {
+       if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) {
                /*
                 * The retry here means something is wrong, either with the
                 * device, with the transport, or with our code.
                 * We keep this because sd.c has retries for capacity.
                 */
-               if (ub_sync_read_cap(sc, &sc->capacity) != 0) {
-                       sc->capacity.nsec = 0;
-                       sc->capacity.bsize = 512;
-                       sc->capacity.bshift = 0;
+               if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) {
+                       lun->capacity.nsec = 0;
+                       lun->capacity.bsize = 512;
+                       lun->capacity.bshift = 0;
                }
        }
 }
@@ -1503,12 +1505,15 @@ static void ub_revalidate(struct ub_dev *sc)
 static int ub_bd_open(struct inode *inode, struct file *filp)
 {
        struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct ub_lun *lun;
        struct ub_dev *sc;
        unsigned long flags;
        int rc;
 
-       if ((sc = disk->private_data) == NULL)
+       if ((lun = disk->private_data) == NULL)
                return -ENXIO;
+       sc = lun->udev;
+
        spin_lock_irqsave(&ub_lock, flags);
        if (atomic_read(&sc->poison)) {
                spin_unlock_irqrestore(&ub_lock, flags);
@@ -1529,15 +1534,15 @@ static int ub_bd_open(struct inode *inode, struct file *filp)
         * The bottom line is, Al Viro says that we should not allow
         * bdev->bd_invalidated to be set when doing add_disk no matter what.
         */
-       if (sc->first_open) {
-               if (sc->changed) {
-                       sc->first_open = 0;
+       if (lun->first_open) {
+               lun->first_open = 0;
+               if (lun->changed) {
                        rc = -ENOMEDIUM;
                        goto err_open;
                }
        }
 
-       if (sc->removable || sc->readonly)
+       if (lun->removable || lun->readonly)
                check_disk_change(inode->i_bdev);
 
        /*
@@ -1545,12 +1550,12 @@ static int ub_bd_open(struct inode *inode, struct file *filp)
         * under some pretty murky conditions (a failure of READ CAPACITY).
         * We may need it one day.
         */
-       if (sc->removable && sc->changed && !(filp->f_flags & O_NDELAY)) {
+       if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) {
                rc = -ENOMEDIUM;
                goto err_open;
        }
 
-       if (sc->readonly && (filp->f_mode & FMODE_WRITE)) {
+       if (lun->readonly && (filp->f_mode & FMODE_WRITE)) {
                rc = -EROFS;
                goto err_open;
        }
@@ -1567,7 +1572,8 @@ err_open:
 static int ub_bd_release(struct inode *inode, struct file *filp)
 {
        struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ub_dev *sc = disk->private_data;
+       struct ub_lun *lun = disk->private_data;
+       struct ub_dev *sc = lun->udev;
 
        ub_put(sc);
        return 0;
@@ -1597,20 +1603,14 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp,
  */
 static int ub_bd_revalidate(struct gendisk *disk)
 {
-       struct ub_dev *sc = disk->private_data;
-
-       ub_revalidate(sc);
-       /* This is pretty much a long term P3 */
-       if (!atomic_read(&sc->poison)) {                /* Cover sc->dev */
-               printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n",
-                   sc->name, sc->dev->devnum,
-                   sc->capacity.nsec, sc->capacity.bsize);
-       }
+       struct ub_lun *lun = disk->private_data;
+
+       ub_revalidate(lun->udev, lun);
 
        /* XXX Support sector size switching like in sr.c */
-       blk_queue_hardsect_size(disk->queue, sc->capacity.bsize);
-       set_capacity(disk, sc->capacity.nsec);
-       // set_disk_ro(sdkp->disk, sc->readonly);
+       blk_queue_hardsect_size(disk->queue, lun->capacity.bsize);
+       set_capacity(disk, lun->capacity.nsec);
+       // set_disk_ro(sdkp->disk, lun->readonly);
 
        return 0;
 }
@@ -1626,9 +1626,9 @@ static int ub_bd_revalidate(struct gendisk *disk)
  */
 static int ub_bd_media_changed(struct gendisk *disk)
 {
-       struct ub_dev *sc = disk->private_data;
+       struct ub_lun *lun = disk->private_data;
 
-       if (!sc->removable)
+       if (!lun->removable)
                return 0;
 
        /*
@@ -1640,12 +1640,12 @@ static int ub_bd_media_changed(struct gendisk *disk)
         * will fail, then block layer discards the data. Since we never
         * spin drives up, such devices simply cannot be used with ub anyway.
         */
-       if (ub_sync_tur(sc) != 0) {
-               sc->changed = 1;
+       if (ub_sync_tur(lun->udev, lun) != 0) {
+               lun->changed = 1;
                return 1;
        }
 
-       return sc->changed;
+       return lun->changed;
 }
 
 static struct block_device_operations ub_bd_fops = {
@@ -1669,7 +1669,7 @@ static void ub_probe_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 /*
  * Test if the device has a check condition on it, synchronously.
  */
-static int ub_sync_tur(struct ub_dev *sc)
+static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun)
 {
        struct ub_scsi_cmd *cmd;
        enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) };
@@ -1688,6 +1688,7 @@ static int ub_sync_tur(struct ub_dev *sc)
        cmd->cdb_len = 6;
        cmd->dir = UB_DIR_NONE;
        cmd->state = UB_CMDST_INIT;
+       cmd->lun = lun;                 /* This may be NULL, but that's ok */
        cmd->done = ub_probe_done;
        cmd->back = &compl;
 
@@ -1718,7 +1719,8 @@ err_alloc:
 /*
  * Read the SCSI capacity synchronously (for probing).
  */
-static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret)
+static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_capacity *ret)
 {
        struct ub_scsi_cmd *cmd;
        char *p;
@@ -1743,6 +1745,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret)
        cmd->state = UB_CMDST_INIT;
        cmd->data = p;
        cmd->len = 8;
+       cmd->lun = lun;
        cmd->done = ub_probe_done;
        cmd->back = &compl;
 
@@ -1811,6 +1814,90 @@ static void ub_probe_timeout(unsigned long arg)
        complete(cop);
 }
 
+/*
+ * Get number of LUNs by the way of Bulk GetMaxLUN command.
+ */
+static int ub_sync_getmaxlun(struct ub_dev *sc)
+{
+       int ifnum = sc->intf->cur_altsetting->desc.bInterfaceNumber;
+       unsigned char *p;
+       enum { ALLOC_SIZE = 1 };
+       struct usb_ctrlrequest *cr;
+       struct completion compl;
+       struct timer_list timer;
+       int nluns;
+       int rc;
+
+       init_completion(&compl);
+
+       rc = -ENOMEM;
+       if ((p = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
+               goto err_alloc;
+       *p = 55;
+
+       cr = &sc->work_cr;
+       cr->bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+       cr->bRequest = US_BULK_GET_MAX_LUN;
+       cr->wValue = cpu_to_le16(0);
+       cr->wIndex = cpu_to_le16(ifnum);
+       cr->wLength = cpu_to_le16(1);
+
+       usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe,
+           (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl);
+       sc->work_urb.transfer_flags = 0;
+       sc->work_urb.actual_length = 0;
+       sc->work_urb.error_count = 0;
+       sc->work_urb.status = 0;
+
+       if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) {
+               if (rc == -EPIPE) {
+                       printk("%s: Stall at GetMaxLUN, using 1 LUN\n",
+                            sc->name); /* P3 */
+               } else {
+                       printk(KERN_WARNING
+                            "%s: Unable to submit GetMaxLUN (%d)\n",
+                            sc->name, rc);
+               }
+               goto err_submit;
+       }
+
+       init_timer(&timer);
+       timer.function = ub_probe_timeout;
+       timer.data = (unsigned long) &compl;
+       timer.expires = jiffies + UB_CTRL_TIMEOUT;
+       add_timer(&timer);
+
+       wait_for_completion(&compl);
+
+       del_timer_sync(&timer);
+       usb_kill_urb(&sc->work_urb);
+
+       if (sc->work_urb.actual_length != 1) {
+               printk("%s: GetMaxLUN returned %d bytes\n", sc->name,
+                   sc->work_urb.actual_length); /* P3 */
+               nluns = 0;
+       } else {
+               if ((nluns = *p) == 55) {
+                       nluns = 0;
+               } else {
+                       /* GetMaxLUN returns the maximum LUN number */
+                       nluns += 1;
+                       if (nluns > UB_MAX_LUNS)
+                               nluns = UB_MAX_LUNS;
+               }
+               printk("%s: GetMaxLUN returned %d, using %d LUNs\n", sc->name,
+                   *p, nluns); /* P3 */
+       }
+
+       kfree(p);
+       return nluns;
+
+err_submit:
+       kfree(p);
+err_alloc:
+       return rc;
+}
+
 /*
  * Clear initial stalls.
  */
@@ -1897,8 +1984,8 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
        }
 
        if (ep_in == NULL || ep_out == NULL) {
-               printk(KERN_NOTICE "%s: device %u failed endpoint check\n",
-                   sc->name, sc->dev->devnum);
+               printk(KERN_NOTICE "%s: failed endpoint check\n",
+                   sc->name);
                return -EIO;
        }
 
@@ -1921,8 +2008,7 @@ static int ub_probe(struct usb_interface *intf,
     const struct usb_device_id *dev_id)
 {
        struct ub_dev *sc;
-       request_queue_t *q;
-       struct gendisk *disk;
+       int nluns;
        int rc;
        int i;
 
@@ -1931,6 +2017,7 @@ static int ub_probe(struct usb_interface *intf,
                goto err_core;
        memset(sc, 0, sizeof(struct ub_dev));
        spin_lock_init(&sc->lock);
+       INIT_LIST_HEAD(&sc->luns);
        usb_init_urb(&sc->work_urb);
        tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
        atomic_set(&sc->poison, 0);
@@ -1942,19 +2029,16 @@ static int ub_probe(struct usb_interface *intf,
        ub_init_completion(&sc->work_done);
        sc->work_done.done = 1;         /* A little yuk, but oh well... */
 
-       rc = -ENOSR;
-       if ((sc->id = ub_id_get()) == -1)
-               goto err_id;
-       snprintf(sc->name, 8, DRV_NAME "%c", sc->id + 'a');
-
        sc->dev = interface_to_usbdev(intf);
        sc->intf = intf;
        // sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
-
        usb_set_intfdata(intf, sc);
        usb_get_dev(sc->dev);
        // usb_get_intf(sc->intf);      /* Do we need this? */
 
+       snprintf(sc->name, 12, DRV_NAME "(%d.%d)",
+           sc->dev->bus->busnum, sc->dev->devnum);
+
        /* XXX Verify that we can handle the device (from descriptors) */
 
        ub_get_pipes(sc, sc->dev, intf);
@@ -1992,35 +2076,88 @@ static int ub_probe(struct usb_interface *intf,
         * In any case it's not our business how revaliadation is implemented.
         */
        for (i = 0; i < 3; i++) {       /* Retries for benh's key */
-               if ((rc = ub_sync_tur(sc)) <= 0) break;
+               if ((rc = ub_sync_tur(sc, NULL)) <= 0) break;
                if (rc != 0x6) break;
                msleep(10);
        }
 
-       sc->removable = 1;              /* XXX Query this from the device */
-       sc->changed = 1;                /* ub_revalidate clears only */
-       sc->first_open = 1;
+       nluns = 1;
+       for (i = 0; i < 3; i++) {
+               if ((rc = ub_sync_getmaxlun(sc)) < 0) {
+                       /* 
+                        * Some devices (i.e. Iomega Zip100) need this --
+                        * apparently the bulk pipes get STALLed when the
+                        * GetMaxLUN request is processed.
+                        * XXX I have a ZIP-100, verify it does this.
+                        */
+                       if (rc == -EPIPE) {
+                               ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
+                               ub_probe_clear_stall(sc, sc->send_bulk_pipe);
+                       }
+                       break;
+               }
+               if (rc != 0) {
+                       nluns = rc;
+                       break;
+               }
+               msleep(100);
+       }
 
-       ub_revalidate(sc);
-       /* This is pretty much a long term P3 */
-       printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n",
-           sc->name, sc->dev->devnum, sc->capacity.nsec, sc->capacity.bsize);
+       for (i = 0; i < nluns; i++) {
+               ub_probe_lun(sc, i);
+       }
+       return 0;
+
+       /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
+err_diag:
+       usb_set_intfdata(intf, NULL);
+       // usb_put_intf(sc->intf);
+       usb_put_dev(sc->dev);
+       kfree(sc);
+err_core:
+       return rc;
+}
+
+static int ub_probe_lun(struct ub_dev *sc, int lnum)
+{
+       struct ub_lun *lun;
+       request_queue_t *q;
+       struct gendisk *disk;
+       int rc;
+
+       rc = -ENOMEM;
+       if ((lun = kmalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL)
+               goto err_alloc;
+       memset(lun, 0, sizeof(struct ub_lun));
+       lun->num = lnum;
+
+       rc = -ENOSR;
+       if ((lun->id = ub_id_get()) == -1)
+               goto err_id;
+
+       lun->udev = sc;
+       list_add(&lun->link, &sc->luns);
+
+       snprintf(lun->name, 16, DRV_NAME "%c(%d.%d.%d)",
+           lun->id + 'a', sc->dev->bus->busnum, sc->dev->devnum, lun->num);
+
+       lun->removable = 1;             /* XXX Query this from the device */
+       lun->changed = 1;               /* ub_revalidate clears only */
+       lun->first_open = 1;
+       ub_revalidate(sc, lun);
 
-       /*
-        * Just one disk per sc currently, but maybe more.
-        */
        rc = -ENOMEM;
        if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL)
                goto err_diskalloc;
 
-       sc->disk = disk;
-       sprintf(disk->disk_name, DRV_NAME "%c", sc->id + 'a');
-       sprintf(disk->devfs_name, DEVFS_NAME "/%c", sc->id + 'a');
+       lun->disk = disk;
+       sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
+       sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
        disk->major = UB_MAJOR;
-       disk->first_minor = sc->id * UB_MINORS_PER_MAJOR;
+       disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
        disk->fops = &ub_bd_fops;
-       disk->private_data = sc;
-       disk->driverfs_dev = &intf->dev;
+       disk->private_data = lun;
+       disk->driverfs_dev = &sc->intf->dev;    /* XXX Many to one ok? */
 
        rc = -ENOMEM;
        if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL)
@@ -2028,28 +2165,17 @@ static int ub_probe(struct usb_interface *intf,
 
        disk->queue = q;
 
-        // blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
+       blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
        blk_queue_max_hw_segments(q, UB_MAX_REQ_SG);
        blk_queue_max_phys_segments(q, UB_MAX_REQ_SG);
-       // blk_queue_segment_boundary(q, CARM_SG_BOUNDARY);
+       blk_queue_segment_boundary(q, 0xffffffff);      /* Dubious. */
        blk_queue_max_sectors(q, UB_MAX_SECTORS);
-       blk_queue_hardsect_size(q, sc->capacity.bsize);
-
-       /*
-        * This is a serious infraction, caused by a deficiency in the
-        * USB sg interface (usb_sg_wait()). We plan to remove this once
-        * we get mileage on the driver and can justify a change to USB API.
-        * See blk_queue_bounce_limit() to understand this part.
-        *
-        * XXX And I still need to be aware of the DMA mask in the HC.
-        */
-       q->bounce_pfn = blk_max_low_pfn;
-       q->bounce_gfp = GFP_NOIO;
+       blk_queue_hardsect_size(q, lun->capacity.bsize);
 
-       q->queuedata = sc;
+       q->queuedata = lun;
 
-       set_capacity(disk, sc->capacity.nsec);
-       if (sc->removable)
+       set_capacity(disk, lun->capacity.nsec);
+       if (lun->removable)
                disk->flags |= GENHD_FL_REMOVABLE;
 
        add_disk(disk);
@@ -2059,22 +2185,20 @@ static int ub_probe(struct usb_interface *intf,
 err_blkqinit:
        put_disk(disk);
 err_diskalloc:
-       device_remove_file(&sc->intf->dev, &dev_attr_diag);
-err_diag:
-       usb_set_intfdata(intf, NULL);
-       // usb_put_intf(sc->intf);
-       usb_put_dev(sc->dev);
-       ub_id_put(sc->id);
+       list_del(&lun->link);
+       ub_id_put(lun->id);
 err_id:
-       kfree(sc);
-err_core:
+       kfree(lun);
+err_alloc:
        return rc;
 }
 
 static void ub_disconnect(struct usb_interface *intf)
 {
        struct ub_dev *sc = usb_get_intfdata(intf);
-       struct gendisk *disk = sc->disk;
+       struct list_head *p;
+       struct ub_lun *lun;
+       struct gendisk *disk;
        unsigned long flags;
 
        /*
@@ -2124,14 +2248,18 @@ static void ub_disconnect(struct usb_interface *intf)
        /*
         * Unregister the upper layer.
         */
-       if (disk->flags & GENHD_FL_UP)
-               del_gendisk(disk);
-       /*
-        * I wish I could do:
-        *    set_bit(QUEUE_FLAG_DEAD, &q->queue_flags);
-        * As it is, we rely on our internal poisoning and let
-        * the upper levels to spin furiously failing all the I/O.
-        */
+       list_for_each (p, &sc->luns) {
+               lun = list_entry(p, struct ub_lun, link);
+               disk = lun->disk;
+               if (disk->flags & GENHD_FL_UP)
+                       del_gendisk(disk);
+               /*
+                * I wish I could do:
+                *    set_bit(QUEUE_FLAG_DEAD, &q->queue_flags);
+                * As it is, we rely on our internal poisoning and let
+                * the upper levels to spin furiously failing all the I/O.
+                */
+       }
 
        /*
         * Taking a lock on a structure which is about to be freed
@@ -2182,8 +2310,8 @@ static int __init ub_init(void)
 {
        int rc;
 
-       /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu\n",
-                       sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev));
+       /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu ub_lun %zu\n",
+                       sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev), sizeof(struct ub_lun));
 
        if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)
                goto err_regblkdev;
index 647a71b12a2a3cb2c1c0850bba012506acb0e9db..ac96de15d833dfa1c667f462d6316a1e8f9a90ee 100644 (file)
@@ -292,7 +292,7 @@ module_param(cdu31a_irq, int, 0);
 
 /* The interrupt handler will wake this queue up when it gets an
    interrupts. */
-DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
+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 */
@@ -2947,7 +2947,7 @@ static int scd_block_media_changed(struct gendisk *disk)
        return cdrom_media_changed(&scd_info);
 }
 
-struct block_device_operations scd_bdops =
+static struct block_device_operations scd_bdops =
 {
        .owner          = THIS_MODULE,
        .open           = scd_block_open,
@@ -3216,7 +3216,7 @@ errout3:
 }
 
 
-void __exit cdu31a_exit(void)
+static void __exit cdu31a_exit(void)
 {
        del_gendisk(scd_gendisk);
        put_disk(scd_gendisk);
index ccde7ab491d4f96b162357ed817fd8b27287b801..07bbd24e3c18c6e33043c55b9fe111149a396a9f 100644 (file)
@@ -107,20 +107,20 @@ static const char *mcdx_c_version
    The _direct_ size is the number of sectors we're allowed to skip
    directly (performing a read instead of requesting the new sector
    needed */
-const int REQUEST_SIZE = 800;  /* should be less then 255 * 4 */
-const int DIRECT_SIZE = 400;   /* should be less then REQUEST_SIZE */
+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 };
 
-const int SINGLE = 0x01;       /* single speed drive (FX001S, LU) */
-const int DOUBLE = 0x02;       /* double speed drive (FX001D, ..? */
-const int DOOR = 0x04;         /* door locking capability */
-const int MULTI = 0x08;                /* multi session capability */
+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 */
 
-const unsigned char READ1X = 0xc0;
-const unsigned char READ2X = 0xc1;
+static const unsigned char READ1X = 0xc0;
+static const unsigned char READ2X = 0xc1;
 
 
 /* DECLARATIONS ****************************************************/
@@ -210,9 +210,7 @@ struct s_drive_stuff {
        repeated here to show what's going on.  And to sense, if they're
        changed elsewhere. */
 
-/* declared in blk.h */
-int mcdx_init(void);
-void do_mcdx_request(request_queue_t * q);
+static int mcdx_init(void);
 
 static int mcdx_block_open(struct inode *inode, struct file *file)
 {
@@ -569,7 +567,7 @@ static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
        }
 }
 
-void do_mcdx_request(request_queue_t * q)
+static void do_mcdx_request(request_queue_t * q)
 {
        struct s_drive_stuff *stuffp;
        struct request *req;
@@ -1028,7 +1026,7 @@ int __mcdx_init(void)
        return 0;
 }
 
-void __exit mcdx_exit(void)
+static void __exit mcdx_exit(void)
 {
        int i;
 
@@ -1075,7 +1073,7 @@ module_exit(mcdx_exit);
 
 /* Support functions ************************************************/
 
-int __init mcdx_init_drive(int drive)
+static int __init mcdx_init_drive(int drive)
 {
        struct s_version version;
        struct gendisk *disk;
@@ -1261,7 +1259,7 @@ int __init mcdx_init_drive(int drive)
        return 0;
 }
 
-int __init mcdx_init(void)
+static int __init mcdx_init(void)
 {
        int drive;
        xwarn("Version 2.14(hs) \n");
index fc2c433f6a29bab5a958677140d01df8f8bf0d4c..452d34675159cd4dbfc6894af5cf7f2b8de19712 100644 (file)
@@ -5895,7 +5895,7 @@ int __init sbpcd_init(void)
 }
 /*==========================================================================*/
 #ifdef MODULE
-void sbpcd_exit(void)
+static void sbpcd_exit(void)
 {
        int j;
        
index fcca26c89bbccfa5803680bc0b5b5d417ced3b44..38dd9ffbe8bcc147cc2174e3965870ab5a9aba73 100644 (file)
@@ -488,6 +488,20 @@ static int viocd_packet(struct cdrom_device_info *cdi,
                                         & (CDC_DVD_RAM | CDC_RAM)) != 0;
                }
                break;
+       case GPCMD_GET_CONFIGURATION:
+               if (cgc->cmd[3] == CDF_RWRT) {
+                       struct rwrt_feature_desc *rfd = (struct rwrt_feature_desc *)(cgc->buffer + sizeof(struct feature_header));
+
+                       if ((buflen >=
+                            (sizeof(struct feature_header) + sizeof(*rfd))) &&
+                           (cdi->ops->capability & ~cdi->mask
+                            & (CDC_DVD_RAM | CDC_RAM))) {
+                               rfd->feature_code = cpu_to_be16(CDF_RWRT);
+                               rfd->curr = 1;
+                               ret = 0;
+                       }
+               }
+               break;
        default:
                if (cgc->sense) {
                        /* indicate Unknown code */
index e162dab64ffd20402e93e8f60ed038e952299bec..5ed6515ae01fe0fee127d23fa18717b688a7eb24 100644 (file)
@@ -153,7 +153,7 @@ config DIGIEPCA
 
 config ESPSERIAL
        tristate "Hayes ESP serial port support"
-       depends on SERIAL_NONSTANDARD && ISA && BROKEN_ON_SMP
+       depends on SERIAL_NONSTANDARD && ISA && BROKEN_ON_SMP && ISA_DMA_API
        help
          This is a driver which supports Hayes ESP serial ports.  Both single
          port cards and multiport cards are supported.  Make sure to read
@@ -195,7 +195,7 @@ config ISI
 
 config SYNCLINK
        tristate "Microgate SyncLink card support"
-       depends on SERIAL_NONSTANDARD && PCI
+       depends on SERIAL_NONSTANDARD && PCI && ISA_DMA_API
        help
          Provides support for the SyncLink ISA and PCI multiprotocol serial
          adapters. These adapters support asynchronous and HDLC bit
@@ -408,7 +408,7 @@ config SGI_TIOCX
 
 config SGI_MBCS
        tristate "SGI FPGA Core Services driver support"
-       depends on (IA64_SGI_SN2 || IA64_GENERIC)
+       depends on SGI_TIOCX
        help
          If you have an SGI Altix with an attached SABrick
          say Y or M here, otherwise say N.
index ad9c11391d81112409b2aaf27549cb5d766e2219..c1fe013c64f34c31c1d9b9cceded9d0d2b51ad08 100644 (file)
@@ -278,6 +278,8 @@ void agp3_generic_cleanup(void);
 #define AGP_GENERIC_SIZES_ENTRIES 11
 extern struct aper_size_info_16 agp3_generic_sizes[];
 
+#define virt_to_gart(x) (phys_to_gart(virt_to_phys(x)))
+#define gart_to_virt(x) (phys_to_virt(gart_to_phys(x)))
 
 extern int agp_off;
 extern int agp_try_unsupported_boot;
index 0212febda654b06da557ec331e3c4c4893c9bfab..9c9c9c2247cecfe8c48d0607e8a5d5a0b5f0921f 100644 (file)
@@ -150,7 +150,7 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge)
        pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
        pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
                        (((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
-                         virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN ));
+                         virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN ));
        return addr;
 }
 
@@ -174,7 +174,7 @@ static void m1541_destroy_page(void * addr)
        pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
        pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
                        (((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
-                         virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN));
+                         virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN));
        agp_generic_destroy_page(addr);
 }
 
index e62a3c2c44a9b891c5dcdb2fa002cd0a56276c62..3a41672e4d6682112f19a19ee8ceae2752984be0 100644 (file)
@@ -43,7 +43,7 @@ static int amd_create_page_map(struct amd_page_map *page_map)
 
        SetPageReserved(virt_to_page(page_map->real));
        global_cache_flush();
-       page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
+       page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
                                            PAGE_SIZE);
        if (page_map->remapped == NULL) {
                ClearPageReserved(virt_to_page(page_map->real));
@@ -154,7 +154,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge)
 
        agp_bridge->gatt_table_real = (u32 *)page_dir.real;
        agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
-       agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
+       agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
 
        /* Get the address for the gart region.
         * This is a bus address even on the alpha, b/c its
@@ -167,7 +167,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge)
 
        /* Calculate the agp offset */
        for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
-               writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1,
+               writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1,
                        page_dir.remapped+GET_PAGE_DIR_OFF(addr));
                readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));        /* PCI Posting. */
        }
index 399c042f68f04f0634ae7375f3917d1f1475edee..1407945a5892887565219b6594dde1444a6e30ea 100644 (file)
@@ -219,7 +219,7 @@ static struct aper_size_info_32 amd_8151_sizes[7] =
 
 static int amd_8151_configure(void)
 {
-       unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real);
+       unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real);
 
        /* Configure AGP regs in each x86-64 host bridge. */
        for_each_nb() {
@@ -591,7 +591,7 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev)
 {
        struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 
-       release_mem_region(virt_to_phys(bridge->gatt_table_real),
+       release_mem_region(virt_to_gart(bridge->gatt_table_real),
                           amd64_aperture_sizes[bridge->aperture_size_idx].size);
        agp_remove_bridge(bridge);
        agp_put_bridge(bridge);
index a65f8827c2831d40f33e0baf5970211e5bba07d9..e572ced9100aeb8d78fc9bdf5379952ae3ff3905 100644 (file)
@@ -61,7 +61,7 @@ static int ati_create_page_map(ati_page_map *page_map)
 
        SetPageReserved(virt_to_page(page_map->real));
        err = map_page_into_agp(virt_to_page(page_map->real));
-       page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
+       page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
                                            PAGE_SIZE);
        if (page_map->remapped == NULL || err) {
                ClearPageReserved(virt_to_page(page_map->real));
@@ -343,7 +343,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge)
 
        agp_bridge->gatt_table_real = (u32 *)page_dir.real;
        agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped;
-       agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real);
+       agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
 
        /* Write out the size register */
        current_size = A_SIZE_LVL2(agp_bridge->current_size);
@@ -373,7 +373,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge)
 
        /* Calculate the agp offset */
        for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
-               writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1,
+               writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1,
                        page_dir.remapped+GET_PAGE_DIR_OFF(addr));
                readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));        /* PCI Posting. */
        }
index 2f3dfb63bdc6518742ebdbd08e9f88ae800974d8..4d4e602fdc7e7cfa326000b84135583ed866296d 100644 (file)
@@ -148,7 +148,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
                        return -ENOMEM;
                }
 
-               bridge->scratch_page_real = virt_to_phys(addr);
+               bridge->scratch_page_real = virt_to_gart(addr);
                bridge->scratch_page =
                    bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0);
        }
@@ -189,7 +189,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
 err_out:
        if (bridge->driver->needs_scratch_page)
                bridge->driver->agp_destroy_page(
-                               phys_to_virt(bridge->scratch_page_real));
+                               gart_to_virt(bridge->scratch_page_real));
        if (got_gatt)
                bridge->driver->free_gatt_table(bridge);
        if (got_keylist) {
@@ -214,7 +214,7 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
        if (bridge->driver->agp_destroy_page &&
            bridge->driver->needs_scratch_page)
                bridge->driver->agp_destroy_page(
-                               phys_to_virt(bridge->scratch_page_real));
+                               gart_to_virt(bridge->scratch_page_real));
 }
 
 /* When we remove the global variable agp_bridge from all drivers
index 1383c3165ea1942143ad8f1fa18872cf78b982d0..ac19fdcd21c1c7583246256edba92157b42d278e 100644 (file)
@@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge)
 
                efficeon_private.l1_table[index] = page;
 
-               value = __pa(page) | pati | present | index;
+               value = virt_to_gart(page) | pati | present | index;
 
                pci_write_config_dword(agp_bridge->dev,
                        EFFICEON_ATTPAGE, value);
index c321a924e38a8241e7d9c9cc2e0927a2bfc384ce..f0079e991bdc4ffaf95c787e50bd9618a848e225 100644 (file)
@@ -153,7 +153,7 @@ void agp_free_memory(struct agp_memory *curr)
        }
        if (curr->page_count != 0) {
                for (i = 0; i < curr->page_count; i++) {
-                       curr->bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i]));
+                       curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
                }
        }
        agp_free_key(curr->key);
@@ -209,7 +209,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
                        agp_free_memory(new);
                        return NULL;
                }
-               new->memory[i] = virt_to_phys(addr);
+               new->memory[i] = virt_to_gart(addr);
                new->page_count++;
        }
        new->bridge = bridge;
@@ -295,19 +295,6 @@ int agp_num_entries(void)
 EXPORT_SYMBOL_GPL(agp_num_entries);
 
 
-static int check_bridge_mode(struct pci_dev *dev)
-{
-       u32 agp3;
-       u8 cap_ptr;
-
-       cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
-       pci_read_config_dword(dev, cap_ptr+AGPSTAT, &agp3);
-       if (agp3 & AGPSTAT_MODE_3_0)
-               return 1;
-       return 0;
-}
-
-
 /**
  *     agp_copy_info  -  copy bridge state information
  *
@@ -328,7 +315,7 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info)
        info->version.minor = bridge->version->minor;
        info->chipset = SUPPORTED;
        info->device = bridge->dev;
-       if (check_bridge_mode(bridge->dev))
+       if (bridge->mode & AGPSTAT_MODE_3_0)
                info->mode = bridge->mode & ~AGP3_RESERVED_MASK;
        else
                info->mode = bridge->mode & ~AGP2_RESERVED_MASK;
@@ -661,7 +648,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode
                bridge_agpstat &= ~AGPSTAT_FW;
 
        /* Check to see if we are operating in 3.0 mode */
-       if (check_bridge_mode(agp_bridge->dev))
+       if (agp_bridge->mode & AGPSTAT_MODE_3_0)
                agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);
        else
                agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);
@@ -732,7 +719,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode)
 
        /* Do AGP version specific frobbing. */
        if (bridge->major_version >= 3) {
-               if (check_bridge_mode(bridge->dev)) {
+               if (bridge->mode & AGPSTAT_MODE_3_0) {
                        /* If we have 3.5, we can do the isoch stuff. */
                        if (bridge->minor_version >= 5)
                                agp_3_5_enable(bridge);
@@ -806,8 +793,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
                                break;
                        }
 
-                       table = (char *) __get_free_pages(GFP_KERNEL,
-                                                         page_order);
+                       table = alloc_gatt_pages(page_order);
 
                        if (table == NULL) {
                                i++;
@@ -838,7 +824,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
                size = ((struct aper_size_info_fixed *) temp)->size;
                page_order = ((struct aper_size_info_fixed *) temp)->page_order;
                num_entries = ((struct aper_size_info_fixed *) temp)->num_entries;
-               table = (char *) __get_free_pages(GFP_KERNEL, page_order);
+               table = alloc_gatt_pages(page_order);
        }
 
        if (table == NULL)
@@ -853,7 +839,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
        agp_gatt_table = (void *)table;
 
        bridge->driver->cache_flush();
-       bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
+       bridge->gatt_table = ioremap_nocache(virt_to_gart(table),
                                        (PAGE_SIZE * (1 << page_order)));
        bridge->driver->cache_flush();
 
@@ -861,11 +847,11 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
                for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
                        ClearPageReserved(page);
 
-               free_pages((unsigned long) table, page_order);
+               free_gatt_pages(table, page_order);
 
                return -ENOMEM;
        }
-       bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real);
+       bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real);
 
        /* AK: bogus, should encode addresses > 4GB */
        for (i = 0; i < num_entries; i++) {
@@ -919,7 +905,7 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge)
        for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
                ClearPageReserved(page);
 
-       free_pages((unsigned long) bridge->gatt_table_real, page_order);
+       free_gatt_pages(bridge->gatt_table_real, page_order);
 
        agp_gatt_table = NULL;
        bridge->gatt_table = NULL;
index 6052bfa04c728c5a7373597d81137635a3ed71ac..99762b6c19aea2fdc82119d44f28dde30479f969 100644 (file)
@@ -110,7 +110,7 @@ static int __init hp_zx1_ioc_shared(void)
        hp->gart_size = HP_ZX1_GART_SIZE;
        hp->gatt_entries = hp->gart_size / hp->io_page_size;
 
-       hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
+       hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
        hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 
        if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
@@ -248,7 +248,7 @@ hp_zx1_configure (void)
        agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
 
        if (hp->io_pdir_owner) {
-               writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
+               writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
                readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
                writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
                readl(hp->ioc_regs+HP_ZX1_TCNFG);
index adbea896c0d2e73f0ee6ab5d51c40fa17aedf47d..94943298c03eb42056d00ba73875147bd40b7e24 100644 (file)
@@ -372,7 +372,7 @@ static int i460_alloc_large_page (struct lp_desc *lp)
        }
        memset(lp->alloced_map, 0, map_size);
 
-       lp->paddr = virt_to_phys(lpage);
+       lp->paddr = virt_to_gart(lpage);
        lp->refcount = 0;
        atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
        return 0;
@@ -383,7 +383,7 @@ static void i460_free_large_page (struct lp_desc *lp)
        kfree(lp->alloced_map);
        lp->alloced_map = NULL;
 
-       free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
+       free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
        atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 }
 
index 8c7d727432bb5b02c25fa22467de24cbd52ef300..51266d6b4d78af9bf138f52dbbdf6f43413ac0c7 100644 (file)
@@ -286,7 +286,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
        if (new == NULL)
                return NULL;
 
-       new->memory[0] = virt_to_phys(addr);
+       new->memory[0] = virt_to_gart(addr);
        if (pg_count == 4) {
                /* kludge to get 4 physical pages for ARGB cursor */
                new->memory[1] = new->memory[0] + PAGE_SIZE;
@@ -329,10 +329,10 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
        agp_free_key(curr->key);
        if(curr->type == AGP_PHYS_MEMORY) {
                if (curr->page_count == 4)
-                       i8xx_destroy_pages(phys_to_virt(curr->memory[0]));
+                       i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
                else
                        agp_bridge->driver->agp_destroy_page(
-                                phys_to_virt(curr->memory[0]));
+                                gart_to_virt(curr->memory[0]));
                vfree(curr->memory);
        }
        kfree(curr);
@@ -418,7 +418,8 @@ static void intel_i830_init_gtt_entries(void)
                case I915_GMCH_GMS_STOLEN_48M:
                        /* Check it's really I915G */
                        if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
-                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB)
                                gtt_entries = MB(48) - KB(size);
                        else
                                gtt_entries = 0;
@@ -426,7 +427,8 @@ static void intel_i830_init_gtt_entries(void)
                case I915_GMCH_GMS_STOLEN_64M:
                        /* Check it's really I915G */
                        if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
-                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB)
                                gtt_entries = MB(64) - KB(size);
                        else
                                gtt_entries = 0;
@@ -1662,6 +1664,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
                }
                name = "915GM";
                break;
+       case PCI_DEVICE_ID_INTEL_82945G_HB:
+               if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG)) {
+                       bridge->driver = &intel_915_driver;
+               } else {
+                       bridge->driver = &intel_845_driver;
+               }
+               name = "945G";
+               break;
        case PCI_DEVICE_ID_INTEL_7505_0:
                bridge->driver = &intel_7505_driver;
                name = "E7505";
@@ -1801,6 +1811,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
        ID(PCI_DEVICE_ID_INTEL_7205_0),
        ID(PCI_DEVICE_ID_INTEL_82915G_HB),
        ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
+       ID(PCI_DEVICE_ID_INTEL_82945G_HB),
        { }
 };
 
index 4b3eda2679761ff5937ba044b2047422ad8c03ce..d3aa159c9decbfa0ba99e6b42db5aa7f22ac6859 100644 (file)
@@ -133,11 +133,14 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start,
        off_t j;
        void *temp;
        struct agp_bridge_data *bridge;
+       u64 *table;
 
        bridge = mem->bridge;
        if (!bridge)
                return -EINVAL;
 
+       table = (u64 *)bridge->gatt_table;
+
        temp = bridge->current_size;
 
        switch (bridge->driver->size_type) {
@@ -175,7 +178,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start,
        j = pg_start;
 
        while (j < (pg_start + mem->page_count)) {
-               if (*(bridge->gatt_table + j))
+               if (table[j])
                        return -EBUSY;
                j++;
        }
@@ -186,7 +189,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start,
        }
 
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-               *(bridge->gatt_table + j) =
+               table[j] =
                    bridge->driver->mask_memory(bridge, mem->memory[i],
                                                mem->type);
        }
@@ -200,6 +203,7 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start,
 {
        size_t i;
        struct agp_bridge_data *bridge;
+       u64 *table;
 
        bridge = mem->bridge;
        if (!bridge)
@@ -209,8 +213,10 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start,
                return -EINVAL;
        }
 
+       table = (u64 *)bridge->gatt_table;
+
        for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-               *(bridge->gatt_table + i) = 0;
+               table[i] = 0;
        }
 
        bridge->driver->tlb_flush(mem);
index 10c23302dd840d3bcc747c93871b2b1f9cc36209..a9fb12c20eb72e92aa343413094270022a159e47 100644 (file)
@@ -51,7 +51,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map)
        }
        SetPageReserved(virt_to_page(page_map->real));
        global_cache_flush();
-       page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), 
+       page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
                                            PAGE_SIZE);
        if (page_map->remapped == NULL) {
                ClearPageReserved(virt_to_page(page_map->real));
@@ -162,7 +162,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
        /* Create a fake scratch directory */
        for(i = 0; i < 1024; i++) {
                writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i);
-               writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
+               writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
        }
 
        retval = serverworks_create_gatt_pages(value->num_entries / 1024);
@@ -174,7 +174,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
 
        agp_bridge->gatt_table_real = (u32 *)page_dir.real;
        agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
-       agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
+       agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
 
        /* Get the address for the gart region.
         * This is a bus address even on the alpha, b/c its
@@ -187,7 +187,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
        /* Calculate the agp offset */  
 
        for(i = 0; i < value->num_entries / 1024; i++)
-               writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);
+               writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);
 
        return 0;
 }
index a673971f2a90309becddc27835d195bd36f30fad..c8255312b8c1f3728fb608928ebf554913cff4d2 100644 (file)
@@ -407,7 +407,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 
        bridge->gatt_table_real = (u32 *) table;
        bridge->gatt_table = (u32 *)table;
-       bridge->gatt_bus_addr = virt_to_phys(table);
+       bridge->gatt_bus_addr = virt_to_gart(table);
 
        for (i = 0; i < num_entries; i++)
                bridge->gatt_table[i] = 0;
index 54a2914e3a321a31c0093b9f53fef81934b99427..11c6950158b3d7606bc3bb859ed1c7132177bacb 100644 (file)
        {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
        {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
        {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+       {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
        {0, 0, 0}
 
index 5b18bee6492e898936d994dab4c5ec93d93fbecf..cd25f28e26a38874738705d935c37d51de4cda42 100644 (file)
@@ -123,11 +123,6 @@ static int radeon_wait_irq(drm_device_t *dev, int swi_nr)
 
        dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
 
-       /* This is a hack to work around mysterious freezes on certain
-        * systems:
-        */ 
-       radeon_acknowledge_irqs( dev_priv );
-
        DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, 
                     RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr );
 
index 49d67f5384a2c2d9a0a5b97ad0cbd4c40c500b2b..6dc765dc5413dfe1f0ba58ead7d921899be22194 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/ipmi.h>
 #include <asm/semaphore.h>
 #include <linux/init.h>
+#include <linux/device.h>
 
 #define IPMI_DEVINTF_VERSION "v33"
 
@@ -519,15 +520,21 @@ MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device.  By"
                 " interface.  Other values will set the major device number"
                 " to that value.");
 
+static struct class_simple *ipmi_class;
+
 static void ipmi_new_smi(int if_num)
 {
-       devfs_mk_cdev(MKDEV(ipmi_major, if_num),
-                     S_IFCHR | S_IRUSR | S_IWUSR,
+       dev_t dev = MKDEV(ipmi_major, if_num);
+
+       devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
                      "ipmidev/%d", if_num);
+
+       class_simple_device_add(ipmi_class, dev, NULL, "ipmi%d", if_num);
 }
 
 static void ipmi_smi_gone(int if_num)
 {
+       class_simple_device_remove(MKDEV(ipmi_major, if_num));
        devfs_remove("ipmidev/%d", if_num);
 }
 
@@ -548,8 +555,15 @@ static __init int init_ipmi_devintf(void)
        printk(KERN_INFO "ipmi device interface version "
               IPMI_DEVINTF_VERSION "\n");
 
+       ipmi_class = class_simple_create(THIS_MODULE, "ipmi");
+       if (IS_ERR(ipmi_class)) {
+               printk(KERN_ERR "ipmi: can't register device class\n");
+               return PTR_ERR(ipmi_class);
+       }
+
        rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
        if (rv < 0) {
+               class_simple_destroy(ipmi_class);
                printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
                return rv;
        }
@@ -563,6 +577,7 @@ static __init int init_ipmi_devintf(void)
        rv = ipmi_smi_watcher_register(&smi_watcher);
        if (rv) {
                unregister_chrdev(ipmi_major, DEVICE_NAME);
+               class_simple_destroy(ipmi_class);
                printk(KERN_WARNING "ipmi: can't register smi watcher\n");
                return rv;
        }
@@ -573,6 +588,7 @@ module_init(init_ipmi_devintf);
 
 static __exit void cleanup_ipmi(void)
 {
+       class_simple_destroy(ipmi_class);
        ipmi_smi_watcher_unregister(&smi_watcher);
        devfs_remove(DEVICE_NAME);
        unregister_chrdev(ipmi_major, DEVICE_NAME);
index 5419440087fd6844c923da80d790bd3ca91acbcc..298574e160613e67191472bf147e141546573957 100644 (file)
@@ -1617,15 +1617,15 @@ typedef struct dmi_header
        u16     handle;
 } dmi_header_t;
 
-static int decode_dmi(dmi_header_t *dm, int intf_num)
+static int decode_dmi(dmi_header_t __iomem *dm, int intf_num)
 {
-       u8              *data = (u8 *)dm;
+       u8              __iomem *data = (u8 __iomem *)dm;
        unsigned long   base_addr;
        u8              reg_spacing;
-       u8              len = dm->length;
+       u8              len = readb(&dm->length);
        dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num;
 
-       ipmi_data->type = data[4];
+       ipmi_data->type = readb(&data[4]);
 
        memcpy(&base_addr, data+8, sizeof(unsigned long));
        if (len >= 0x11) {
@@ -1640,12 +1640,12 @@ static int decode_dmi(dmi_header_t *dm, int intf_num)
                }
                /* If bit 4 of byte 0x10 is set, then the lsb for the address
                   is odd. */
-               ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4);
+               ipmi_data->base_addr = base_addr | ((readb(&data[0x10]) & 0x10) >> 4);
 
-               ipmi_data->irq = data[0x11];
+               ipmi_data->irq = readb(&data[0x11]);
 
                /* The top two bits of byte 0x10 hold the register spacing. */
-               reg_spacing = (data[0x10] & 0xC0) >> 6;
+               reg_spacing = (readb(&data[0x10]) & 0xC0) >> 6;
                switch(reg_spacing){
                case 0x00: /* Byte boundaries */
                    ipmi_data->offset = 1;
@@ -1673,7 +1673,7 @@ static int decode_dmi(dmi_header_t *dm, int intf_num)
                ipmi_data->offset = 1;
        }
 
-       ipmi_data->slave_addr = data[6];
+       ipmi_data->slave_addr = readb(&data[6]);
 
        if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) {
                dmi_data_entries++;
@@ -1687,9 +1687,9 @@ static int decode_dmi(dmi_header_t *dm, int intf_num)
 
 static int dmi_table(u32 base, int len, int num)
 {
-       u8                *buf;
-       struct dmi_header *dm;
-       u8                *data;
+       u8                __iomem *buf;
+       struct dmi_header __iomem *dm;
+       u8                __iomem *data;
        int               i=1;
        int               status=-1;
        int               intf_num = 0;
@@ -1702,12 +1702,12 @@ static int dmi_table(u32 base, int len, int num)
 
        while(i<num && (data - buf) < len)
        {
-               dm=(dmi_header_t *)data;
+               dm=(dmi_header_t __iomem *)data;
 
-               if((data-buf+dm->length) >= len)
+               if((data-buf+readb(&dm->length)) >= len)
                        break;
 
-               if (dm->type == 38) {
+               if (readb(&dm->type) == 38) {
                        if (decode_dmi(dm, intf_num) == 0) {
                                intf_num++;
                                if (intf_num >= SI_MAX_DRIVERS)
@@ -1715,8 +1715,8 @@ static int dmi_table(u32 base, int len, int num)
                        }
                }
 
-               data+=dm->length;
-               while((data-buf) < len && (*data || data[1]))
+               data+=readb(&dm->length);
+               while((data-buf) < len && (readb(data)||readb(data+1)))
                        data++;
                data+=2;
                i++;
index a0212b004016ab3547562f2bb7ec46a8dabed2e0..62791dd429856d3755fe4898e83791b25dabaca3 100644 (file)
@@ -51,7 +51,7 @@ struct si_sm_io
        /* Generic info used by the actual handling routines, the
            state machine shouldn't touch these. */
        void *info;
-       void *addr;
+       void __iomem *addr;
        int  regspacing;
        int  regsize;
        int  regshift;
index 3ce51c6a1b1821c6c25429ea813b1ab67a4ba91d..7b19e02f112fd585d02fe48e4eb1eb8c2a0001cc 100644 (file)
@@ -1026,7 +1026,8 @@ static void kbd_rawcode(unsigned char data)
                put_queue(vc, data);
 }
 
-void kbd_keycode(unsigned int keycode, int down, int hw_raw, struct pt_regs *regs)
+static void kbd_keycode(unsigned int keycode, int down,
+                       int hw_raw, struct pt_regs *regs)
 {
        struct vc_data *vc = vc_cons[fg_console].d;
        unsigned short keysym, *key_map;
index ec7100556c50bbe19a0de2aec439cf78362f5bec..ac9cfa9701ea9003d0f440ec572e0eecaec7a1a3 100644 (file)
@@ -394,7 +394,7 @@ int mbcs_open(struct inode *ip, struct file *fp)
        return -ENODEV;
 }
 
-ssize_t mbcs_sram_read(struct file * fp, char *buf, size_t len, loff_t * off)
+ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t * off)
 {
        struct cx_dev *cx_dev = fp->private_data;
        struct mbcs_soft *soft = cx_dev->soft;
@@ -419,7 +419,7 @@ ssize_t mbcs_sram_read(struct file * fp, char *buf, size_t len, loff_t * off)
 }
 
 ssize_t
-mbcs_sram_write(struct file * fp, const char *buf, size_t len, loff_t * off)
+mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * off)
 {
        struct cx_dev *cx_dev = fp->private_data;
        struct mbcs_soft *soft = cx_dev->soft;
index 844644d201c5c427a6d11866aecb67ae94e8dce0..e7fd47e43257396bd899fab5d1748045ef1590cc 100644 (file)
@@ -543,9 +543,9 @@ struct mbcs_soft {
 };
 
 extern int mbcs_open(struct inode *ip, struct file *fp);
-extern ssize_t mbcs_sram_read(struct file *fp, char *buf, size_t len,
+extern ssize_t mbcs_sram_read(struct file *fp, char __user *buf, size_t len,
                              loff_t * off);
-extern ssize_t mbcs_sram_write(struct file *fp, const char *buf, size_t len,
+extern ssize_t mbcs_sram_write(struct file *fp, const char __user *buf, size_t len,
                               loff_t * off);
 extern loff_t mbcs_sram_llseek(struct file *filp, loff_t off, int whence);
 extern int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma);
index 7a245068e3e55e2ba47801ca8ea9fa08f99cf66a..f022f0944434158f31eb3a9b3f0c9da35abadf1b 100644 (file)
@@ -1995,9 +1995,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
        unsigned char ch, gdl;
        int ignored = 0;
        int cnt = 0;
-       unsigned char *cp;
-       char *fp;
-       int count;
        int recv_room;
        int max = 256;
        unsigned long flags;
@@ -2011,10 +2008,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
                //return;
        }
 
-       cp = tty->flip.char_buf;
-       fp = tty->flip.flag_buf;
-       count = 0;
-
        // following add by Victor Yu. 09-02-2002
        if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {
 
@@ -2041,12 +2034,10 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
                }
                while (gdl--) {
                        ch = inb(info->base + UART_RX);
-                       count++;
-                       *cp++ = ch;
-                       *fp++ = 0;
+                       tty_insert_flip_char(tty, ch, 0);
                        cnt++;
                        /*
-                          if((count>=HI_WATER) && (info->stop_rx==0)){
+                          if((cnt>=HI_WATER) && (info->stop_rx==0)){
                           mxser_stoprx(tty);
                           info->stop_rx=1;
                           break;
@@ -2061,7 +2052,7 @@ intr_old:
                if (max-- < 0)
                        break;
                /*
-                  if((count>=HI_WATER) && (info->stop_rx==0)){
+                  if((cnt>=HI_WATER) && (info->stop_rx==0)){
                   mxser_stoprx(tty);
                   info->stop_rx=1;
                   break;
@@ -2078,36 +2069,33 @@ intr_old:
                        if (++ignored > 100)
                                break;
                } else {
-                       count++;
+                       char flag = 0;
                        if (*status & UART_LSR_SPECIAL) {
                                if (*status & UART_LSR_BI) {
-                                       *fp++ = TTY_BREAK;
+                                       flag = TTY_BREAK;
 /* added by casper 1/11/2000 */
                                        info->icount.brk++;
-
 /* */
                                        if (info->flags & ASYNC_SAK)
                                                do_SAK(tty);
                                } else if (*status & UART_LSR_PE) {
-                                       *fp++ = TTY_PARITY;
+                                       flag = TTY_PARITY;
 /* added by casper 1/11/2000 */
                                        info->icount.parity++;
 /* */
                                } else if (*status & UART_LSR_FE) {
-                                       *fp++ = TTY_FRAME;
+                                       flag = TTY_FRAME;
 /* added by casper 1/11/2000 */
                                        info->icount.frame++;
 /* */
                                } else if (*status & UART_LSR_OE) {
-                                       *fp++ = TTY_OVERRUN;
+                                       flag = TTY_OVERRUN;
 /* added by casper 1/11/2000 */
                                        info->icount.overrun++;
 /* */
-                               } else
-                                       *fp++ = 0;
-                       } else
-                               *fp++ = 0;
-                       *cp++ = ch;
+                               }
+                       }
+                       tty_insert_flip_char(tty, ch, flag);
                        cnt++;
                        if (cnt >= recv_room) {
                                if (!info->ldisc_stop_rx) {
@@ -2132,13 +2120,13 @@ intr_old:
                // above add by Victor Yu. 09-02-2002
        } while (*status & UART_LSR_DR);
 
-      end_intr:                // add by Victor Yu. 09-02-2002
+end_intr:              // add by Victor Yu. 09-02-2002
 
        mxvar_log.rxcnt[info->port] += cnt;
        info->mon_data.rxcnt += cnt;
        info->mon_data.up_rxcnt += cnt;
        spin_unlock_irqrestore(&info->slock, flags);
-       
+
        tty_flip_buffer_push(tty);
 }
 
index a2e33ec796151ab4f96f4a869447f87088f0e300..ca5f42bcaad91eeca08a3984cf530ab2f7b5818c 100644 (file)
@@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp,
 {
        struct block_device *bdev = filp->private_data;
 
-       return ioctl_by_bdev(bdev, command, arg);
+       return blkdev_ioctl(bdev->bd_inode, NULL, command, arg);
 }
 
 static void bind_device(struct raw_config_request *rq)
index c812191417c36aac6190f7e94e997ca7f6c3beac..fd042060809a3b5572183f6874219d890261a09b 100644 (file)
@@ -1021,11 +1021,11 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
                        ret = -EIO;
                        break;
                }
-               if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+               if (copy_to_user(argp, &val8, sizeof(val8)))
                        ret = -EFAULT;
                break;
        case SONYPI_IOCSFAN:
-               if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) {
+               if (copy_from_user(&val8, argp, sizeof(val8))) {
                        ret = -EFAULT;
                        break;
                }
@@ -1038,7 +1038,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
                        ret = -EIO;
                        break;
                }
-               if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+               if (copy_to_user(argp, &val8, sizeof(val8)))
                        ret = -EFAULT;
                break;
        default:
index 06e5a3f1836dbb595ed3108f30e0cbc00c614dd2..26e5e19ed8545b880833623e960f654378e595f0 100644 (file)
@@ -185,7 +185,7 @@ char *tty_name(struct tty_struct *tty, char *buf)
 
 EXPORT_SYMBOL(tty_name);
 
-inline int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
+int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
                              const char *routine)
 {
 #ifdef TTY_PARANOIA_CHECK
index c337978dc966b7e955a1ed736e8fd7bad47a062b..b14d642439ed1343ba30e8db18769176d80a9b63 100644 (file)
@@ -382,6 +382,7 @@ static struct pci_device_id i8xx_tco_pci_tbl[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2,      PCI_ANY_ID, PCI_ANY_ID, },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,      PCI_ANY_ID, PCI_ANY_ID, },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,      PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1,       PCI_ANY_ID, PCI_ANY_ID, },
        { 0, },                 /* End of list */
 };
 MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl);
index 95882bb1950e3c2f211e28467d782a51fb4cd69a..60c9be99c6d91244f311dccd2837f49e00b14e87 100644 (file)
@@ -46,6 +46,10 @@ config CPU_FREQ_STAT_DETAILS
          This will show detail CPU frequency translation table in sysfs file
          system
 
+# Note that it is not currently possible to set the other governors (such as ondemand)
+# as the default, since if they fail to initialise, cpufreq will be
+# left in an undefined state.
+
 choice
        prompt "Default CPUFreq governor"
        default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110
@@ -115,4 +119,24 @@ config CPU_FREQ_GOV_ONDEMAND
 
          If in doubt, say N.
 
+config CPU_FREQ_GOV_CONSERVATIVE
+       tristate "'conservative' cpufreq governor"
+       depends on CPU_FREQ
+       help
+         'conservative' - this driver is rather similar to the 'ondemand'
+         governor both in its source code and its purpose, the difference is
+         its optimisation for better suitability in a battery powered
+         environment.  The frequency is gracefully increased and decreased
+         rather than jumping to 100% when speed is required.
+
+         If you have a desktop machine then you should really be considering
+         the 'ondemand' governor instead, however if you are using a laptop,
+         PDA or even an AMD64 based computer (due to the unacceptable
+         step-by-step latency issues between the minimum and maximum frequency
+         transitions in the CPU) you will probably want to use this governor.
+
+         For details, take a look at linux/Documentation/cpu-freq.
+
+         If in doubt, say N.
+
 endif  # CPU_FREQ
index 67b16e5a41a790d1cbfcc9aae766f96c1b379e6c..71fc3b4173f10d2d81930ae003445f0037fb1e7d 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE)  += cpufreq_performance.o
 obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE)   += cpufreq_powersave.o
 obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)   += cpufreq_userspace.o
 obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)    += cpufreq_ondemand.o
+obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)        += cpufreq_conservative.o
 
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)           += freq_table.o
index 8e561313d0942571c99de7c19b26f920d355f974..03b5fb2ddcf44902aba3d2e79d7f1c5f3b036140 100644 (file)
@@ -258,7 +258,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
                            (likely(cpufreq_cpu_data[freqs->cpu]->cur)) &&
                            (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur)))
                        {
-                               printk(KERN_WARNING "Warning: CPU frequency is %u, "
+                               dprintk(KERN_WARNING "Warning: CPU frequency is %u, "
                                       "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur);
                                freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
                        }
@@ -814,7 +814,7 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne
 {
        struct cpufreq_freqs freqs;
 
-       printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing "
+       dprintk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing "
               "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
 
        freqs.cpu = cpu;
@@ -923,7 +923,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, u32 state)
                struct cpufreq_freqs freqs;
 
                if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
-                       printk(KERN_DEBUG "Warning: CPU frequency is %u, "
+                       dprintk(KERN_DEBUG "Warning: CPU frequency is %u, "
                               "cpufreq assumed %u kHz.\n",
                               cur_freq, cpu_policy->cur);
 
@@ -1004,7 +1004,7 @@ static int cpufreq_resume(struct sys_device * sysdev)
                        struct cpufreq_freqs freqs;
 
                        if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
-                               printk(KERN_WARNING "Warning: CPU frequency"
+                               dprintk(KERN_WARNING "Warning: CPU frequency"
                                       "is %u, cpufreq assumed %u kHz.\n",
                                       cur_freq, cpu_policy->cur);
 
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
new file mode 100644 (file)
index 0000000..e1df376
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+ *  drivers/cpufreq/cpufreq_conservative.c
+ *
+ *  Copyright (C)  2001 Russell King
+ *            (C)  2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
+ *                      Jun Nakajima <jun.nakajima@intel.com>
+ *            (C)  2004 Alexander Clouter <alex-kernel@digriz.org.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ctype.h>
+#include <linux/cpufreq.h>
+#include <linux/sysctl.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/sysfs.h>
+#include <linux/sched.h>
+#include <linux/kmod.h>
+#include <linux/workqueue.h>
+#include <linux/jiffies.h>
+#include <linux/kernel_stat.h>
+#include <linux/percpu.h>
+
+/*
+ * dbs is used in this file as a shortform for demandbased switching
+ * It helps to keep variable names smaller, simpler
+ */
+
+#define DEF_FREQUENCY_UP_THRESHOLD             (80)
+#define MIN_FREQUENCY_UP_THRESHOLD             (0)
+#define MAX_FREQUENCY_UP_THRESHOLD             (100)
+
+#define DEF_FREQUENCY_DOWN_THRESHOLD           (20)
+#define MIN_FREQUENCY_DOWN_THRESHOLD           (0)
+#define MAX_FREQUENCY_DOWN_THRESHOLD           (100)
+
+/* 
+ * The polling frequency of this governor depends on the capability of 
+ * the processor. Default polling frequency is 1000 times the transition
+ * latency of the processor. The governor will work on any processor with 
+ * transition latency <= 10mS, using appropriate sampling 
+ * rate.
+ * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
+ * this governor will not work.
+ * All times here are in uS.
+ */
+static unsigned int                            def_sampling_rate;
+#define MIN_SAMPLING_RATE                      (def_sampling_rate / 2)
+#define MAX_SAMPLING_RATE                      (500 * def_sampling_rate)
+#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER   (100000)
+#define DEF_SAMPLING_DOWN_FACTOR               (5)
+#define TRANSITION_LATENCY_LIMIT               (10 * 1000)
+
+static void do_dbs_timer(void *data);
+
+struct cpu_dbs_info_s {
+       struct cpufreq_policy   *cur_policy;
+       unsigned int            prev_cpu_idle_up;
+       unsigned int            prev_cpu_idle_down;
+       unsigned int            enable;
+};
+static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
+
+static unsigned int dbs_enable;        /* number of CPUs using this policy */
+
+static DECLARE_MUTEX   (dbs_sem);
+static DECLARE_WORK    (dbs_work, do_dbs_timer, NULL);
+
+struct dbs_tuners {
+       unsigned int            sampling_rate;
+       unsigned int            sampling_down_factor;
+       unsigned int            up_threshold;
+       unsigned int            down_threshold;
+       unsigned int            ignore_nice;
+       unsigned int            freq_step;
+};
+
+static struct dbs_tuners dbs_tuners_ins = {
+       .up_threshold           = DEF_FREQUENCY_UP_THRESHOLD,
+       .down_threshold         = DEF_FREQUENCY_DOWN_THRESHOLD,
+       .sampling_down_factor   = DEF_SAMPLING_DOWN_FACTOR,
+};
+
+static inline unsigned int get_cpu_idle_time(unsigned int cpu)
+{
+       return  kstat_cpu(cpu).cpustat.idle +
+               kstat_cpu(cpu).cpustat.iowait +
+               ( !dbs_tuners_ins.ignore_nice ? 
+                 kstat_cpu(cpu).cpustat.nice :
+                 0);
+}
+
+/************************** sysfs interface ************************/
+static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
+{
+       return sprintf (buf, "%u\n", MAX_SAMPLING_RATE);
+}
+
+static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
+{
+       return sprintf (buf, "%u\n", MIN_SAMPLING_RATE);
+}
+
+#define define_one_ro(_name)                                   \
+static struct freq_attr _name =                                \
+__ATTR(_name, 0444, show_##_name, NULL)
+
+define_one_ro(sampling_rate_max);
+define_one_ro(sampling_rate_min);
+
+/* cpufreq_conservative Governor Tunables */
+#define show_one(file_name, object)                                    \
+static ssize_t show_##file_name                                                \
+(struct cpufreq_policy *unused, char *buf)                             \
+{                                                                      \
+       return sprintf(buf, "%u\n", dbs_tuners_ins.object);             \
+}
+show_one(sampling_rate, sampling_rate);
+show_one(sampling_down_factor, sampling_down_factor);
+show_one(up_threshold, up_threshold);
+show_one(down_threshold, down_threshold);
+show_one(ignore_nice, ignore_nice);
+show_one(freq_step, freq_step);
+
+static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, 
+               const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+       ret = sscanf (buf, "%u", &input);
+       if (ret != 1 )
+               return -EINVAL;
+
+       down(&dbs_sem);
+       dbs_tuners_ins.sampling_down_factor = input;
+       up(&dbs_sem);
+
+       return count;
+}
+
+static ssize_t store_sampling_rate(struct cpufreq_policy *unused, 
+               const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+       ret = sscanf (buf, "%u", &input);
+
+       down(&dbs_sem);
+       if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
+               up(&dbs_sem);
+               return -EINVAL;
+       }
+
+       dbs_tuners_ins.sampling_rate = input;
+       up(&dbs_sem);
+
+       return count;
+}
+
+static ssize_t store_up_threshold(struct cpufreq_policy *unused, 
+               const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+       ret = sscanf (buf, "%u", &input);
+
+       down(&dbs_sem);
+       if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || 
+                       input < MIN_FREQUENCY_UP_THRESHOLD ||
+                       input <= dbs_tuners_ins.down_threshold) {
+               up(&dbs_sem);
+               return -EINVAL;
+       }
+
+       dbs_tuners_ins.up_threshold = input;
+       up(&dbs_sem);
+
+       return count;
+}
+
+static ssize_t store_down_threshold(struct cpufreq_policy *unused, 
+               const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+       ret = sscanf (buf, "%u", &input);
+
+       down(&dbs_sem);
+       if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || 
+                       input < MIN_FREQUENCY_DOWN_THRESHOLD ||
+                       input >= dbs_tuners_ins.up_threshold) {
+               up(&dbs_sem);
+               return -EINVAL;
+       }
+
+       dbs_tuners_ins.down_threshold = input;
+       up(&dbs_sem);
+
+       return count;
+}
+
+static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
+               const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+
+       unsigned int j;
+       
+       ret = sscanf (buf, "%u", &input);
+       if ( ret != 1 )
+               return -EINVAL;
+
+       if ( input > 1 )
+               input = 1;
+       
+       down(&dbs_sem);
+       if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
+               up(&dbs_sem);
+               return count;
+       }
+       dbs_tuners_ins.ignore_nice = input;
+
+       /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */
+       for_each_online_cpu(j) {
+               struct cpu_dbs_info_s *j_dbs_info;
+               j_dbs_info = &per_cpu(cpu_dbs_info, j);
+               j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
+               j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;
+       }
+       up(&dbs_sem);
+
+       return count;
+}
+
+static ssize_t store_freq_step(struct cpufreq_policy *policy,
+               const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+
+       ret = sscanf (buf, "%u", &input);
+
+       if ( ret != 1 )
+               return -EINVAL;
+
+       if ( input > 100 )
+               input = 100;
+       
+       /* no need to test here if freq_step is zero as the user might actually
+        * want this, they would be crazy though :) */
+       down(&dbs_sem);
+       dbs_tuners_ins.freq_step = input;
+       up(&dbs_sem);
+
+       return count;
+}
+
+#define define_one_rw(_name) \
+static struct freq_attr _name = \
+__ATTR(_name, 0644, show_##_name, store_##_name)
+
+define_one_rw(sampling_rate);
+define_one_rw(sampling_down_factor);
+define_one_rw(up_threshold);
+define_one_rw(down_threshold);
+define_one_rw(ignore_nice);
+define_one_rw(freq_step);
+
+static struct attribute * dbs_attributes[] = {
+       &sampling_rate_max.attr,
+       &sampling_rate_min.attr,
+       &sampling_rate.attr,
+       &sampling_down_factor.attr,
+       &up_threshold.attr,
+       &down_threshold.attr,
+       &ignore_nice.attr,
+       &freq_step.attr,
+       NULL
+};
+
+static struct attribute_group dbs_attr_group = {
+       .attrs = dbs_attributes,
+       .name = "conservative",
+};
+
+/************************** sysfs end ************************/
+
+static void dbs_check_cpu(int cpu)
+{
+       unsigned int idle_ticks, up_idle_ticks, down_idle_ticks;
+       unsigned int freq_step;
+       unsigned int freq_down_sampling_rate;
+       static int down_skip[NR_CPUS];
+       static int requested_freq[NR_CPUS];
+       static unsigned short init_flag = 0;
+       struct cpu_dbs_info_s *this_dbs_info;
+       struct cpu_dbs_info_s *dbs_info;
+
+       struct cpufreq_policy *policy;
+       unsigned int j;
+
+       this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
+       if (!this_dbs_info->enable)
+               return;
+
+       policy = this_dbs_info->cur_policy;
+
+       if ( init_flag == 0 ) {
+               for ( /* NULL */; init_flag < NR_CPUS; init_flag++ ) {
+                       dbs_info = &per_cpu(cpu_dbs_info, init_flag);
+                       requested_freq[cpu] = dbs_info->cur_policy->cur;
+               }
+               init_flag = 1;
+       }
+       
+       /* 
+        * The default safe range is 20% to 80% 
+        * Every sampling_rate, we check
+        *      - If current idle time is less than 20%, then we try to 
+        *        increase frequency
+        * Every sampling_rate*sampling_down_factor, we check
+        *      - If current idle time is more than 80%, then we try to
+        *        decrease frequency
+        *
+        * Any frequency increase takes it to the maximum frequency. 
+        * Frequency reduction happens at minimum steps of 
+        * 5% (default) of max_frequency 
+        */
+
+       /* Check for frequency increase */
+
+       idle_ticks = UINT_MAX;
+       for_each_cpu_mask(j, policy->cpus) {
+               unsigned int tmp_idle_ticks, total_idle_ticks;
+               struct cpu_dbs_info_s *j_dbs_info;
+
+               j_dbs_info = &per_cpu(cpu_dbs_info, j);
+               /* Check for frequency increase */
+               total_idle_ticks = get_cpu_idle_time(j);
+               tmp_idle_ticks = total_idle_ticks -
+                       j_dbs_info->prev_cpu_idle_up;
+               j_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+
+               if (tmp_idle_ticks < idle_ticks)
+                       idle_ticks = tmp_idle_ticks;
+       }
+
+       /* Scale idle ticks by 100 and compare with up and down ticks */
+       idle_ticks *= 100;
+       up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) *
+               usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+
+       if (idle_ticks < up_idle_ticks) {
+               down_skip[cpu] = 0;
+               for_each_cpu_mask(j, policy->cpus) {
+                       struct cpu_dbs_info_s *j_dbs_info;
+
+                       j_dbs_info = &per_cpu(cpu_dbs_info, j);
+                       j_dbs_info->prev_cpu_idle_down = 
+                                       j_dbs_info->prev_cpu_idle_up;
+               }
+               /* if we are already at full speed then break out early */
+               if (requested_freq[cpu] == policy->max)
+                       return;
+               
+               freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100;
+
+               /* max freq cannot be less than 100. But who knows.... */
+               if (unlikely(freq_step == 0))
+                       freq_step = 5;
+               
+               requested_freq[cpu] += freq_step;
+               if (requested_freq[cpu] > policy->max)
+                       requested_freq[cpu] = policy->max;
+
+               __cpufreq_driver_target(policy, requested_freq[cpu], 
+                       CPUFREQ_RELATION_H);
+               return;
+       }
+
+       /* Check for frequency decrease */
+       down_skip[cpu]++;
+       if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor)
+               return;
+
+       idle_ticks = UINT_MAX;
+       for_each_cpu_mask(j, policy->cpus) {
+               unsigned int tmp_idle_ticks, total_idle_ticks;
+               struct cpu_dbs_info_s *j_dbs_info;
+
+               j_dbs_info = &per_cpu(cpu_dbs_info, j);
+               total_idle_ticks = j_dbs_info->prev_cpu_idle_up;
+               tmp_idle_ticks = total_idle_ticks -
+                       j_dbs_info->prev_cpu_idle_down;
+               j_dbs_info->prev_cpu_idle_down = total_idle_ticks;
+
+               if (tmp_idle_ticks < idle_ticks)
+                       idle_ticks = tmp_idle_ticks;
+       }
+
+       /* Scale idle ticks by 100 and compare with up and down ticks */
+       idle_ticks *= 100;
+       down_skip[cpu] = 0;
+
+       freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
+               dbs_tuners_ins.sampling_down_factor;
+       down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) *
+                       usecs_to_jiffies(freq_down_sampling_rate);
+
+       if (idle_ticks > down_idle_ticks) {
+               /* if we are already at the lowest speed then break out early
+                * or if we 'cannot' reduce the speed as the user might want
+                * freq_step to be zero */
+               if (requested_freq[cpu] == policy->min
+                               || dbs_tuners_ins.freq_step == 0)
+                       return;
+
+               freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100;
+
+               /* max freq cannot be less than 100. But who knows.... */
+               if (unlikely(freq_step == 0))
+                       freq_step = 5;
+
+               requested_freq[cpu] -= freq_step;
+               if (requested_freq[cpu] < policy->min)
+                       requested_freq[cpu] = policy->min;
+
+               __cpufreq_driver_target(policy,
+                       requested_freq[cpu],
+                       CPUFREQ_RELATION_H);
+               return;
+       }
+}
+
+static void do_dbs_timer(void *data)
+{ 
+       int i;
+       down(&dbs_sem);
+       for_each_online_cpu(i)
+               dbs_check_cpu(i);
+       schedule_delayed_work(&dbs_work, 
+                       usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
+       up(&dbs_sem);
+} 
+
+static inline void dbs_timer_init(void)
+{
+       INIT_WORK(&dbs_work, do_dbs_timer, NULL);
+       schedule_delayed_work(&dbs_work,
+                       usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
+       return;
+}
+
+static inline void dbs_timer_exit(void)
+{
+       cancel_delayed_work(&dbs_work);
+       return;
+}
+
+static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+                                  unsigned int event)
+{
+       unsigned int cpu = policy->cpu;
+       struct cpu_dbs_info_s *this_dbs_info;
+       unsigned int j;
+
+       this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
+
+       switch (event) {
+       case CPUFREQ_GOV_START:
+               if ((!cpu_online(cpu)) || 
+                   (!policy->cur))
+                       return -EINVAL;
+
+               if (policy->cpuinfo.transition_latency >
+                               (TRANSITION_LATENCY_LIMIT * 1000))
+                       return -EINVAL;
+               if (this_dbs_info->enable) /* Already enabled */
+                       break;
+                
+               down(&dbs_sem);
+               for_each_cpu_mask(j, policy->cpus) {
+                       struct cpu_dbs_info_s *j_dbs_info;
+                       j_dbs_info = &per_cpu(cpu_dbs_info, j);
+                       j_dbs_info->cur_policy = policy;
+               
+                       j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
+                       j_dbs_info->prev_cpu_idle_down
+                               = j_dbs_info->prev_cpu_idle_up;
+               }
+               this_dbs_info->enable = 1;
+               sysfs_create_group(&policy->kobj, &dbs_attr_group);
+               dbs_enable++;
+               /*
+                * Start the timerschedule work, when this governor
+                * is used for first time
+                */
+               if (dbs_enable == 1) {
+                       unsigned int latency;
+                       /* policy latency is in nS. Convert it to uS first */
+
+                       latency = policy->cpuinfo.transition_latency;
+                       if (latency < 1000)
+                               latency = 1000;
+
+                       def_sampling_rate = (latency / 1000) *
+                                       DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
+                       dbs_tuners_ins.sampling_rate = def_sampling_rate;
+                       dbs_tuners_ins.ignore_nice = 0;
+                       dbs_tuners_ins.freq_step = 5;
+
+                       dbs_timer_init();
+               }
+               
+               up(&dbs_sem);
+               break;
+
+       case CPUFREQ_GOV_STOP:
+               down(&dbs_sem);
+               this_dbs_info->enable = 0;
+               sysfs_remove_group(&policy->kobj, &dbs_attr_group);
+               dbs_enable--;
+               /*
+                * Stop the timerschedule work, when this governor
+                * is used for first time
+                */
+               if (dbs_enable == 0) 
+                       dbs_timer_exit();
+               
+               up(&dbs_sem);
+
+               break;
+
+       case CPUFREQ_GOV_LIMITS:
+               down(&dbs_sem);
+               if (policy->max < this_dbs_info->cur_policy->cur)
+                       __cpufreq_driver_target(
+                                       this_dbs_info->cur_policy,
+                                       policy->max, CPUFREQ_RELATION_H);
+               else if (policy->min > this_dbs_info->cur_policy->cur)
+                       __cpufreq_driver_target(
+                                       this_dbs_info->cur_policy,
+                                       policy->min, CPUFREQ_RELATION_L);
+               up(&dbs_sem);
+               break;
+       }
+       return 0;
+}
+
+static struct cpufreq_governor cpufreq_gov_dbs = {
+       .name           = "conservative",
+       .governor       = cpufreq_governor_dbs,
+       .owner          = THIS_MODULE,
+};
+
+static int __init cpufreq_gov_dbs_init(void)
+{
+       return cpufreq_register_governor(&cpufreq_gov_dbs);
+}
+
+static void __exit cpufreq_gov_dbs_exit(void)
+{
+       /* Make sure that the scheduled work is indeed not running */
+       flush_scheduled_work();
+
+       cpufreq_unregister_governor(&cpufreq_gov_dbs);
+}
+
+
+MODULE_AUTHOR ("Alexander Clouter <alex-kernel@digriz.org.uk>");
+MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for "
+               "Low Latency Frequency Transition capable processors "
+               "optimised for use in a battery environment");
+MODULE_LICENSE ("GPL");
+
+module_init(cpufreq_gov_dbs_init);
+module_exit(cpufreq_gov_dbs_exit);
index 8d83a21c6477f3e7a3cd223a9bffa4e8b1af1710..c1fc9c62bb51d0c1d2620f522d7c6ebbb0f432bc 100644 (file)
  */
 
 #define DEF_FREQUENCY_UP_THRESHOLD             (80)
-#define MIN_FREQUENCY_UP_THRESHOLD             (0)
+#define MIN_FREQUENCY_UP_THRESHOLD             (11)
 #define MAX_FREQUENCY_UP_THRESHOLD             (100)
 
-#define DEF_FREQUENCY_DOWN_THRESHOLD           (20)
-#define MIN_FREQUENCY_DOWN_THRESHOLD           (0)
-#define MAX_FREQUENCY_DOWN_THRESHOLD           (100)
-
 /* 
  * The polling frequency of this governor depends on the capability of 
  * the processor. Default polling frequency is 1000 times the transition
@@ -55,9 +51,9 @@ static unsigned int                           def_sampling_rate;
 #define MIN_SAMPLING_RATE                      (def_sampling_rate / 2)
 #define MAX_SAMPLING_RATE                      (500 * def_sampling_rate)
 #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER   (1000)
-#define DEF_SAMPLING_DOWN_FACTOR               (10)
+#define DEF_SAMPLING_DOWN_FACTOR               (1)
+#define MAX_SAMPLING_DOWN_FACTOR               (10)
 #define TRANSITION_LATENCY_LIMIT               (10 * 1000)
-#define sampling_rate_in_HZ(x)                 (((x * HZ) < (1000 * 1000))?1:((x * HZ) / (1000 * 1000)))
 
 static void do_dbs_timer(void *data);
 
@@ -78,15 +74,23 @@ struct dbs_tuners {
        unsigned int            sampling_rate;
        unsigned int            sampling_down_factor;
        unsigned int            up_threshold;
-       unsigned int            down_threshold;
+       unsigned int            ignore_nice;
 };
 
 static struct dbs_tuners dbs_tuners_ins = {
        .up_threshold           = DEF_FREQUENCY_UP_THRESHOLD,
-       .down_threshold         = DEF_FREQUENCY_DOWN_THRESHOLD,
        .sampling_down_factor   = DEF_SAMPLING_DOWN_FACTOR,
 };
 
+static inline unsigned int get_cpu_idle_time(unsigned int cpu)
+{
+       return  kstat_cpu(cpu).cpustat.idle +
+               kstat_cpu(cpu).cpustat.iowait +
+               ( !dbs_tuners_ins.ignore_nice ? 
+                 kstat_cpu(cpu).cpustat.nice :
+                 0);
+}
+
 /************************** sysfs interface ************************/
 static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
 {
@@ -115,7 +119,7 @@ static ssize_t show_##file_name                                             \
 show_one(sampling_rate, sampling_rate);
 show_one(sampling_down_factor, sampling_down_factor);
 show_one(up_threshold, up_threshold);
-show_one(down_threshold, down_threshold);
+show_one(ignore_nice, ignore_nice);
 
 static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, 
                const char *buf, size_t count)
@@ -126,6 +130,9 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
        if (ret != 1 )
                return -EINVAL;
 
+       if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
+               return -EINVAL;
+
        down(&dbs_sem);
        dbs_tuners_ins.sampling_down_factor = input;
        up(&dbs_sem);
@@ -161,8 +168,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
 
        down(&dbs_sem);
        if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || 
-                       input < MIN_FREQUENCY_UP_THRESHOLD ||
-                       input <= dbs_tuners_ins.down_threshold) {
+                       input < MIN_FREQUENCY_UP_THRESHOLD) {
                up(&dbs_sem);
                return -EINVAL;
        }
@@ -173,22 +179,35 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
        return count;
 }
 
-static ssize_t store_down_threshold(struct cpufreq_policy *unused, 
+static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
                const char *buf, size_t count)
 {
        unsigned int input;
        int ret;
+
+       unsigned int j;
+       
        ret = sscanf (buf, "%u", &input);
+       if ( ret != 1 )
+               return -EINVAL;
 
+       if ( input > 1 )
+               input = 1;
+       
        down(&dbs_sem);
-       if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || 
-                       input < MIN_FREQUENCY_DOWN_THRESHOLD ||
-                       input >= dbs_tuners_ins.up_threshold) {
+       if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
                up(&dbs_sem);
-               return -EINVAL;
+               return count;
        }
+       dbs_tuners_ins.ignore_nice = input;
 
-       dbs_tuners_ins.down_threshold = input;
+       /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */
+       for_each_online_cpu(j) {
+               struct cpu_dbs_info_s *j_dbs_info;
+               j_dbs_info = &per_cpu(cpu_dbs_info, j);
+               j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
+               j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;
+       }
        up(&dbs_sem);
 
        return count;
@@ -201,7 +220,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
 define_one_rw(sampling_rate);
 define_one_rw(sampling_down_factor);
 define_one_rw(up_threshold);
-define_one_rw(down_threshold);
+define_one_rw(ignore_nice);
 
 static struct attribute * dbs_attributes[] = {
        &sampling_rate_max.attr,
@@ -209,7 +228,7 @@ static struct attribute * dbs_attributes[] = {
        &sampling_rate.attr,
        &sampling_down_factor.attr,
        &up_threshold.attr,
-       &down_threshold.attr,
+       &ignore_nice.attr,
        NULL
 };
 
@@ -222,9 +241,8 @@ static struct attribute_group dbs_attr_group = {
 
 static void dbs_check_cpu(int cpu)
 {
-       unsigned int idle_ticks, up_idle_ticks, down_idle_ticks;
-       unsigned int total_idle_ticks;
-       unsigned int freq_down_step;
+       unsigned int idle_ticks, up_idle_ticks, total_ticks;
+       unsigned int freq_next;
        unsigned int freq_down_sampling_rate;
        static int down_skip[NR_CPUS];
        struct cpu_dbs_info_s *this_dbs_info;
@@ -238,38 +256,25 @@ static void dbs_check_cpu(int cpu)
 
        policy = this_dbs_info->cur_policy;
        /* 
-        * The default safe range is 20% to 80% 
-        * Every sampling_rate, we check
-        *      - If current idle time is less than 20%, then we try to 
-        *        increase frequency
-        * Every sampling_rate*sampling_down_factor, we check
-        *      - If current idle time is more than 80%, then we try to
-        *        decrease frequency
+        * Every sampling_rate, we check, if current idle time is less
+        * than 20% (default), then we try to increase frequency
+        * Every sampling_rate*sampling_down_factor, we look for a the lowest
+        * frequency which can sustain the load while keeping idle time over
+        * 30%. If such a frequency exist, we try to decrease to this frequency.
         *
         * Any frequency increase takes it to the maximum frequency. 
         * Frequency reduction happens at minimum steps of 
-        * 5% of max_frequency 
+        * 5% (default) of current frequency 
         */
 
        /* Check for frequency increase */
-       total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
-               kstat_cpu(cpu).cpustat.iowait;
-       idle_ticks = total_idle_ticks -
-               this_dbs_info->prev_cpu_idle_up;
-       this_dbs_info->prev_cpu_idle_up = total_idle_ticks;
-       
-
+       idle_ticks = UINT_MAX;
        for_each_cpu_mask(j, policy->cpus) {
-               unsigned int tmp_idle_ticks;
+               unsigned int tmp_idle_ticks, total_idle_ticks;
                struct cpu_dbs_info_s *j_dbs_info;
 
-               if (j == cpu)
-                       continue;
-
                j_dbs_info = &per_cpu(cpu_dbs_info, j);
-               /* Check for frequency increase */
-               total_idle_ticks = kstat_cpu(j).cpustat.idle +
-                       kstat_cpu(j).cpustat.iowait;
+               total_idle_ticks = get_cpu_idle_time(j);
                tmp_idle_ticks = total_idle_ticks -
                        j_dbs_info->prev_cpu_idle_up;
                j_dbs_info->prev_cpu_idle_up = total_idle_ticks;
@@ -281,13 +286,23 @@ static void dbs_check_cpu(int cpu)
        /* Scale idle ticks by 100 and compare with up and down ticks */
        idle_ticks *= 100;
        up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) *
-                       sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate);
+                       usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
 
        if (idle_ticks < up_idle_ticks) {
+               down_skip[cpu] = 0;
+               for_each_cpu_mask(j, policy->cpus) {
+                       struct cpu_dbs_info_s *j_dbs_info;
+
+                       j_dbs_info = &per_cpu(cpu_dbs_info, j);
+                       j_dbs_info->prev_cpu_idle_down = 
+                                       j_dbs_info->prev_cpu_idle_up;
+               }
+               /* if we are already at full speed then break out early */
+               if (policy->cur == policy->max)
+                       return;
+               
                __cpufreq_driver_target(policy, policy->max, 
                        CPUFREQ_RELATION_H);
-               down_skip[cpu] = 0;
-               this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
                return;
        }
 
@@ -296,23 +311,14 @@ static void dbs_check_cpu(int cpu)
        if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor)
                return;
 
-       total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
-               kstat_cpu(cpu).cpustat.iowait;
-       idle_ticks = total_idle_ticks -
-               this_dbs_info->prev_cpu_idle_down;
-       this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
-
+       idle_ticks = UINT_MAX;
        for_each_cpu_mask(j, policy->cpus) {
-               unsigned int tmp_idle_ticks;
+               unsigned int tmp_idle_ticks, total_idle_ticks;
                struct cpu_dbs_info_s *j_dbs_info;
 
-               if (j == cpu)
-                       continue;
-
                j_dbs_info = &per_cpu(cpu_dbs_info, j);
-               /* Check for frequency increase */
-               total_idle_ticks = kstat_cpu(j).cpustat.idle +
-                       kstat_cpu(j).cpustat.iowait;
+               /* Check for frequency decrease */
+               total_idle_ticks = j_dbs_info->prev_cpu_idle_up;
                tmp_idle_ticks = total_idle_ticks -
                        j_dbs_info->prev_cpu_idle_down;
                j_dbs_info->prev_cpu_idle_down = total_idle_ticks;
@@ -321,38 +327,37 @@ static void dbs_check_cpu(int cpu)
                        idle_ticks = tmp_idle_ticks;
        }
 
-       /* Scale idle ticks by 100 and compare with up and down ticks */
-       idle_ticks *= 100;
        down_skip[cpu] = 0;
+       /* if we cannot reduce the frequency anymore, break out early */
+       if (policy->cur == policy->min)
+               return;
 
+       /* Compute how many ticks there are between two measurements */
        freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
                dbs_tuners_ins.sampling_down_factor;
-       down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) *
-                       sampling_rate_in_HZ(freq_down_sampling_rate);
+       total_ticks = usecs_to_jiffies(freq_down_sampling_rate);
 
-       if (idle_ticks > down_idle_ticks ) {
-               freq_down_step = (5 * policy->max) / 100;
-
-               /* max freq cannot be less than 100. But who knows.... */
-               if (unlikely(freq_down_step == 0))
-                       freq_down_step = 5;
+       /*
+        * The optimal frequency is the frequency that is the lowest that
+        * can support the current CPU usage without triggering the up
+        * policy. To be safe, we focus 10 points under the threshold.
+        */
+       freq_next = ((total_ticks - idle_ticks) * 100) / total_ticks;
+       freq_next = (freq_next * policy->cur) / 
+                       (dbs_tuners_ins.up_threshold - 10);
 
-               __cpufreq_driver_target(policy,
-                       policy->cur - freq_down_step, 
-                       CPUFREQ_RELATION_H);
-               return;
-       }
+       if (freq_next <= ((policy->cur * 95) / 100))
+               __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L);
 }
 
 static void do_dbs_timer(void *data)
 { 
        int i;
        down(&dbs_sem);
-       for (i = 0; i < NR_CPUS; i++)
-               if (cpu_online(i))
-                       dbs_check_cpu(i);
+       for_each_online_cpu(i)
+               dbs_check_cpu(i);
        schedule_delayed_work(&dbs_work, 
-                       sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate));
+                       usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
        up(&dbs_sem);
 } 
 
@@ -360,7 +365,7 @@ static inline void dbs_timer_init(void)
 {
        INIT_WORK(&dbs_work, do_dbs_timer, NULL);
        schedule_delayed_work(&dbs_work,
-                       sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate));
+                       usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
        return;
 }
 
@@ -397,12 +402,9 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        j_dbs_info = &per_cpu(cpu_dbs_info, j);
                        j_dbs_info->cur_policy = policy;
                
-                       j_dbs_info->prev_cpu_idle_up = 
-                               kstat_cpu(j).cpustat.idle +
-                               kstat_cpu(j).cpustat.iowait;
-                       j_dbs_info->prev_cpu_idle_down = 
-                               kstat_cpu(j).cpustat.idle +
-                               kstat_cpu(j).cpustat.iowait;
+                       j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
+                       j_dbs_info->prev_cpu_idle_down
+                               = j_dbs_info->prev_cpu_idle_up;
                }
                this_dbs_info->enable = 1;
                sysfs_create_group(&policy->kobj, &dbs_attr_group);
@@ -422,6 +424,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        def_sampling_rate = (latency / 1000) *
                                        DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
                        dbs_tuners_ins.sampling_rate = def_sampling_rate;
+                       dbs_tuners_ins.ignore_nice = 0;
 
                        dbs_timer_init();
                }
@@ -461,12 +464,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
        return 0;
 }
 
-struct cpufreq_governor cpufreq_gov_dbs = {
+static struct cpufreq_governor cpufreq_gov_dbs = {
        .name           = "ondemand",
        .governor       = cpufreq_governor_dbs,
        .owner          = THIS_MODULE,
 };
-EXPORT_SYMBOL(cpufreq_gov_dbs);
 
 static int __init cpufreq_gov_dbs_init(void)
 {
index 2084593937c6382508ee75b0701fb7d49636046a..741b6b191e6a2ca667b5ab6f36888279cb9823ce 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/percpu.h>
 #include <linux/kobject.h>
 #include <linux/spinlock.h>
+#include <asm/cputime.h>
 
 static spinlock_t cpufreq_stats_lock;
 
@@ -29,20 +30,14 @@ static struct freq_attr _attr_##_name = {\
        .show = _show,\
 };
 
-static unsigned long
-delta_time(unsigned long old, unsigned long new)
-{
-       return (old > new) ? (old - new): (new + ~old + 1);
-}
-
 struct cpufreq_stats {
        unsigned int cpu;
        unsigned int total_trans;
-       unsigned long long last_time;
+       unsigned long long  last_time;
        unsigned int max_state;
        unsigned int state_num;
        unsigned int last_index;
-       unsigned long long *time_in_state;
+       cputime64_t *time_in_state;
        unsigned int *freq_table;
 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
        unsigned int *trans_table;
@@ -60,12 +55,16 @@ static int
 cpufreq_stats_update (unsigned int cpu)
 {
        struct cpufreq_stats *stat;
+       unsigned long long cur_time;
+
+       cur_time = get_jiffies_64();
        spin_lock(&cpufreq_stats_lock);
        stat = cpufreq_stats_table[cpu];
        if (stat->time_in_state)
-               stat->time_in_state[stat->last_index] +=
-                       delta_time(stat->last_time, jiffies);
-       stat->last_time = jiffies;
+               stat->time_in_state[stat->last_index] =
+                       cputime64_add(stat->time_in_state[stat->last_index],
+                                     cputime_sub(cur_time, stat->last_time));
+       stat->last_time = cur_time;
        spin_unlock(&cpufreq_stats_lock);
        return 0;
 }
@@ -90,8 +89,8 @@ show_time_in_state(struct cpufreq_policy *policy, char *buf)
                return 0;
        cpufreq_stats_update(stat->cpu);
        for (i = 0; i < stat->state_num; i++) {
-               len += sprintf(buf + len, "%u %llu\n",
-                       stat->freq_table[i], stat->time_in_state[i]);
+               len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], 
+                       (unsigned long long)cputime64_to_clock_t(stat->time_in_state[i]));
        }
        return len;
 }
@@ -107,16 +106,30 @@ show_trans_table(struct cpufreq_policy *policy, char *buf)
        if(!stat)
                return 0;
        cpufreq_stats_update(stat->cpu);
+       len += snprintf(buf + len, PAGE_SIZE - len, "   From  :    To\n");
+       len += snprintf(buf + len, PAGE_SIZE - len, "         : ");
+       for (i = 0; i < stat->state_num; i++) {
+               if (len >= PAGE_SIZE)
+                       break;
+               len += snprintf(buf + len, PAGE_SIZE - len, "%9u ",
+                               stat->freq_table[i]);
+       }
+       if (len >= PAGE_SIZE)
+               return len;
+
+       len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+
        for (i = 0; i < stat->state_num; i++) {
                if (len >= PAGE_SIZE)
                        break;
-               len += snprintf(buf + len, PAGE_SIZE - len, "%9u:\t",
+
+               len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ",
                                stat->freq_table[i]);
 
                for (j = 0; j < stat->state_num; j++)   {
                        if (len >= PAGE_SIZE)
                                break;
-                       len += snprintf(buf + len, PAGE_SIZE - len, "%u\t",
+                       len += snprintf(buf + len, PAGE_SIZE - len, "%9u ",
                                        stat->trans_table[i*stat->max_state+j]);
                }
                len += snprintf(buf + len, PAGE_SIZE - len, "\n");
@@ -197,7 +210,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
                count++;
        }
 
-       alloc_size = count * sizeof(int) + count * sizeof(long long);
+       alloc_size = count * sizeof(int) + count * sizeof(cputime64_t);
 
 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
        alloc_size += count * count * sizeof(int);
@@ -224,7 +237,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
        }
        stat->state_num = j;
        spin_lock(&cpufreq_stats_lock);
-       stat->last_time = jiffies;
+       stat->last_time = get_jiffies_64();
        stat->last_index = freq_table_get_index(stat, policy->cur);
        spin_unlock(&cpufreq_stats_lock);
        cpufreq_cpu_put(data);
index 6d5df6c2efa2ff3044610736aeaf79326396b182..df1b721154d2728504541e023a43701db5e6d2f5 100644 (file)
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/config.h>
 #include <linux/acpi.h>
 #include <linux/console.h>
 #include <linux/efi.h>
index 35710818fe47cbfaf78b5070c59a4c85fabee641..fdd881aee618172df04f70977ee4cb4a57e7d58c 100644 (file)
@@ -2,6 +2,7 @@
  *     i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge
  *
  *     Copyright (C) 2004 Patrick Mochel
+ *                   2005 Rudolf Marek <r.marek@sh.cvut.cz>
  *
  *     The 1563 southbridge is deceptively similar to the 1533, with a
  *     few notable exceptions. One of those happens to be the fact they
 #define HST_CNTL2_BLOCK                0x05
 
 
+#define HST_CNTL2_SIZEMASK     0x38
 
 static unsigned short ali1563_smba;
 
-static int ali1563_transaction(struct i2c_adapter * a)
+static int ali1563_transaction(struct i2c_adapter * a, int size)
 {
        u32 data;
        int timeout;
@@ -73,7 +75,7 @@ static int ali1563_transaction(struct i2c_adapter * a)
 
        data = inb_p(SMB_HST_STS);
        if (data & HST_STS_BAD) {
-               dev_warn(&a->dev,"ali1563: Trying to reset busy device\n");
+               dev_err(&a->dev, "ali1563: Trying to reset busy device\n");
                outb_p(data | HST_STS_BAD,SMB_HST_STS);
                data = inb_p(SMB_HST_STS);
                if (data & HST_STS_BAD)
@@ -94,19 +96,31 @@ static int ali1563_transaction(struct i2c_adapter * a)
 
        if (timeout && !(data & HST_STS_BAD))
                return 0;
-       dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n",
-               timeout ? "Timeout " : "",
-               data & HST_STS_FAIL ? "Transaction Failed " : "",
-               data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
-               data & HST_STS_DEVERR ? "Device Error " : "",
-               !(data & HST_STS_DONE) ? "Transaction Never Finished " : "");
 
-       if (!(data & HST_STS_DONE))
+       if (!timeout) {
+               dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n");
                /* Issue 'kill' to host controller */
                outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2);
-       else
-               /* Issue timeout to reset all devices on bus */
+               data = inb_p(SMB_HST_STS);
+       }
+
+       /* device error - no response, ignore the autodetection case */
+       if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) {
+               dev_err(&a->dev, "Device error!\n");
+       }
+
+       /* bus collision */
+       if (data & HST_STS_BUSERR) {
+               dev_err(&a->dev, "Bus collision!\n");
+               /* Issue timeout, hoping it helps */
                outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1);
+       }
+
+       if (data & HST_STS_FAIL) {
+               dev_err(&a->dev, "Cleaning fail after KILL!\n");
+               outb_p(0x0,SMB_HST_CNTL2);
+       }
+
        return -1;
 }
 
@@ -149,7 +163,7 @@ static int ali1563_block_start(struct i2c_adapter * a)
 
        if (timeout && !(data & HST_STS_BAD))
                return 0;
-       dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n",
+       dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n",
                timeout ? "Timeout " : "",
                data & HST_STS_FAIL ? "Transaction Failed " : "",
                data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
@@ -242,13 +256,15 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr,
        }
 
        outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD);
-       outb_p(inb_p(SMB_HST_CNTL2) | (size << 3), SMB_HST_CNTL2);
+       outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2);
 
        /* Write the command register */
+
        switch(size) {
        case HST_CNTL2_BYTE:
                if (rw== I2C_SMBUS_WRITE)
-                       outb_p(cmd, SMB_HST_CMD);
+                       /* Beware it uses DAT0 register and not CMD! */
+                       outb_p(cmd, SMB_HST_DAT0);
                break;
        case HST_CNTL2_BYTE_DATA:
                outb_p(cmd, SMB_HST_CMD);
@@ -268,7 +284,7 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr,
                goto Done;
        }
 
-       if ((error = ali1563_transaction(a)))
+       if ((error = ali1563_transaction(a, size)))
                goto Done;
 
        if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK))
index dd0d4c463146be33d9469c2f434ddbed4d96d615..867d443e7133f03c1f8999e4fe25e38f76f9419f 100644 (file)
@@ -516,6 +516,11 @@ create_iface(struct device_node *np, struct device *dev)
        u32 *psteps, *prate;
        int rc;
 
+       if (np->n_intrs < 1 || np->n_addrs < 1) {
+               printk(KERN_ERR "%s: Missing interrupt or address !\n",
+                      np->full_name);
+               return -ENODEV;
+       }
        if (pmac_low_i2c_lock(np))
                return -ENODEV;
 
index 33a020faeabde258ef0b0e6903480f74a4f1b2d6..39f3e9101ed4b9eebb45237de5d1d3c982063d89 100644 (file)
@@ -1932,8 +1932,11 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 
                /*
                 * check if dma is safe
+                *
+                * NOTE! The "len" and "addr" checks should possibly have
+                * separate masks.
                 */
-               if ((rq->data_len & mask) || (addr & mask))
+               if ((rq->data_len & 15) || (addr & mask))
                        info->dma = 0;
        }
 
@@ -3255,16 +3258,12 @@ sector_t ide_cdrom_capacity (ide_drive_t *drive)
        return capacity * sectors_per_frame;
 }
 
-static
-int ide_cdrom_cleanup(ide_drive_t *drive)
+static int ide_cd_remove(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        struct cdrom_info *info = drive->driver_data;
 
-       if (ide_unregister_subdriver(drive)) {
-               printk(KERN_ERR "%s: %s: failed to ide_unregister_subdriver\n",
-                       __FUNCTION__, drive->name);
-               return 1;
-       }
+       ide_unregister_subdriver(drive, info->driver);
 
        del_gendisk(info->disk);
 
@@ -3297,7 +3296,7 @@ static void ide_cd_release(struct kref *kref)
        kfree(info);
 }
 
-static int ide_cdrom_attach (ide_drive_t *drive);
+static int ide_cd_probe(struct device *);
 
 #ifdef CONFIG_PROC_FS
 static int proc_idecd_read_capacity
@@ -3320,19 +3319,20 @@ static ide_proc_entry_t idecd_proc[] = {
 
 static ide_driver_t ide_cdrom_driver = {
        .owner                  = THIS_MODULE,
-       .name                   = "ide-cdrom",
+       .gen_driver = {
+               .name           = "ide-cdrom",
+               .bus            = &ide_bus_type,
+               .probe          = ide_cd_probe,
+               .remove         = ide_cd_remove,
+       },
        .version                = IDECD_VERSION,
        .media                  = ide_cdrom,
-       .busy                   = 0,
        .supports_dsc_overlap   = 1,
-       .cleanup                = ide_cdrom_cleanup,
        .do_request             = ide_do_rw_cdrom,
        .end_request            = ide_end_request,
        .error                  = __ide_error,
        .abort                  = __ide_abort,
        .proc                   = idecd_proc,
-       .attach                 = ide_cdrom_attach,
-       .drives                 = LIST_HEAD_INIT(ide_cdrom_driver.drives),
 };
 
 static int idecd_open(struct inode * inode, struct file * file)
@@ -3418,8 +3418,9 @@ static char *ignore = NULL;
 module_param(ignore, charp, 0400);
 MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
 
-static int ide_cdrom_attach (ide_drive_t *drive)
+static int ide_cd_probe(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        struct cdrom_info *info;
        struct gendisk *g;
        struct request_sense sense;
@@ -3453,11 +3454,8 @@ static int ide_cdrom_attach (ide_drive_t *drive)
 
        ide_init_disk(g, drive);
 
-       if (ide_register_subdriver(drive, &ide_cdrom_driver)) {
-               printk(KERN_ERR "%s: Failed to register the driver with ide.c\n",
-                       drive->name);
-               goto out_put_disk;
-       }
+       ide_register_subdriver(drive, &ide_cdrom_driver);
+
        memset(info, 0, sizeof (struct cdrom_info));
 
        kref_init(&info->kref);
@@ -3470,7 +3468,6 @@ static int ide_cdrom_attach (ide_drive_t *drive)
 
        drive->driver_data = info;
 
-       DRIVER(drive)->busy++;
        g->minors = 1;
        snprintf(g->devfs_name, sizeof(g->devfs_name),
                        "%s/cd", drive->devfs_name);
@@ -3478,8 +3475,7 @@ static int ide_cdrom_attach (ide_drive_t *drive)
        g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
        if (ide_cdrom_setup(drive)) {
                struct cdrom_device_info *devinfo = &info->devinfo;
-               DRIVER(drive)->busy--;
-               ide_unregister_subdriver(drive);
+               ide_unregister_subdriver(drive, &ide_cdrom_driver);
                if (info->buffer != NULL)
                        kfree(info->buffer);
                if (info->toc != NULL)
@@ -3492,7 +3488,6 @@ static int ide_cdrom_attach (ide_drive_t *drive)
                drive->driver_data = NULL;
                goto failed;
        }
-       DRIVER(drive)->busy--;
 
        cdrom_read_toc(drive, &sense);
        g->fops = &idecd_ops;
@@ -3500,23 +3495,20 @@ static int ide_cdrom_attach (ide_drive_t *drive)
        add_disk(g);
        return 0;
 
-out_put_disk:
-       put_disk(g);
 out_free_cd:
        kfree(info);
 failed:
-       return 1;
+       return -ENODEV;
 }
 
 static void __exit ide_cdrom_exit(void)
 {
-       ide_unregister_driver(&ide_cdrom_driver);
+       driver_unregister(&ide_cdrom_driver.gen_driver);
 }
  
 static int ide_cdrom_init(void)
 {
-       ide_register_driver(&ide_cdrom_driver);
-       return 0;
+       return driver_register(&ide_cdrom_driver.gen_driver);
 }
 
 module_init(ide_cdrom_init);
index 5d54f77561007f1622c632d1fa1dbc7886a02a51..3302cd8eab4c160caf430c1a22268abcc024e5e9 100644 (file)
@@ -1024,14 +1024,16 @@ static void ide_cacheflush_p(ide_drive_t *drive)
                printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
 }
 
-static int idedisk_cleanup (ide_drive_t *drive)
+static int ide_disk_remove(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        struct ide_disk_obj *idkp = drive->driver_data;
        struct gendisk *g = idkp->disk;
 
        ide_cacheflush_p(drive);
-       if (ide_unregister_subdriver(drive))
-               return 1;
+
+       ide_unregister_subdriver(drive, idkp->driver);
+
        del_gendisk(g);
 
        ide_disk_put(idkp);
@@ -1052,7 +1054,7 @@ static void ide_disk_release(struct kref *kref)
        kfree(idkp);
 }
 
-static int idedisk_attach(ide_drive_t *drive);
+static int ide_disk_probe(struct device *dev);
 
 static void ide_device_shutdown(struct device *dev)
 {
@@ -1082,27 +1084,23 @@ static void ide_device_shutdown(struct device *dev)
        dev->bus->suspend(dev, PMSG_SUSPEND);
 }
 
-/*
- *      IDE subdriver functions, registered with ide.c
- */
 static ide_driver_t idedisk_driver = {
        .owner                  = THIS_MODULE,
        .gen_driver = {
+               .name           = "ide-disk",
+               .bus            = &ide_bus_type,
+               .probe          = ide_disk_probe,
+               .remove         = ide_disk_remove,
                .shutdown       = ide_device_shutdown,
        },
-       .name                   = "ide-disk",
        .version                = IDEDISK_VERSION,
        .media                  = ide_disk,
-       .busy                   = 0,
        .supports_dsc_overlap   = 0,
-       .cleanup                = idedisk_cleanup,
        .do_request             = ide_do_rw_disk,
        .end_request            = ide_end_request,
        .error                  = __ide_error,
        .abort                  = __ide_abort,
        .proc                   = idedisk_proc,
-       .attach                 = idedisk_attach,
-       .drives                 = LIST_HEAD_INIT(idedisk_driver.drives),
 };
 
 static int idedisk_open(struct inode *inode, struct file *filp)
@@ -1199,8 +1197,9 @@ static struct block_device_operations idedisk_ops = {
 
 MODULE_DESCRIPTION("ATA DISK Driver");
 
-static int idedisk_attach(ide_drive_t *drive)
+static int ide_disk_probe(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        struct ide_disk_obj *idkp;
        struct gendisk *g;
 
@@ -1222,10 +1221,7 @@ static int idedisk_attach(ide_drive_t *drive)
 
        ide_init_disk(g, drive);
 
-       if (ide_register_subdriver(drive, &idedisk_driver)) {
-               printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name);
-               goto out_put_disk;
-       }
+       ide_register_subdriver(drive, &idedisk_driver);
 
        memset(idkp, 0, sizeof(*idkp));
 
@@ -1239,7 +1235,6 @@ static int idedisk_attach(ide_drive_t *drive)
 
        drive->driver_data = idkp;
 
-       DRIVER(drive)->busy++;
        idedisk_setup(drive);
        if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
                printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
@@ -1247,7 +1242,7 @@ static int idedisk_attach(ide_drive_t *drive)
                drive->attach = 0;
        } else
                drive->attach = 1;
-       DRIVER(drive)->busy--;
+
        g->minors = 1 << PARTN_BITS;
        strcpy(g->devfs_name, drive->devfs_name);
        g->driverfs_dev = &drive->gendev;
@@ -1257,22 +1252,20 @@ static int idedisk_attach(ide_drive_t *drive)
        add_disk(g);
        return 0;
 
-out_put_disk:
-       put_disk(g);
 out_free_idkp:
        kfree(idkp);
 failed:
-       return 1;
+       return -ENODEV;
 }
 
 static void __exit idedisk_exit (void)
 {
-       ide_unregister_driver(&idedisk_driver);
+       driver_unregister(&idedisk_driver.gen_driver);
 }
 
 static int idedisk_init (void)
 {
-       return ide_register_driver(&idedisk_driver);
+       return driver_register(&idedisk_driver.gen_driver);
 }
 
 module_init(idedisk_init);
index 36c0b74a4e45b69dd4e0f5d71671bf5ba3781d83..c949e98df4b6da35da013d26ddb1b2d979cb36b4 100644 (file)
@@ -1865,13 +1865,13 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
        idefloppy_add_settings(drive);
 }
 
-static int idefloppy_cleanup (ide_drive_t *drive)
+static int ide_floppy_remove(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        idefloppy_floppy_t *floppy = drive->driver_data;
        struct gendisk *g = floppy->disk;
 
-       if (ide_unregister_subdriver(drive))
-               return 1;
+       ide_unregister_subdriver(drive, floppy->driver);
 
        del_gendisk(g);
 
@@ -1916,26 +1916,24 @@ static ide_proc_entry_t idefloppy_proc[] = {
 
 #endif /* CONFIG_PROC_FS */
 
-static int idefloppy_attach(ide_drive_t *drive);
+static int ide_floppy_probe(struct device *);
 
-/*
- *     IDE subdriver functions, registered with ide.c
- */
 static ide_driver_t idefloppy_driver = {
        .owner                  = THIS_MODULE,
-       .name                   = "ide-floppy",
+       .gen_driver = {
+               .name           = "ide-floppy",
+               .bus            = &ide_bus_type,
+               .probe          = ide_floppy_probe,
+               .remove         = ide_floppy_remove,
+       },
        .version                = IDEFLOPPY_VERSION,
        .media                  = ide_floppy,
-       .busy                   = 0,
        .supports_dsc_overlap   = 0,
-       .cleanup                = idefloppy_cleanup,
        .do_request             = idefloppy_do_request,
        .end_request            = idefloppy_do_end_request,
        .error                  = __ide_error,
        .abort                  = __ide_abort,
        .proc                   = idefloppy_proc,
-       .attach                 = idefloppy_attach,
-       .drives                 = LIST_HEAD_INIT(idefloppy_driver.drives),
 };
 
 static int idefloppy_open(struct inode *inode, struct file *filp)
@@ -2122,8 +2120,9 @@ static struct block_device_operations idefloppy_ops = {
        .revalidate_disk= idefloppy_revalidate_disk
 };
 
-static int idefloppy_attach (ide_drive_t *drive)
+static int ide_floppy_probe(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        idefloppy_floppy_t *floppy;
        struct gendisk *g;
 
@@ -2152,10 +2151,7 @@ static int idefloppy_attach (ide_drive_t *drive)
 
        ide_init_disk(g, drive);
 
-       if (ide_register_subdriver(drive, &idefloppy_driver)) {
-               printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name);
-               goto out_put_disk;
-       }
+       ide_register_subdriver(drive, &idefloppy_driver);
 
        memset(floppy, 0, sizeof(*floppy));
 
@@ -2169,9 +2165,8 @@ static int idefloppy_attach (ide_drive_t *drive)
 
        drive->driver_data = floppy;
 
-       DRIVER(drive)->busy++;
        idefloppy_setup (drive, floppy);
-       DRIVER(drive)->busy--;
+
        g->minors = 1 << PARTN_BITS;
        g->driverfs_dev = &drive->gendev;
        strcpy(g->devfs_name, drive->devfs_name);
@@ -2181,19 +2176,17 @@ static int idefloppy_attach (ide_drive_t *drive)
        add_disk(g);
        return 0;
 
-out_put_disk:
-       put_disk(g);
 out_free_floppy:
        kfree(floppy);
 failed:
-       return 1;
+       return -ENODEV;
 }
 
 MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
 
 static void __exit idefloppy_exit (void)
 {
-       ide_unregister_driver(&idefloppy_driver);
+       driver_unregister(&idefloppy_driver.gen_driver);
 }
 
 /*
@@ -2202,8 +2195,7 @@ static void __exit idefloppy_exit (void)
 static int idefloppy_init (void)
 {
        printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
-       ide_register_driver(&idefloppy_driver);
-       return 0;
+       return driver_register(&idefloppy_driver.gen_driver);
 }
 
 module_init(idefloppy_init);
index 554473a95cf7474616263f791cecc427a8bd6ab6..5d876f53c69735d53c6d9b13a42eed559294d5b9 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
+#include <linux/devfs_fs_kernel.h>
 #include <linux/spinlock.h>
 #include <linux/kmod.h>
 #include <linux/pci.h>
@@ -696,13 +697,13 @@ static int wait_hwif_ready(ide_hwif_t *hwif)
        SELECT_DRIVE(&hwif->drives[0]);
        hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
        mdelay(2);
-       rc = ide_wait_not_busy(hwif, 10000);
+       rc = ide_wait_not_busy(hwif, 35000);
        if (rc)
                return rc;
        SELECT_DRIVE(&hwif->drives[1]);
        hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
        mdelay(2);
-       rc = ide_wait_not_busy(hwif, 10000);
+       rc = ide_wait_not_busy(hwif, 35000);
 
        /* Exit function with master reselected (let's be sane) */
        SELECT_DRIVE(&hwif->drives[0]);
@@ -918,7 +919,7 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)
                           want them on default or a new "empty" class
                           for hotplug reprobing ? */
                        if (drive->present) {
-                               ata_attach(drive);
+                               device_register(&drive->gendev);
                        }
                }
        }
@@ -1279,10 +1280,51 @@ void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)
 
 EXPORT_SYMBOL_GPL(ide_init_disk);
 
+static void ide_remove_drive_from_hwgroup(ide_drive_t *drive)
+{
+       ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
+
+       if (drive == drive->next) {
+               /* special case: last drive from hwgroup. */
+               BUG_ON(hwgroup->drive != drive);
+               hwgroup->drive = NULL;
+       } else {
+               ide_drive_t *walk;
+
+               walk = hwgroup->drive;
+               while (walk->next != drive)
+                       walk = walk->next;
+               walk->next = drive->next;
+               if (hwgroup->drive == drive) {
+                       hwgroup->drive = drive->next;
+                       hwgroup->hwif = hwgroup->drive->hwif;
+               }
+       }
+       BUG_ON(hwgroup->drive == drive);
+}
+
 static void drive_release_dev (struct device *dev)
 {
        ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
 
+       spin_lock_irq(&ide_lock);
+       if (drive->devfs_name[0] != '\0') {
+               devfs_remove(drive->devfs_name);
+               drive->devfs_name[0] = '\0';
+       }
+       ide_remove_drive_from_hwgroup(drive);
+       if (drive->id != NULL) {
+               kfree(drive->id);
+               drive->id = NULL;
+       }
+       drive->present = 0;
+       /* Messed up locking ... */
+       spin_unlock_irq(&ide_lock);
+       blk_cleanup_queue(drive->queue);
+       spin_lock_irq(&ide_lock);
+       drive->queue = NULL;
+       spin_unlock_irq(&ide_lock);
+
        up(&drive->gendev_rel_sem);
 }
 
@@ -1306,7 +1348,6 @@ static void init_gendisk (ide_hwif_t *hwif)
                drive->gendev.driver_data = drive;
                drive->gendev.release = drive_release_dev;
                if (drive->present) {
-                       device_register(&drive->gendev);
                        sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d",
                                (hwif->channel && hwif->mate) ?
                                hwif->mate->index : hwif->index,
@@ -1412,7 +1453,7 @@ int ideprobe_init (void)
                                hwif->chipset = ide_generic;
                        for (unit = 0; unit < MAX_DRIVES; ++unit)
                                if (hwif->drives[unit].present)
-                                       ata_attach(&hwif->drives[unit]);
+                                       device_register(&hwif->drives[unit].gendev);
                }
        }
        return 0;
index bdff5ac580531c2bf1cdbc4faf79700552e5c762..4063d2c34e3dae692fd5654245fac53e3c371c2d 100644 (file)
@@ -307,17 +307,41 @@ static int proc_ide_read_driver
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
        ide_drive_t     *drive = (ide_drive_t *) data;
-       ide_driver_t    *driver = drive->driver;
+       struct device   *dev = &drive->gendev;
+       ide_driver_t    *ide_drv;
        int             len;
 
-       if (driver) {
+       down_read(&dev->bus->subsys.rwsem);
+       if (dev->driver) {
+               ide_drv = container_of(dev->driver, ide_driver_t, gen_driver);
                len = sprintf(page, "%s version %s\n",
-                               driver->name, driver->version);
+                               dev->driver->name, ide_drv->version);
        } else
                len = sprintf(page, "ide-default version 0.9.newide\n");
+       up_read(&dev->bus->subsys.rwsem);
        PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
+static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
+{
+       struct device *dev = &drive->gendev;
+       int ret = 1;
+
+       down_write(&dev->bus->subsys.rwsem);
+       device_release_driver(dev);
+       /* FIXME: device can still be in use by previous driver */
+       strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
+       device_attach(dev);
+       drive->driver_req[0] = 0;
+       if (dev->driver == NULL)
+               device_attach(dev);
+       if (dev->driver && !strcmp(dev->driver->name, driver))
+               ret = 0;
+       up_write(&dev->bus->subsys.rwsem);
+
+       return ret;
+}
+
 static int proc_ide_write_driver
        (struct file *file, const char __user *buffer, unsigned long count, void *data)
 {
@@ -488,16 +512,32 @@ void destroy_proc_ide_interface(ide_hwif_t *hwif)
        }
 }
 
-extern struct seq_operations ide_drivers_op;
+static int proc_print_driver(struct device_driver *drv, void *data)
+{
+       ide_driver_t *ide_drv = container_of(drv, ide_driver_t, gen_driver);
+       struct seq_file *s = data;
+
+       seq_printf(s, "%s version %s\n", drv->name, ide_drv->version);
+
+       return 0;
+}
+
+static int ide_drivers_show(struct seq_file *s, void *p)
+{
+       bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
+       return 0;
+}
+
 static int ide_drivers_open(struct inode *inode, struct file *file)
 {
-       return seq_open(file, &ide_drivers_op);
+       return single_open(file, &ide_drivers_show, NULL);
 }
+
 static struct file_operations ide_drivers_operations = {
        .open           = ide_drivers_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = seq_release,
+       .release        = single_release,
 };
 
 void proc_ide_create(void)
@@ -516,6 +556,6 @@ void proc_ide_create(void)
 
 void proc_ide_destroy(void)
 {
-       remove_proc_entry("ide/drivers", proc_ide_root);
+       remove_proc_entry("drivers", proc_ide_root);
        remove_proc_entry("ide", NULL);
 }
index 4825448549850d48cb212d5f4bc006be12904988..5a3dc46008e64895fd5ccbe5e48dd3d32bd7a079 100644 (file)
@@ -4681,21 +4681,12 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
        idetape_add_settings(drive);
 }
 
-static int idetape_cleanup (ide_drive_t *drive)
+static int ide_tape_remove(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        idetape_tape_t *tape = drive->driver_data;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ide_lock, flags);
-       if (test_bit(IDETAPE_BUSY, &tape->flags) || drive->usage ||
-           tape->first_stage != NULL || tape->merge_stage_size) {
-               spin_unlock_irqrestore(&ide_lock, flags);
-               return 1;
-       }
 
-       spin_unlock_irqrestore(&ide_lock, flags);
-       DRIVER(drive)->busy = 0;
-       (void) ide_unregister_subdriver(drive);
+       ide_unregister_subdriver(drive, tape->driver);
 
        ide_unregister_region(tape->disk);
 
@@ -4710,6 +4701,8 @@ static void ide_tape_release(struct kref *kref)
        ide_drive_t *drive = tape->drive;
        struct gendisk *g = tape->disk;
 
+       BUG_ON(tape->first_stage != NULL || tape->merge_stage_size);
+
        drive->dsc_overlap = 0;
        drive->driver_data = NULL;
        devfs_remove("%s/mt", drive->devfs_name);
@@ -4747,26 +4740,24 @@ static ide_proc_entry_t idetape_proc[] = {
 
 #endif
 
-static int idetape_attach(ide_drive_t *drive);
+static int ide_tape_probe(struct device *);
 
-/*
- *     IDE subdriver functions, registered with ide.c
- */
 static ide_driver_t idetape_driver = {
        .owner                  = THIS_MODULE,
-       .name                   = "ide-tape",
+       .gen_driver = {
+               .name           = "ide-tape",
+               .bus            = &ide_bus_type,
+               .probe          = ide_tape_probe,
+               .remove         = ide_tape_remove,
+       },
        .version                = IDETAPE_VERSION,
        .media                  = ide_tape,
-       .busy                   = 1,
        .supports_dsc_overlap   = 1,
-       .cleanup                = idetape_cleanup,
        .do_request             = idetape_do_request,
        .end_request            = idetape_end_request,
        .error                  = __ide_error,
        .abort                  = __ide_abort,
        .proc                   = idetape_proc,
-       .attach                 = idetape_attach,
-       .drives                 = LIST_HEAD_INIT(idetape_driver.drives),
 };
 
 /*
@@ -4829,8 +4820,9 @@ static struct block_device_operations idetape_block_ops = {
        .ioctl          = idetape_ioctl,
 };
 
-static int idetape_attach (ide_drive_t *drive)
+static int ide_tape_probe(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        idetape_tape_t *tape;
        struct gendisk *g;
        int minor;
@@ -4865,10 +4857,7 @@ static int idetape_attach (ide_drive_t *drive)
 
        ide_init_disk(g, drive);
 
-       if (ide_register_subdriver(drive, &idetape_driver)) {
-               printk(KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name);
-               goto out_put_disk;
-       }
+       ide_register_subdriver(drive, &idetape_driver);
 
        memset(tape, 0, sizeof(*tape));
 
@@ -4902,12 +4891,11 @@ static int idetape_attach (ide_drive_t *drive)
        ide_register_region(g);
 
        return 0;
-out_put_disk:
-       put_disk(g);
+
 out_free_tape:
        kfree(tape);
 failed:
-       return 1;
+       return -ENODEV;
 }
 
 MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
@@ -4915,7 +4903,7 @@ MODULE_LICENSE("GPL");
 
 static void __exit idetape_exit (void)
 {
-       ide_unregister_driver(&idetape_driver);
+       driver_unregister(&idetape_driver.gen_driver);
        unregister_chrdev(IDETAPE_MAJOR, "ht");
 }
 
@@ -4928,8 +4916,7 @@ static int idetape_init (void)
                printk(KERN_ERR "ide-tape: Failed to register character device interface\n");
                return -EBUSY;
        }
-       ide_register_driver(&idetape_driver);
-       return 0;
+       return driver_register(&idetape_driver.gen_driver);
 }
 
 module_init(idetape_init);
index 973dec799b5c8b2d6d62f17fd8f639f7072a7be0..dae1bd5b8c3e1e16872af0eb5470ff93b3231230 100644 (file)
@@ -196,8 +196,6 @@ ide_hwif_t ide_hwifs[MAX_HWIFS];    /* master data repository */
 
 EXPORT_SYMBOL(ide_hwifs);
 
-static struct list_head ide_drives = LIST_HEAD_INIT(ide_drives);
-
 /*
  * Do not even *think* about calling this!
  */
@@ -358,54 +356,6 @@ static int ide_system_bus_speed(void)
        return system_bus_speed;
 }
 
-/*
- *     drives_lock protects the list of drives, drivers_lock the
- *     list of drivers.  Currently nobody takes both at once.
- */
-
-static DEFINE_SPINLOCK(drives_lock);
-static DEFINE_SPINLOCK(drivers_lock);
-static LIST_HEAD(drivers);
-
-/* Iterator for the driver list. */
-
-static void *m_start(struct seq_file *m, loff_t *pos)
-{
-       struct list_head *p;
-       loff_t l = *pos;
-       spin_lock(&drivers_lock);
-       list_for_each(p, &drivers)
-               if (!l--)
-                       return list_entry(p, ide_driver_t, drivers);
-       return NULL;
-}
-
-static void *m_next(struct seq_file *m, void *v, loff_t *pos)
-{
-       struct list_head *p = ((ide_driver_t *)v)->drivers.next;
-       (*pos)++;
-       return p==&drivers ? NULL : list_entry(p, ide_driver_t, drivers);
-}
-
-static void m_stop(struct seq_file *m, void *v)
-{
-       spin_unlock(&drivers_lock);
-}
-
-static int show_driver(struct seq_file *m, void *v)
-{
-       ide_driver_t *driver = v;
-       seq_printf(m, "%s version %s\n", driver->name, driver->version);
-       return 0;
-}
-
-struct seq_operations ide_drivers_op = {
-       .start  = m_start,
-       .next   = m_next,
-       .stop   = m_stop,
-       .show   = show_driver
-};
-
 #ifdef CONFIG_PROC_FS
 struct proc_dir_entry *proc_ide_root;
 #endif
@@ -630,7 +580,7 @@ void ide_unregister(unsigned int index)
        ide_hwif_t *hwif, *g;
        static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */
        ide_hwgroup_t *hwgroup;
-       int irq_count = 0, unit, i;
+       int irq_count = 0, unit;
 
        BUG_ON(index >= MAX_HWIFS);
 
@@ -643,23 +593,22 @@ void ide_unregister(unsigned int index)
                goto abort;
        for (unit = 0; unit < MAX_DRIVES; ++unit) {
                drive = &hwif->drives[unit];
-               if (!drive->present)
+               if (!drive->present) {
+                       if (drive->devfs_name[0] != '\0') {
+                               devfs_remove(drive->devfs_name);
+                               drive->devfs_name[0] = '\0';
+                       }
                        continue;
-               if (drive->usage || DRIVER(drive)->busy)
-                       goto abort;
-               drive->dead = 1;
+               }
+               spin_unlock_irq(&ide_lock);
+               device_unregister(&drive->gendev);
+               down(&drive->gendev_rel_sem);
+               spin_lock_irq(&ide_lock);
        }
        hwif->present = 0;
 
        spin_unlock_irq(&ide_lock);
 
-       for (unit = 0; unit < MAX_DRIVES; ++unit) {
-               drive = &hwif->drives[unit];
-               if (!drive->present)
-                       continue;
-               DRIVER(drive)->cleanup(drive);
-       }
-
        destroy_proc_ide_interface(hwif);
 
        hwgroup = hwif->hwgroup;
@@ -687,44 +636,6 @@ void ide_unregister(unsigned int index)
         * Remove us from the hwgroup, and free
         * the hwgroup if we were the only member
         */
-       for (i = 0; i < MAX_DRIVES; ++i) {
-               drive = &hwif->drives[i];
-               if (drive->devfs_name[0] != '\0') {
-                       devfs_remove(drive->devfs_name);
-                       drive->devfs_name[0] = '\0';
-               }
-               if (!drive->present)
-                       continue;
-               if (drive == drive->next) {
-                       /* special case: last drive from hwgroup. */
-                       BUG_ON(hwgroup->drive != drive);
-                       hwgroup->drive = NULL;
-               } else {
-                       ide_drive_t *walk;
-
-                       walk = hwgroup->drive;
-                       while (walk->next != drive)
-                               walk = walk->next;
-                       walk->next = drive->next;
-                       if (hwgroup->drive == drive) {
-                               hwgroup->drive = drive->next;
-                               hwgroup->hwif = HWIF(hwgroup->drive);
-                       }
-               }
-               BUG_ON(hwgroup->drive == drive);
-               if (drive->id != NULL) {
-                       kfree(drive->id);
-                       drive->id = NULL;
-               }
-               drive->present = 0;
-               /* Messed up locking ... */
-               spin_unlock_irq(&ide_lock);
-               blk_cleanup_queue(drive->queue);
-               device_unregister(&drive->gendev);
-               down(&drive->gendev_rel_sem);
-               spin_lock_irq(&ide_lock);
-               drive->queue = NULL;
-       }
        if (hwif->next == hwif) {
                BUG_ON(hwgroup->hwif != hwif);
                kfree(hwgroup);
@@ -1304,73 +1215,6 @@ int system_bus_clock (void)
 
 EXPORT_SYMBOL(system_bus_clock);
 
-/*
- *     Locking is badly broken here - since way back.  That sucker is
- * root-only, but that's not an excuse...  The real question is what
- * exclusion rules do we want here.
- */
-int ide_replace_subdriver (ide_drive_t *drive, const char *driver)
-{
-       if (!drive->present || drive->usage || drive->dead)
-               goto abort;
-       if (DRIVER(drive)->cleanup(drive))
-               goto abort;
-       strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
-       if (ata_attach(drive)) {
-               spin_lock(&drives_lock);
-               list_del_init(&drive->list);
-               spin_unlock(&drives_lock);
-               drive->driver_req[0] = 0;
-               ata_attach(drive);
-       } else {
-               drive->driver_req[0] = 0;
-       }
-       if (drive->driver && !strcmp(drive->driver->name, driver))
-               return 0;
-abort:
-       return 1;
-}
-
-/**
- *     ata_attach              -       attach an ATA/ATAPI device
- *     @drive: drive to attach
- *
- *     Takes a drive that is as yet not assigned to any midlayer IDE
- *     driver (or is assigned to the default driver) and figures out
- *     which driver would like to own it. If nobody claims the drive
- *     then it is automatically attached to the default driver used for
- *     unclaimed objects.
- *
- *     A return of zero indicates attachment to a driver, of one
- *     attachment to the default driver.
- *
- *     Takes drivers_lock.
- */
-
-int ata_attach(ide_drive_t *drive)
-{
-       struct list_head *p;
-       spin_lock(&drivers_lock);
-       list_for_each(p, &drivers) {
-               ide_driver_t *driver = list_entry(p, ide_driver_t, drivers);
-               if (!try_module_get(driver->owner))
-                       continue;
-               spin_unlock(&drivers_lock);
-               if (driver->attach(drive) == 0) {
-                       module_put(driver->owner);
-                       drive->gendev.driver = &driver->gen_driver;
-                       return 0;
-               }
-               spin_lock(&drivers_lock);
-               module_put(driver->owner);
-       }
-       drive->gendev.driver = NULL;
-       spin_unlock(&drivers_lock);
-       if (ide_register_subdriver(drive, NULL))
-               panic("ide: default attach failed");
-       return 1;
-}
-
 static int generic_ide_suspend(struct device *dev, pm_message_t state)
 {
        ide_drive_t *drive = dev->driver_data;
@@ -2013,27 +1857,11 @@ static void __init probe_for_hwifs (void)
 #endif
 }
 
-int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver)
+void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&ide_lock, flags);
-       if (!drive->present || drive->driver != NULL ||
-           drive->usage || drive->dead) {
-               spin_unlock_irqrestore(&ide_lock, flags);
-               return 1;
-       }
-       drive->driver = driver;
-       spin_unlock_irqrestore(&ide_lock, flags);
-       spin_lock(&drives_lock);
-       list_add_tail(&drive->list, driver ? &driver->drives : &ide_drives);
-       spin_unlock(&drives_lock);
-//     printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name);
 #ifdef CONFIG_PROC_FS
-       if (driver)
-               ide_add_proc_entries(drive->proc, driver->proc, drive);
+       ide_add_proc_entries(drive->proc, driver->proc, drive);
 #endif
-       return 0;
 }
 
 EXPORT_SYMBOL(ide_register_subdriver);
@@ -2041,136 +1869,51 @@ EXPORT_SYMBOL(ide_register_subdriver);
 /**
  *     ide_unregister_subdriver        -       disconnect drive from driver
  *     @drive: drive to unplug
+ *     @driver: driver
  *
  *     Disconnect a drive from the driver it was attached to and then
  *     clean up the various proc files and other objects attached to it.
  *
- *     Takes ide_setting_sem, ide_lock and drives_lock.
+ *     Takes ide_setting_sem and ide_lock.
  *     Caller must hold none of the locks.
- *
- *     No locking versus subdriver unload because we are moving to the
- *     default driver anyway. Wants double checking.
  */
 
-int ide_unregister_subdriver (ide_drive_t *drive)
+void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver)
 {
        unsigned long flags;
        
        down(&ide_setting_sem);
        spin_lock_irqsave(&ide_lock, flags);
-       if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) {
-               spin_unlock_irqrestore(&ide_lock, flags);
-               up(&ide_setting_sem);
-               return 1;
-       }
 #ifdef CONFIG_PROC_FS
-       ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc);
+       ide_remove_proc_entries(drive->proc, driver->proc);
 #endif
        auto_remove_settings(drive);
-       drive->driver = NULL;
        spin_unlock_irqrestore(&ide_lock, flags);
        up(&ide_setting_sem);
-       spin_lock(&drives_lock);
-       list_del_init(&drive->list);
-       spin_unlock(&drives_lock);
-       /* drive will be added to &ide_drives in ata_attach() */
-       return 0;
 }
 
 EXPORT_SYMBOL(ide_unregister_subdriver);
 
-static int ide_drive_remove(struct device * dev)
-{
-       ide_drive_t * drive = container_of(dev,ide_drive_t,gendev);
-       DRIVER(drive)->cleanup(drive);
-       return 0;
-}
-
-/**
- *     ide_register_driver     -       register IDE device driver
- *     @driver: the IDE device driver
- *
- *     Register a new device driver and then scan the devices
- *     on the IDE bus in case any should be attached to the
- *     driver we have just registered.  If so attach them.
- *
- *     Takes drivers_lock and drives_lock.
- */
-
-int ide_register_driver(ide_driver_t *driver)
-{
-       struct list_head list;
-       struct list_head *list_loop;
-       struct list_head *tmp_storage;
-
-       spin_lock(&drivers_lock);
-       list_add(&driver->drivers, &drivers);
-       spin_unlock(&drivers_lock);
-
-       INIT_LIST_HEAD(&list);
-       spin_lock(&drives_lock);
-       list_splice_init(&ide_drives, &list);
-       spin_unlock(&drives_lock);
-
-       list_for_each_safe(list_loop, tmp_storage, &list) {
-               ide_drive_t *drive = container_of(list_loop, ide_drive_t, list);
-               list_del_init(&drive->list);
-               if (drive->present)
-                       ata_attach(drive);
-       }
-       driver->gen_driver.name = (char *) driver->name;
-       driver->gen_driver.bus = &ide_bus_type;
-       driver->gen_driver.remove = ide_drive_remove;
-       return driver_register(&driver->gen_driver);
-}
-
-EXPORT_SYMBOL(ide_register_driver);
-
-/**
- *     ide_unregister_driver   -       unregister IDE device driver
- *     @driver: the IDE device driver
- *
- *     Called when a driver module is being unloaded. We reattach any
- *     devices to whatever driver claims them next (typically the default
- *     driver).
- *
- *     Takes drivers_lock and called functions will take ide_setting_sem.
- */
-
-void ide_unregister_driver(ide_driver_t *driver)
-{
-       ide_drive_t *drive;
-
-       spin_lock(&drivers_lock);
-       list_del(&driver->drivers);
-       spin_unlock(&drivers_lock);
-
-       driver_unregister(&driver->gen_driver);
-
-       while(!list_empty(&driver->drives)) {
-               drive = list_entry(driver->drives.next, ide_drive_t, list);
-               if (driver->cleanup(drive)) {
-                       printk(KERN_ERR "%s: cleanup_module() called while still busy\n", drive->name);
-                       BUG();
-               }
-               ata_attach(drive);
-       }
-}
-
-EXPORT_SYMBOL(ide_unregister_driver);
-
 /*
  * Probe module
  */
 
 EXPORT_SYMBOL(ide_lock);
 
+static int ide_bus_match(struct device *dev, struct device_driver *drv)
+{
+       return 1;
+}
+
 struct bus_type ide_bus_type = {
        .name           = "ide",
+       .match          = ide_bus_match,
        .suspend        = generic_ide_suspend,
        .resume         = generic_ide_resume,
 };
 
+EXPORT_SYMBOL_GPL(ide_bus_type);
+
 /*
  * This is gets invoked once during initialization, to set *everything* up
  */
index 47225e324356a3b20c90480cadc1579fd99fb99f..4e0f13d1d06073aef6f593d2141c8cb31dd58114 100644 (file)
@@ -72,6 +72,7 @@ static struct amd_ide_chip {
        { 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 },
        { 0 }
 };
 
@@ -487,6 +488,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
        /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"),
        /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"),
        /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
+       /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
 };
 
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -521,6 +523,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
 #endif
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 },
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
+       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
index 9d70ba5ea59b9d731a6ff10614c38a7e6532f9c6..16b3e2d8bfb107635f5489c8b3b75c807b1a291a 100644 (file)
@@ -726,7 +726,7 @@ static int sis5513_config_xfer_rate (ide_drive_t *drive)
 */
 
 /* Chip detection and general config */
-static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name)
 {
        struct pci_dev *host;
        int i = 0;
@@ -879,7 +879,7 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char
        return 0;
 }
 
-static unsigned int __init ata66_sis5513 (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif)
 {
        u8 ata66 = 0;
 
@@ -897,7 +897,7 @@ static unsigned int __init ata66_sis5513 (ide_hwif_t *hwif)
         return ata66;
 }
 
-static void __init init_hwif_sis5513 (ide_hwif_t *hwif)
+static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
 {
        hwif->autodma = 0;
 
index 78b201fb5e8ab792c622bddcc69e396039a8b772..7d58af1ae306f2574c5217a2b4477f9ef1e378f0 100644 (file)
@@ -84,11 +84,6 @@ config IEEE1394_PCILYNX
          To compile this driver as a module, say M here: the
          module will be called pcilynx.
 
-# Non-maintained pcilynx options
-# if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then
-#     bool '    Use PCILynx local RAM' CONFIG_IEEE1394_PCILYNX_LOCALRAM
-#     bool '    Support for non-IEEE1394 local ports' CONFIG_IEEE1394_PCILYNX_PORTS
-# fi
 config IEEE1394_OHCI1394
        tristate "OHCI-1394 support"
        depends on PCI && IEEE1394
index 1c5845f7e4ab3103675db0a54edb04c4a4adf6cb..a294e45c77cdfb09c7338ca07c2777514427ed7a 100644 (file)
@@ -520,7 +520,7 @@ int hpsb_send_packet(struct hpsb_packet *packet)
 
        if (!packet->no_waiter || packet->expect_response) {
                atomic_inc(&packet->refcnt);
-               packet->sendtime = jiffies;
+               packet->sendtime = jiffies + 10 * HZ;
                skb_queue_tail(&host->pending_packet_queue, packet->skb);
        }
 
@@ -1248,7 +1248,6 @@ EXPORT_SYMBOL(hpsb_make_phypacket);
 EXPORT_SYMBOL(hpsb_make_isopacket);
 EXPORT_SYMBOL(hpsb_read);
 EXPORT_SYMBOL(hpsb_write);
-EXPORT_SYMBOL(hpsb_lock);
 EXPORT_SYMBOL(hpsb_packet_success);
 
 /** highlevel.c **/
index 09908b9564d8b944d5029f83b03f405846890fc4..0aa876360f9be647e307923a325bcda390970979 100644 (file)
@@ -535,6 +535,7 @@ hpsb_write_fail:
         return retval;
 }
 
+#if 0
 
 int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
              u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
@@ -599,3 +600,5 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
 
        return retval;
 }
+
+#endif  /*  0  */
index 526a43ceb49602f6130869826b21ab91d2a1dad8..45ba784fe6da044b4114cfa40f1a26f96bb0fdc2 100644 (file)
@@ -53,12 +53,5 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
              u64 addr, quadlet_t *buffer, size_t length);
 int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
               u64 addr, quadlet_t *buffer, size_t length);
-int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
-             u64 addr, int extcode, quadlet_t *data, quadlet_t arg);
-int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation,
-               u64 addr, int extcode, octlet_t *data, octlet_t arg);
-int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
-                   quadlet_t *buffer, size_t length, u32 specifier_id,
-                   unsigned int version);
 
 #endif /* _IEEE1394_TRANSACTIONS_H */
index a1e30a66297bcbff0de7d95c9257710ecfb6ea0a..83e66ed97ab53640480728c816b810e7c67319a5 100644 (file)
@@ -1005,8 +1005,7 @@ static struct unit_directory *nodemgr_process_unit_directory
        return ud;
 
 unit_directory_error:
-       if (ud != NULL)
-               kfree(ud);
+       kfree(ud);
        return NULL;
 }
 
index 6cb0b586c29761d2e3873219a692f83ace1017d6..36e25ac823dc73c2f69c58e391dd4382af59de55 100644 (file)
@@ -2931,7 +2931,7 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
                kfree(d->prg_cpu);
                kfree(d->prg_bus);
        }
-       if (d->spb) kfree(d->spb);
+       kfree(d->spb);
 
        /* Mark this context as freed. */
        d->ohci = NULL;
index d1758d409610b3906823fb186a8a1325c70fd1dd..cc66c1cae250c1cb105599810637e1ff77ba58bb 100644 (file)
@@ -236,6 +236,9 @@ struct ti_ohci {
 
 static inline int cross_bound(unsigned long addr, unsigned int size)
 {
+       if (size == 0)
+               return 0;
+
        if (size > PAGE_SIZE)
                return 1;
 
index a261d2b0e5ac7b40ed039fd51a4d385c5d0e4aca..bdb3a85cafa68507a82616e88b55952f3ff0a057 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/fs.h>
 #include <linux/poll.h>
 #include <linux/kdev_t.h>
+#include <linux/dma-mapping.h>
 #include <asm/byteorder.h>
 #include <asm/atomic.h>
 #include <asm/io.h>
@@ -834,327 +835,6 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
  * IEEE-1394 functionality section END *
  ***************************************/
 
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-/* VFS functions for local bus / aux device access.  Access to those
- * is implemented as a character device instead of block devices
- * because buffers are not wanted for this.  Therefore llseek (from
- * VFS) can be used for these char devices with obvious effects.
- */
-static int mem_open(struct inode*, struct file*);
-static int mem_release(struct inode*, struct file*);
-static unsigned int aux_poll(struct file*, struct poll_table_struct*);
-static loff_t mem_llseek(struct file*, loff_t, int);
-static ssize_t mem_read (struct file*, char*, size_t, loff_t*);
-static ssize_t mem_write(struct file*, const char*, size_t, loff_t*);
-
-
-static struct file_operations aux_ops = {
-       .owner =        THIS_MODULE,
-        .read =         mem_read,
-        .write =        mem_write,
-        .poll =         aux_poll,
-        .llseek =       mem_llseek,
-        .open =         mem_open,
-        .release =      mem_release,
-};
-
-
-static void aux_setup_pcls(struct ti_lynx *lynx)
-{
-        struct ti_pcl pcl;
-
-        pcl.next = PCL_NEXT_INVALID;
-        pcl.user_data = pcl_bus(lynx, lynx->dmem_pcl);
-        put_pcl(lynx, lynx->dmem_pcl, &pcl);
-}
-
-static int mem_open(struct inode *inode, struct file *file)
-{
-        int cid = iminor(inode);
-        enum { t_rom, t_aux, t_ram } type;
-        struct memdata *md;
-
-        if (cid < PCILYNX_MINOR_AUX_START) {
-                /* just for completeness */
-                return -ENXIO;
-        } else if (cid < PCILYNX_MINOR_ROM_START) {
-                cid -= PCILYNX_MINOR_AUX_START;
-                if (cid >= num_of_cards || !cards[cid].aux_port)
-                        return -ENXIO;
-                type = t_aux;
-        } else if (cid < PCILYNX_MINOR_RAM_START) {
-                cid -= PCILYNX_MINOR_ROM_START;
-                if (cid >= num_of_cards || !cards[cid].local_rom)
-                        return -ENXIO;
-                type = t_rom;
-        } else {
-                /* WARNING: Know what you are doing when opening RAM.
-                 * It is currently used inside the driver! */
-                cid -= PCILYNX_MINOR_RAM_START;
-                if (cid >= num_of_cards || !cards[cid].local_ram)
-                        return -ENXIO;
-                type = t_ram;
-        }
-
-        md = (struct memdata *)kmalloc(sizeof(struct memdata), SLAB_KERNEL);
-        if (md == NULL)
-                return -ENOMEM;
-
-        md->lynx = &cards[cid];
-        md->cid = cid;
-
-        switch (type) {
-        case t_rom:
-                md->type = rom;
-                break;
-        case t_ram:
-                md->type = ram;
-                break;
-        case t_aux:
-                atomic_set(&md->aux_intr_last_seen,
-                           atomic_read(&cards[cid].aux_intr_seen));
-                md->type = aux;
-                break;
-        }
-
-        file->private_data = md;
-
-        return 0;
-}
-
-static int mem_release(struct inode *inode, struct file *file)
-{
-        kfree(file->private_data);
-        return 0;
-}
-
-static unsigned int aux_poll(struct file *file, poll_table *pt)
-{
-        struct memdata *md = (struct memdata *)file->private_data;
-        int cid = md->cid;
-        unsigned int mask;
-
-        /* reading and writing is always allowed */
-        mask = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;
-
-        if (md->type == aux) {
-                poll_wait(file, &cards[cid].aux_intr_wait, pt);
-
-                if (atomic_read(&md->aux_intr_last_seen)
-                    != atomic_read(&cards[cid].aux_intr_seen)) {
-                        mask |= POLLPRI;
-                        atomic_inc(&md->aux_intr_last_seen);
-                }
-        }
-
-        return mask;
-}
-
-loff_t mem_llseek(struct file *file, loff_t offs, int orig)
-{
-        loff_t newoffs;
-
-        switch (orig) {
-        case 0:
-                newoffs = offs;
-                break;
-        case 1:
-                newoffs = offs + file->f_pos;
-                break;
-        case 2:
-                newoffs = PCILYNX_MAX_MEMORY + 1 + offs;
-                break;
-        default:
-                return -EINVAL;
-        }
-
-        if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) return -EINVAL;
-
-        file->f_pos = newoffs;
-        return newoffs;
-}
-
-/*
- * do not DMA if count is too small because this will have a serious impact
- * on performance - the value 2400 was found by experiment and may not work
- * everywhere as good as here - use mem_mindma option for modules to change
- */
-static short mem_mindma = 2400;
-module_param(mem_mindma, short, 0444);
-MODULE_PARM_DESC(mem_mindma, "Minimum amount of data required to use DMA");
-
-static ssize_t mem_dmaread(struct memdata *md, u32 physbuf, ssize_t count,
-                           int offset)
-{
-        pcltmp_t pcltmp;
-        struct ti_pcl *pcl;
-        size_t retval;
-        int i;
-        DECLARE_WAITQUEUE(wait, current);
-
-        count &= ~3;
-        count = min(count, 53196);
-        retval = count;
-
-        if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS))
-            & DMA_CHAN_CTRL_BUSY) {
-                PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!");
-        }
-
-        reg_write(md->lynx, LBUS_ADDR, md->type | offset);
-
-        pcl = edit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp);
-        pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | min(count, 4092);
-        pcl->buffer[0].pointer = physbuf;
-        count -= 4092;
-
-        i = 0;
-        while (count > 0) {
-                i++;
-                pcl->buffer[i].control = min(count, 4092);
-                pcl->buffer[i].pointer = physbuf + i * 4092;
-                count -= 4092;
-        }
-        pcl->buffer[i].control |= PCL_LAST_BUFF;
-        commit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp);
-
-        set_current_state(TASK_INTERRUPTIBLE);
-        add_wait_queue(&md->lynx->mem_dma_intr_wait, &wait);
-        run_sub_pcl(md->lynx, md->lynx->dmem_pcl, 2, CHANNEL_LOCALBUS);
-
-        schedule();
-        while (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS))
-               & DMA_CHAN_CTRL_BUSY) {
-                if (signal_pending(current)) {
-                        retval = -EINTR;
-                        break;
-                }
-                schedule();
-        }
-
-        reg_write(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS), 0);
-        remove_wait_queue(&md->lynx->mem_dma_intr_wait, &wait);
-
-        if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS))
-            & DMA_CHAN_CTRL_BUSY) {
-                PRINT(KERN_ERR, md->lynx->id, "DMA STILL ACTIVE!");
-        }
-
-        return retval;
-}
-
-static ssize_t mem_read(struct file *file, char *buffer, size_t count,
-                        loff_t *offset)
-{
-        struct memdata *md = (struct memdata *)file->private_data;
-        ssize_t bcount;
-        size_t alignfix;
-       loff_t off = *offset; /* avoid useless 64bit-arithmetic */
-        ssize_t retval;
-        void *membase;
-
-        if ((off + count) > PCILYNX_MAX_MEMORY+1) {
-                count = PCILYNX_MAX_MEMORY+1 - off;
-        }
-        if (count == 0 || off > PCILYNX_MAX_MEMORY) {
-                return -ENOSPC;
-        }
-
-        switch (md->type) {
-        case rom:
-                membase = md->lynx->local_rom;
-                break;
-        case ram:
-                membase = md->lynx->local_ram;
-                break;
-        case aux:
-                membase = md->lynx->aux_port;
-                break;
-        default:
-                panic("pcilynx%d: unsupported md->type %d in %s",
-                      md->lynx->id, md->type, __FUNCTION__);
-        }
-
-        down(&md->lynx->mem_dma_mutex);
-
-        if (count < mem_mindma) {
-                memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, count);
-                goto out;
-        }
-
-        bcount = count;
-        alignfix = 4 - (off % 4);
-        if (alignfix != 4) {
-                if (bcount < alignfix) {
-                        alignfix = bcount;
-                }
-                memcpy_fromio(md->lynx->mem_dma_buffer, membase+off,
-                              alignfix);
-                if (bcount == alignfix) {
-                        goto out;
-                }
-                bcount -= alignfix;
-                off += alignfix;
-        }
-
-        while (bcount >= 4) {
-                retval = mem_dmaread(md, md->lynx->mem_dma_buffer_dma
-                                     + count - bcount, bcount, off);
-                if (retval < 0) return retval;
-
-                bcount -= retval;
-                off += retval;
-        }
-
-        if (bcount) {
-                memcpy_fromio(md->lynx->mem_dma_buffer + count - bcount,
-                              membase+off, bcount);
-        }
-
- out:
-        retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count);
-        up(&md->lynx->mem_dma_mutex);
-
-       if (retval) return -EFAULT;
-        *offset += count;
-        return count;
-}
-
-
-static ssize_t mem_write(struct file *file, const char *buffer, size_t count,
-                         loff_t *offset)
-{
-        struct memdata *md = (struct memdata *)file->private_data;
-
-        if (((*offset) + count) > PCILYNX_MAX_MEMORY+1) {
-                count = PCILYNX_MAX_MEMORY+1 - *offset;
-        }
-        if (count == 0 || *offset > PCILYNX_MAX_MEMORY) {
-                return -ENOSPC;
-        }
-
-        /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */
-        switch (md->type) {
-        case aux:
-               if (copy_from_user(md->lynx->aux_port+(*offset), buffer, count))
-                       return -EFAULT;
-                break;
-        case ram:
-               if (copy_from_user(md->lynx->local_ram+(*offset), buffer, count))
-                       return -EFAULT;
-                break;
-        case rom:
-                /* the ROM may be writeable */
-               if (copy_from_user(md->lynx->local_rom+(*offset), buffer, count))
-                       return -EFAULT;
-                break;
-        }
-
-        file->f_pos += count;
-        return count;
-}
-#endif /* CONFIG_IEEE1394_PCILYNX_PORTS */
-
 
 /********************************************************
  * Global stuff (interrupt handler, init/shutdown code) *
@@ -1181,18 +861,6 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id,
         reg_write(lynx, LINK_INT_STATUS, linkint);
         reg_write(lynx, PCI_INT_STATUS, intmask);
 
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-        if (intmask & PCI_INT_AUX_INT) {
-                atomic_inc(&lynx->aux_intr_seen);
-                wake_up_interruptible(&lynx->aux_intr_wait);
-        }
-
-        if (intmask & PCI_INT_DMA_HLT(CHANNEL_LOCALBUS)) {
-                wake_up_interruptible(&lynx->mem_dma_intr_wait);
-        }
-#endif
-
-
         if (intmask & PCI_INT_1394) {
                 if (linkint & LINK_INT_PHY_TIMEOUT) {
                         PRINT(KERN_INFO, lynx->id, "PHY timeout occurred");
@@ -1484,15 +1152,9 @@ static void remove_card(struct pci_dev *dev)
                 pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page,
                                     lynx->rcv_page_dma);
         case have_aux_buf:
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-                pci_free_consistent(lynx->dev, 65536, lynx->mem_dma_buffer,
-                                    lynx->mem_dma_buffer_dma);
-#endif
         case have_pcl_mem:
-#ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM
                 pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem,
                                     lynx->pcl_mem_dma);
-#endif
         case clear:
                 /* do nothing - already freed */
                 ;
@@ -1524,7 +1186,7 @@ static int __devinit add_card(struct pci_dev *dev,
 
         error = -ENXIO;
 
-        if (pci_set_dma_mask(dev, 0xffffffff))
+        if (pci_set_dma_mask(dev, DMA_32BIT_MASK))
                 FAIL("DMA address limits not supported for PCILynx hardware");
         if (pci_enable_device(dev))
                 FAIL("failed to enable PCILynx hardware");
@@ -1546,7 +1208,6 @@ static int __devinit add_card(struct pci_dev *dev,
         spin_lock_init(&lynx->lock);
         spin_lock_init(&lynx->phy_reg_lock);
 
-#ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM
         lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE,
                                              &lynx->pcl_mem_dma);
 
@@ -1558,16 +1219,6 @@ static int __devinit add_card(struct pci_dev *dev,
         } else {
                 FAIL("failed to allocate PCL memory area");
         }
-#endif
-
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-        lynx->mem_dma_buffer = pci_alloc_consistent(dev, 65536,
-                                                    &lynx->mem_dma_buffer_dma);
-        if (lynx->mem_dma_buffer == NULL) {
-                FAIL("failed to allocate DMA buffer for aux");
-        }
-        lynx->state = have_aux_buf;
-#endif
 
         lynx->rcv_page = pci_alloc_consistent(dev, PAGE_SIZE,
                                               &lynx->rcv_page_dma);
@@ -1597,13 +1248,6 @@ static int __devinit add_card(struct pci_dev *dev,
                 FAIL("failed to remap registers - card not accessible");
         }
 
-#ifdef CONFIG_IEEE1394_PCILYNX_LOCALRAM
-        if (lynx->local_ram == NULL) {
-                FAIL("failed to remap local RAM which is required for "
-                     "operation");
-        }
-#endif
-
         reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET);
         /* Fix buggy cards with autoboot pin not tied low: */
         reg_write(lynx, DMA0_CHAN_CTRL, 0);
@@ -1624,13 +1268,6 @@ static int __devinit add_card(struct pci_dev *dev,
 
         /* alloc_pcl return values are not checked, it is expected that the
          * provided PCL space is sufficient for the initial allocations */
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-        if (lynx->aux_port != NULL) {
-                lynx->dmem_pcl = alloc_pcl(lynx);
-                aux_setup_pcls(lynx);
-                sema_init(&lynx->mem_dma_mutex, 1);
-        }
-#endif
         lynx->rcv_pcl = alloc_pcl(lynx);
         lynx->rcv_pcl_start = alloc_pcl(lynx);
         lynx->async.pcl = alloc_pcl(lynx);
@@ -1647,12 +1284,6 @@ static int __devinit add_card(struct pci_dev *dev,
 
         reg_write(lynx, PCI_INT_ENABLE, PCI_INT_DMA_ALL);
 
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-        reg_set_bits(lynx, PCI_INT_ENABLE, PCI_INT_AUX_INT);
-        init_waitqueue_head(&lynx->mem_dma_intr_wait);
-        init_waitqueue_head(&lynx->aux_intr_wait);
-#endif
-
        tasklet_init(&lynx->iso_rcv.tq, (void (*)(unsigned long))iso_rcv_bh,
                     (unsigned long)lynx);
 
@@ -1944,37 +1575,18 @@ static int __init pcilynx_init(void)
 {
         int ret;
 
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-        if (register_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME, &aux_ops)) {
-                PRINT_G(KERN_ERR, "allocation of char major number %d failed",
-                        PCILYNX_MAJOR);
-                return -EBUSY;
-        }
-#endif
-
         ret = pci_register_driver(&lynx_pci_driver);
         if (ret < 0) {
                 PRINT_G(KERN_ERR, "PCI module init failed");
-                goto free_char_dev;
+                return ret;
         }
 
         return 0;
-
- free_char_dev:
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-        unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME);
-#endif
-
-        return ret;
 }
 
 static void __exit pcilynx_cleanup(void)
 {
         pci_unregister_driver(&lynx_pci_driver);
-
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-        unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME);
-#endif
 }
 
 
index 644ec55d3d469b945b68f3cd51fae5651509b875..d631aa8383ada2311102469f6fb545fce1e88b70 100644 (file)
@@ -55,16 +55,6 @@ struct ti_lynx {
         void __iomem *aux_port;
        quadlet_t bus_info_block[5];
 
-#ifdef CONFIG_IEEE1394_PCILYNX_PORTS
-        atomic_t aux_intr_seen;
-        wait_queue_head_t aux_intr_wait;
-
-        void *mem_dma_buffer;
-        dma_addr_t mem_dma_buffer_dma;
-        struct semaphore mem_dma_mutex;
-        wait_queue_head_t mem_dma_intr_wait;
-#endif
-
         /*
          * use local RAM of LOCALRAM_SIZE bytes for PCLs, which allows for
          * LOCALRAM_SIZE * 8 PCLs (each sized 128 bytes);
@@ -72,11 +62,9 @@ struct ti_lynx {
          */
         u8 pcl_bmap[LOCALRAM_SIZE / 1024];
 
-#ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM
        /* point to PCLs memory area if needed */
        void *pcl_mem;
         dma_addr_t pcl_mem_dma;
-#endif
 
         /* PCLs for local mem / aux transfers */
         pcl_t dmem_pcl;
@@ -378,39 +366,6 @@ struct ti_pcl {
 #define pcloffs(MEMBER) (offsetof(struct ti_pcl, MEMBER))
 
 
-#ifdef CONFIG_IEEE1394_PCILYNX_LOCALRAM
-
-static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid,
-                           const struct ti_pcl *pcl)
-{
-        int i;
-        u32 *in = (u32 *)pcl;
-        u32 *out = (u32 *)(lynx->local_ram + pclid * sizeof(struct ti_pcl));
-
-        for (i = 0; i < 32; i++, out++, in++) {
-                writel(*in, out);
-        }
-}
-
-static inline void get_pcl(const struct ti_lynx *lynx, pcl_t pclid,
-                           struct ti_pcl *pcl)
-{
-        int i;
-        u32 *out = (u32 *)pcl;
-        u32 *in = (u32 *)(lynx->local_ram + pclid * sizeof(struct ti_pcl));
-
-        for (i = 0; i < 32; i++, out++, in++) {
-                *out = readl(in);
-        }
-}
-
-static inline u32 pcl_bus(const struct ti_lynx *lynx, pcl_t pclid)
-{
-        return pci_resource_start(lynx->dev, 1) + pclid * sizeof(struct ti_pcl);
-}
-
-#else /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */
-
 static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid,
                            const struct ti_pcl *pcl)
 {
@@ -431,10 +386,8 @@ static inline u32 pcl_bus(const struct ti_lynx *lynx, pcl_t pclid)
         return lynx->pcl_mem_dma + pclid * sizeof(struct ti_pcl);
 }
 
-#endif /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */
-
 
-#if defined (CONFIG_IEEE1394_PCILYNX_LOCALRAM) || defined (__BIG_ENDIAN)
+#if defined (__BIG_ENDIAN)
 typedef struct ti_pcl pcltmp_t;
 
 static inline struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid,
index 4bedf7113f407e56bc1e509e255eab669cc2fe27..d68c4658f2fc1d11b10efed4f0269e56514bbf95 100644 (file)
  *
  */
 
+/* Markus Tavenrath <speedygoo@speedygoo.de> :
+   - fixed checks for valid buffer-numbers in video1394_icotl
+   - changed the ways the dma prg's are used, now it's possible to use
+     even a single dma buffer
+*/
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -112,6 +117,7 @@ struct dma_iso_ctx {
        struct it_dma_prg **it_prg;
 
        unsigned int *buffer_status;
+       unsigned int *buffer_prg_assignment;
         struct timeval *buffer_time; /* time when the buffer was received */
        unsigned int *last_used_cmd; /* For ISO Transmit with
                                        variable sized packets only ! */
@@ -180,23 +186,14 @@ static int free_dma_iso_ctx(struct dma_iso_ctx *d)
                kfree(d->prg_reg);
        }
 
-       if (d->ir_prg)
-               kfree(d->ir_prg);
-
-       if (d->it_prg)
-               kfree(d->it_prg);
-
-       if (d->buffer_status)
-               kfree(d->buffer_status);
-       if (d->buffer_time)
-               kfree(d->buffer_time);
-       if (d->last_used_cmd)
-               kfree(d->last_used_cmd);
-       if (d->next_buffer)
-               kfree(d->next_buffer);
-
+       kfree(d->ir_prg);
+       kfree(d->it_prg);
+       kfree(d->buffer_status);
+       kfree(d->buffer_prg_assignment);
+       kfree(d->buffer_time);
+       kfree(d->last_used_cmd);
+       kfree(d->next_buffer);
        list_del(&d->link);
-
        kfree(d);
 
        return 0;
@@ -230,7 +227,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
        /* Init the regions for easy cleanup */
        dma_region_init(&d->dma);
 
-       if (dma_region_alloc(&d->dma, d->num_desc * d->buf_size, ohci->dev,
+       if (dma_region_alloc(&d->dma, (d->num_desc - 1) * d->buf_size, ohci->dev,
                             PCI_DMA_BIDIRECTIONAL)) {
                PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma buffer");
                free_dma_iso_ctx(d);
@@ -342,6 +339,8 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
 
        d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int),
                                   GFP_KERNEL);
+       d->buffer_prg_assignment = kmalloc(d->num_desc * sizeof(unsigned int),
+                                  GFP_KERNEL);
        d->buffer_time = kmalloc(d->num_desc * sizeof(struct timeval),
                                   GFP_KERNEL);
        d->last_used_cmd = kmalloc(d->num_desc * sizeof(unsigned int),
@@ -354,6 +353,11 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
                free_dma_iso_ctx(d);
                return NULL;
        }
+       if (d->buffer_prg_assignment == NULL) {
+               PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_prg_assignment");
+               free_dma_iso_ctx(d);
+               return NULL;
+       }
        if (d->buffer_time == NULL) {
                PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_time");
                free_dma_iso_ctx(d);
@@ -370,6 +374,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
                return NULL;
        }
        memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int));
+       memset(d->buffer_prg_assignment, 0, d->num_desc * sizeof(unsigned int));
        memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval));
        memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int));
        memset(d->next_buffer, -1, d->num_desc * sizeof(int));
@@ -379,7 +384,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
        PRINT(KERN_INFO, ohci->host->id, "Iso %s DMA: %d buffers "
              "of size %d allocated for a frame size %d, each with %d prgs",
              (type == OHCI_ISO_RECEIVE) ? "receive" : "transmit",
-             d->num_desc, d->buf_size, d->frame_size, d->nb_cmd);
+             d->num_desc - 1, d->buf_size, d->frame_size, d->nb_cmd);
 
        return d;
 }
@@ -394,11 +399,36 @@ static void reset_ir_status(struct dma_iso_ctx *d, int n)
        d->ir_prg[n][i].status = cpu_to_le32(d->left_size);
 }
 
+static void reprogram_dma_ir_prg(struct dma_iso_ctx *d, int n, int buffer, int flags)
+{
+       struct dma_cmd *ir_prg = d->ir_prg[n];
+       unsigned long buf = (unsigned long)d->dma.kvirt + buffer * d->buf_size;
+       int i;
+
+       d->buffer_prg_assignment[n] = buffer;
+
+       ir_prg[0].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, buf -
+                               (unsigned long)d->dma.kvirt));
+       ir_prg[1].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma,
+                               (buf + 4) - (unsigned long)d->dma.kvirt));
+
+       for (i=2;i<d->nb_cmd-1;i++) {
+               ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma,
+                                               (buf+(i-1)*PAGE_SIZE) -
+                                               (unsigned long)d->dma.kvirt));
+       }
+
+       ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
+                                 DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size);
+       ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma,
+                                 (buf+(i-1)*PAGE_SIZE) - (unsigned long)d->dma.kvirt));
+}
+
 static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags)
 {
        struct dma_cmd *ir_prg = d->ir_prg[n];
        struct dma_prog_region *ir_reg = &d->prg_reg[n];
-       unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size;
+       unsigned long buf = (unsigned long)d->dma.kvirt;
        int i;
 
        /* the first descriptor will read only 4 bytes */
@@ -508,7 +538,7 @@ static void wakeup_dma_ir_ctx(unsigned long l)
        for (i = 0; i < d->num_desc; i++) {
                if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) {
                        reset_ir_status(d, i);
-                       d->buffer_status[i] = VIDEO1394_BUFFER_READY;
+                       d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY;
                        do_gettimeofday(&d->buffer_time[i]);
                }
        }
@@ -585,7 +615,7 @@ static void wakeup_dma_it_ctx(unsigned long l)
                        int next = d->next_buffer[i];
                        put_timestamp(ohci, d, next);
                        d->it_prg[i][d->last_used_cmd[i]].end.status = 0;
-                       d->buffer_status[i] = VIDEO1394_BUFFER_READY;
+                       d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY;
                }
        }
 
@@ -595,11 +625,25 @@ static void wakeup_dma_it_ctx(unsigned long l)
                wake_up_interruptible(&d->waitq);
 }
 
+static void reprogram_dma_it_prg(struct dma_iso_ctx  *d, int n, int buffer)
+{
+       struct it_dma_prg *it_prg = d->it_prg[n];
+       unsigned long buf = (unsigned long)d->dma.kvirt + buffer * d->buf_size;
+       int i;
+
+       d->buffer_prg_assignment[n] = buffer;
+       for (i=0;i<d->nb_cmd;i++) {
+         it_prg[i].end.address =
+               cpu_to_le32(dma_region_offset_to_bus(&d->dma,
+                       (buf+i*d->packet_size) - (unsigned long)d->dma.kvirt));
+       }
+}
+
 static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag)
 {
        struct it_dma_prg *it_prg = d->it_prg[n];
        struct dma_prog_region *it_reg = &d->prg_reg[n];
-       unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size;
+       unsigned long buf = (unsigned long)d->dma.kvirt;
        int i;
        d->last_used_cmd[n] = d->nb_cmd - 1;
        for (i=0;i<d->nb_cmd;i++) {
@@ -796,7 +840,7 @@ static int __video1394_ioctl(struct file *file,
 
                if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL) {
                        d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE,
-                                             v.nb_buffers, v.buf_size,
+                                             v.nb_buffers + 1, v.buf_size,
                                              v.channel, 0);
 
                        if (d == NULL) {
@@ -817,7 +861,7 @@ static int __video1394_ioctl(struct file *file,
                }
                else {
                        d = alloc_dma_iso_ctx(ohci, OHCI_ISO_TRANSMIT,
-                                             v.nb_buffers, v.buf_size,
+                                             v.nb_buffers + 1, v.buf_size,
                                              v.channel, v.packet_size);
 
                        if (d == NULL) {
@@ -889,6 +933,7 @@ static int __video1394_ioctl(struct file *file,
        {
                struct video1394_wait v;
                struct dma_iso_ctx *d;
+               int next_prg;
 
                if (copy_from_user(&v, argp, sizeof(v)))
                        return -EFAULT;
@@ -896,7 +941,7 @@ static int __video1394_ioctl(struct file *file,
                d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
                if (d == NULL) return -EFAULT;
 
-               if ((v.buffer<0) || (v.buffer>d->num_desc)) {
+               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
                        PRINT(KERN_ERR, ohci->host->id,
                              "Buffer %d out of range",v.buffer);
                        return -EINVAL;
@@ -913,12 +958,14 @@ static int __video1394_ioctl(struct file *file,
 
                d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED;
 
+               next_prg = (d->last_buffer + 1) % d->num_desc;
                if (d->last_buffer>=0)
                        d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress =
-                               cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0)
+                               cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0)
                                        & 0xfffffff0) | 0x1);
 
-               d->last_buffer = v.buffer;
+               d->last_buffer = next_prg;
+               reprogram_dma_ir_prg(d, d->last_buffer, v.buffer, d->flags);
 
                d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = 0;
 
@@ -930,7 +977,7 @@ static int __video1394_ioctl(struct file *file,
 
                        /* Tell the controller where the first program is */
                        reg_write(ohci, d->cmdPtr,
-                               dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x1);
+                                 dma_prog_region_offset_to_bus(&d->prg_reg[d->last_buffer], 0) | 0x1);
 
                        /* Run IR context */
                        reg_write(ohci, d->ctrlSet, 0x8000);
@@ -951,7 +998,7 @@ static int __video1394_ioctl(struct file *file,
        {
                struct video1394_wait v;
                struct dma_iso_ctx *d;
-               int i;
+               int i = 0;
 
                if (copy_from_user(&v, argp, sizeof(v)))
                        return -EFAULT;
@@ -959,7 +1006,7 @@ static int __video1394_ioctl(struct file *file,
                d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
                if (d == NULL) return -EFAULT;
 
-               if ((v.buffer<0) || (v.buffer>d->num_desc)) {
+               if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) {
                        PRINT(KERN_ERR, ohci->host->id,
                              "Buffer %d out of range",v.buffer);
                        return -EINVAL;
@@ -1005,9 +1052,9 @@ static int __video1394_ioctl(struct file *file,
                 * Look ahead to see how many more buffers have been received
                 */
                i=0;
-               while (d->buffer_status[(v.buffer+1)%d->num_desc]==
+               while (d->buffer_status[(v.buffer+1)%(d->num_desc - 1)]==
                       VIDEO1394_BUFFER_READY) {
-                       v.buffer=(v.buffer+1)%d->num_desc;
+                       v.buffer=(v.buffer+1)%(d->num_desc - 1);
                        i++;
                }
                spin_unlock_irqrestore(&d->lock, flags);
@@ -1023,6 +1070,7 @@ static int __video1394_ioctl(struct file *file,
                struct video1394_wait v;
                unsigned int *psizes = NULL;
                struct dma_iso_ctx *d;
+               int next_prg;
 
                if (copy_from_user(&v, argp, sizeof(v)))
                        return -EFAULT;
@@ -1030,7 +1078,7 @@ static int __video1394_ioctl(struct file *file,
                d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
                if (d == NULL) return -EFAULT;
 
-               if ((v.buffer<0) || (v.buffer>d->num_desc)) {
+               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
                        PRINT(KERN_ERR, ohci->host->id,
                              "Buffer %d out of range",v.buffer);
                        return -EINVAL;
@@ -1056,19 +1104,19 @@ static int __video1394_ioctl(struct file *file,
 
                spin_lock_irqsave(&d->lock,flags);
 
+               // last_buffer is last_prg
+               next_prg = (d->last_buffer + 1) % d->num_desc;
                if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) {
                        PRINT(KERN_ERR, ohci->host->id,
                              "Buffer %d is already used",v.buffer);
                        spin_unlock_irqrestore(&d->lock,flags);
-                       if (psizes)
-                               kfree(psizes);
+                       kfree(psizes);
                        return -EBUSY;
                }
 
                if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) {
                        initialize_dma_it_prg_var_packet_queue(
-                               d, v.buffer, psizes,
-                               ohci);
+                               d, next_prg, psizes, ohci);
                }
 
                d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED;
@@ -1076,16 +1124,17 @@ static int __video1394_ioctl(struct file *file,
                if (d->last_buffer >= 0) {
                        d->it_prg[d->last_buffer]
                                [ d->last_used_cmd[d->last_buffer] ].end.branchAddress =
-                                       cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer],
+                                       cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg],
                                                0) & 0xfffffff0) | 0x3);
 
                        d->it_prg[d->last_buffer]
                                [ d->last_used_cmd[d->last_buffer] ].begin.branchAddress =
-                                       cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer],
+                                       cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg],
                                                0) & 0xfffffff0) | 0x3);
-                       d->next_buffer[d->last_buffer] = v.buffer;
+                       d->next_buffer[d->last_buffer] = (v.buffer + 1) % (d->num_desc - 1);
                }
-               d->last_buffer = v.buffer;
+               d->last_buffer = next_prg;
+               reprogram_dma_it_prg(d, d->last_buffer, v.buffer);
                d->next_buffer[d->last_buffer] = -1;
 
                d->it_prg[d->last_buffer][d->last_used_cmd[d->last_buffer]].end.branchAddress = 0;
@@ -1100,7 +1149,7 @@ static int __video1394_ioctl(struct file *file,
 
                        /* Tell the controller where the first program is */
                        reg_write(ohci, d->cmdPtr,
-                               dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x3);
+                               dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0) | 0x3);
 
                        /* Run IT context */
                        reg_write(ohci, d->ctrlSet, 0x8000);
@@ -1116,9 +1165,7 @@ static int __video1394_ioctl(struct file *file,
                        }
                }
 
-               if (psizes)
-                       kfree(psizes);
-
+               kfree(psizes);
                return 0;
 
        }
@@ -1133,7 +1180,7 @@ static int __video1394_ioctl(struct file *file,
                d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
                if (d == NULL) return -EFAULT;
 
-               if ((v.buffer<0) || (v.buffer>d->num_desc)) {
+               if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
                        PRINT(KERN_ERR, ohci->host->id,
                              "Buffer %d out of range",v.buffer);
                        return -EINVAL;
index d4233ee61c35cbff8cd40a6aa8e24e22bd7ab29e..276e1a53010ddc19a312b067caccf89c3c6b6c00 100644 (file)
@@ -587,7 +587,7 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
 
        init_mad(query->sa_query.mad, agent);
 
-       query->sa_query.callback              = ib_sa_path_rec_callback;
+       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;
        query->sa_query.mad->mad_hdr.method   = IB_MGMT_METHOD_GET;
@@ -663,7 +663,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
 
        init_mad(query->sa_query.mad, agent);
 
-       query->sa_query.callback              = ib_sa_mcmember_rec_callback;
+       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;
        query->sa_query.mad->mad_hdr.method   = method;
@@ -698,20 +698,21 @@ static void send_handler(struct ib_mad_agent *agent,
        if (!query)
                return;
 
-       switch (mad_send_wc->status) {
-       case IB_WC_SUCCESS:
-               /* No callback -- already got recv */
-               break;
-       case IB_WC_RESP_TIMEOUT_ERR:
-               query->callback(query, -ETIMEDOUT, NULL);
-               break;
-       case IB_WC_WR_FLUSH_ERR:
-               query->callback(query, -EINTR, NULL);
-               break;
-       default:
-               query->callback(query, -EIO, NULL);
-               break;
-       }
+       if (query->callback)
+               switch (mad_send_wc->status) {
+               case IB_WC_SUCCESS:
+                       /* No callback -- already got recv */
+                       break;
+               case IB_WC_RESP_TIMEOUT_ERR:
+                       query->callback(query, -ETIMEDOUT, NULL);
+                       break;
+               case IB_WC_WR_FLUSH_ERR:
+                       query->callback(query, -EINTR, NULL);
+                       break;
+               default:
+                       query->callback(query, -EIO, NULL);
+                       break;
+               }
 
        dma_unmap_single(agent->device->dma_device,
                         pci_unmap_addr(query, mapping),
@@ -736,7 +737,7 @@ static void recv_handler(struct ib_mad_agent *mad_agent,
        query = idr_find(&query_idr, mad_recv_wc->wc->wr_id);
        spin_unlock_irqrestore(&idr_lock, flags);
 
-       if (query) {
+       if (query && query->callback) {
                if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
                        query->callback(query,
                                        mad_recv_wc->recv_buf.mad->mad_hdr.status ?
index 56b9c2fa2ecccbf99399a6015a1e6f1ee3f7e650..9d912d6877ffc01ed55943b15a55ae7230f23a6a 100644 (file)
@@ -499,6 +499,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp)
 static int ib_umad_close(struct inode *inode, struct file *filp)
 {
        struct ib_umad_file *file = filp->private_data;
+       struct ib_umad_packet *packet, *tmp;
        int i;
 
        for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
@@ -507,6 +508,9 @@ static int ib_umad_close(struct inode *inode, struct file *filp)
                        ib_unregister_mad_agent(file->agent[i]);
                }
 
+       list_for_each_entry_safe(packet, tmp, &file->recv_list, list)
+               kfree(packet);
+
        kfree(file);
 
        return 0;
index f4f747707b30d462d2f5fcce2945ebac6ee9c938..00222285eb9a20ed0345784f3899fdbd8b5aa319 100644 (file)
@@ -147,7 +147,7 @@ struct ib_sa_path_rec {
        /* reserved */
        u8           sl;
        u8           mtu_selector;
-       enum ib_mtu  mtu;
+       u8           mtu;
        u8           rate_selector;
        u8           rate;
        u8           packet_life_time_selector;
@@ -180,7 +180,7 @@ struct ib_sa_mcmember_rec {
        u32          qkey;
        u16          mlid;
        u8           mtu_selector;
-       enum         ib_mtu mtu;
+       u8           mtu;
        u8           traffic_class;
        u16          pkey;
        u8           rate_selector;
index 6282f460aba00073cff67a3ea46acf3ff7c7feeb..1d93f50929049332e9ec2397cd67dfce9dfb2fe9 100644 (file)
@@ -68,23 +68,3 @@ config GAMEPORT_CS461X
        depends on PCI
 
 endif
-
-# Yes, SOUND_GAMEPORT looks a bit odd. Yes, it ends up being turned on
-# in every .config. Please don't touch it. It is here to handle an
-# unusual dependency between GAMEPORT and sound drivers.
-#
-# Some sound drivers call gameport functions. If GAMEPORT is
-# not selected, empty stubs are provided for the functions and all is
-# well.
-# If GAMEPORT is built in, everything is fine.
-# If GAMEPORT is a module, however, it would need to be loaded for the
-# sound driver to be able to link properly. Therefore, the sound
-# driver must be a module as well in that case. Since there's no way
-# to express that directly in Kconfig, we use SOUND_GAMEPORT to
-# express it. SOUND_GAMEPORT boils down to "if GAMEPORT is 'm',
-# anything that depends on SOUND_GAMEPORT must be 'm' as well. if
-# GAMEPORT is 'y' or 'n', it can be anything".
-config SOUND_GAMEPORT
-       tristate
-       default m if GAMEPORT=m
-       default y
index 7d7527f8b02dc6f832cfcde761138bbd17b9d0c8..627d343dfba17cecce6aaa64cc27471f600a01ed 100644 (file)
@@ -422,7 +422,7 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
                        joydev->nkey++;
                }
 
-       for (i = 0; i < BTN_JOYSTICK - BTN_MISC + 1; i++)
+       for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++)
                if (test_bit(i + BTN_MISC, dev->keybit)) {
                        joydev->keymap[i] = joydev->nkey;
                        joydev->keypam[joydev->nkey] = i + BTN_MISC;
index ff66ed4ee2cd0d77a0123560b854ca9f8bfc8368..48fdf1e517cfb07c3771a79f692ca63dd1cdea55 100644 (file)
@@ -54,7 +54,7 @@ static int atkbd_softraw = 1;
 module_param_named(softraw, atkbd_softraw, bool, 0);
 MODULE_PARM_DESC(softraw, "Use software generated rawmode");
 
-static int atkbd_scroll = 1;
+static int atkbd_scroll = 0;
 module_param_named(scroll, atkbd_scroll, bool, 0);
 MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
 
@@ -171,9 +171,9 @@ static struct {
        unsigned char set2;
 } atkbd_scroll_keys[] = {
        { ATKBD_SCR_1,     0xc5 },
-       { ATKBD_SCR_2,     0xa9 },
-       { ATKBD_SCR_4,     0xb6 },
-       { ATKBD_SCR_8,     0xa7 },
+       { ATKBD_SCR_2,     0x9d },
+       { ATKBD_SCR_4,     0xa4 },
+       { ATKBD_SCR_8,     0x9b },
        { ATKBD_SCR_CLICK, 0xe0 },
        { ATKBD_SCR_LEFT,  0xcb },
        { ATKBD_SCR_RIGHT, 0xd2 },
@@ -465,8 +465,10 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co
                        if (atkbd->softrepeat) return 0;
 
                        i = j = 0;
-                       while (i < 32 && period[i] < dev->rep[REP_PERIOD]) i++;
-                       while (j < 4 && delay[j] < dev->rep[REP_DELAY]) j++;
+                       while (i < 31 && period[i] < dev->rep[REP_PERIOD])
+                               i++;
+                       while (j < 3 && delay[j] < dev->rep[REP_DELAY])
+                               j++;
                        dev->rep[REP_PERIOD] = period[i];
                        dev->rep[REP_DELAY] = delay[j];
                        param[0] = i | (j << 5);
index 1f85a9718c89847e16053c1cae1614cd4e16a439..42a9f7f6f8cb2a9b31e65404959dfbb1305be942 100644 (file)
@@ -341,6 +341,8 @@ static int alps_reconnect(struct psmouse *psmouse)
        unsigned char param[4];
        int version;
 
+       psmouse_reset(psmouse);
+
        if (!(priv->i = alps_get_model(psmouse, &version)))
                return -1;
 
@@ -395,7 +397,7 @@ int alps_init(struct psmouse *psmouse)
        }
 
        if (param[0] & 0x04) {
-               printk(KERN_INFO "  Enabling hardware tapping\n");
+               printk(KERN_INFO "alps.c: Enabling hardware tapping\n");
                if (alps_tap_mode(psmouse, 1))
                        printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
        }
index cd8509549eac60dcebfbe37144eca1eb720baa1e..019034b21a0bc91d3f0f941b05e7e495b6b69a08 100644 (file)
@@ -518,13 +518,16 @@ static int psmouse_probe(struct psmouse *psmouse)
 /*
  * First, we check if it's a mouse. It should send 0x00 or 0x03
  * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer.
+ * Sunrex K8561 IR Keyboard/Mouse reports 0xff on second and subsequent
+ * ID queries, probably due to a firmware bug.
  */
 
        param[0] = 0xa5;
        if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
                return -1;
 
-       if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04)
+       if (param[0] != 0x00 && param[0] != 0x03 &&
+           param[0] != 0x04 && param[0] != 0xff)
                return -1;
 
 /*
@@ -972,7 +975,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
                return -EINVAL;
 
        if (!strncmp(val, "any", 3)) {
-               *((unsigned int *)kp->arg) = -1UL;
+               *((unsigned int *)kp->arg) = -1U;
                return 0;
        }
 
index 69832f8fb7202e4716e23d529a7f2ac33c8db60f..36c721227b681cfd4e28f3b7ac5cd0265c56d9b7 100644 (file)
@@ -143,39 +143,6 @@ static int synaptics_identify(struct psmouse *psmouse)
        return -1;
 }
 
-static void print_ident(struct synaptics_data *priv)
-{
-       printk(KERN_INFO "Synaptics Touchpad, model: %ld\n", SYN_ID_MODEL(priv->identity));
-       printk(KERN_INFO " Firmware: %ld.%ld\n", SYN_ID_MAJOR(priv->identity),
-              SYN_ID_MINOR(priv->identity));
-       if (SYN_MODEL_ROT180(priv->model_id))
-               printk(KERN_INFO " 180 degree mounted touchpad\n");
-       if (SYN_MODEL_PORTRAIT(priv->model_id))
-               printk(KERN_INFO " portrait touchpad\n");
-       printk(KERN_INFO " Sensor: %ld\n", SYN_MODEL_SENSOR(priv->model_id));
-       if (SYN_MODEL_NEWABS(priv->model_id))
-               printk(KERN_INFO " new absolute packet format\n");
-       if (SYN_MODEL_PEN(priv->model_id))
-               printk(KERN_INFO " pen detection\n");
-
-       if (SYN_CAP_EXTENDED(priv->capabilities)) {
-               printk(KERN_INFO " Touchpad has extended capability bits\n");
-               if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
-                       printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n",
-                              (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)));
-               if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
-                       printk(KERN_INFO " -> middle button\n");
-               if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
-                       printk(KERN_INFO " -> four buttons\n");
-               if (SYN_CAP_MULTIFINGER(priv->capabilities))
-                       printk(KERN_INFO " -> multifinger detection\n");
-               if (SYN_CAP_PALMDETECT(priv->capabilities))
-                       printk(KERN_INFO " -> palm detection\n");
-               if (SYN_CAP_PASS_THROUGH(priv->capabilities))
-                       printk(KERN_INFO " -> pass-through port\n");
-       }
-}
-
 static int synaptics_query_hardware(struct psmouse *psmouse)
 {
        int retries = 0;
@@ -666,7 +633,11 @@ int synaptics_init(struct psmouse *psmouse)
 
        priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
 
-       print_ident(priv);
+       printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n",
+               SYN_ID_MODEL(priv->identity),
+               SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
+               priv->model_id, priv->capabilities, priv->ext_cap);
+
        set_input_params(&psmouse->dev, priv);
 
        psmouse->protocol_handler = synaptics_process_byte;
index 564974ce57935402ceb2e44471d727b07a056070..96fb9870834abfbb6b15b2a2df423b315dbc9da1 100644 (file)
@@ -101,6 +101,7 @@ struct mousedev_list {
        unsigned char ready, buffer, bufsiz;
        unsigned char imexseq, impsseq;
        enum mousedev_emul mode;
+       unsigned long last_buttons;
 };
 
 #define MOUSEDEV_SEQ_LEN       6
@@ -224,7 +225,7 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h
                spin_lock_irqsave(&list->packet_lock, flags);
 
                p = &list->packets[list->head];
-               if (list->ready && p->buttons != packet->buttons) {
+               if (list->ready && p->buttons != mousedev->packet.buttons) {
                        unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN;
                        if (new_head != list->tail) {
                                p = &list->packets[list->head = new_head];
@@ -249,10 +250,13 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h
                p->dz += packet->dz;
                p->buttons = mousedev->packet.buttons;
 
-               list->ready = 1;
+               if (p->dx || p->dy || p->dz || p->buttons != list->last_buttons)
+                       list->ready = 1;
 
                spin_unlock_irqrestore(&list->packet_lock, flags);
-               kill_fasync(&list->fasync, SIGIO, POLL_IN);
+
+               if (list->ready)
+                       kill_fasync(&list->fasync, SIGIO, POLL_IN);
        }
 
        wake_up_interruptible(&mousedev->wait);
@@ -477,9 +481,10 @@ static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data)
        }
 
        if (!p->dx && !p->dy && !p->dz) {
-               if (list->tail == list->head)
+               if (list->tail == list->head) {
                        list->ready = 0;
-               else
+                       list->last_buttons = p->buttons;
+               } else
                        list->tail = (list->tail + 1) % PACKET_QUEUE_LEN;
        }
 
index f64867808fea9ddde56c298e67fac8771b53f69c..0487ecbb8a49232d26b32a26c63b5e5911d31f02 100644 (file)
@@ -88,9 +88,11 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
 };
 
 /*
- * Some Fujitsu notebooks are ahving trouble with touhcpads if
+ * Some Fujitsu notebooks are having trouble with touchpads if
  * active multiplexing mode is activated. Luckily they don't have
  * external PS/2 ports so we can safely disable it.
+ * ... apparently some Toshibas don't like MUX mode either and
+ * die horrible death on reboot.
  */
 static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
        {
@@ -114,6 +116,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
                },
        },
+       {
+               .ident = "Fujitsu Lifebook S6230",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
+               },
+       },
        {
                .ident = "Fujitsu T70H",
                .matches = {
@@ -121,6 +130,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
                },
        },
+       {
+               .ident = "Toshiba P10",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
+               },
+       },
        { }
 };
 
@@ -215,11 +231,15 @@ static struct pnp_driver i8042_pnp_aux_driver = {
 
 static void i8042_pnp_exit(void)
 {
-       if (i8042_pnp_kbd_registered)
+       if (i8042_pnp_kbd_registered) {
+               i8042_pnp_kbd_registered = 0;
                pnp_unregister_driver(&i8042_pnp_kbd_driver);
+       }
 
-       if (i8042_pnp_aux_registered)
+       if (i8042_pnp_aux_registered) {
+               i8042_pnp_aux_registered = 0;
                pnp_unregister_driver(&i8042_pnp_aux_driver);
+       }
 }
 
 static int i8042_pnp_init(void)
@@ -227,7 +247,7 @@ static int i8042_pnp_init(void)
        int result_kbd, result_aux;
 
        if (i8042_nopnp) {
-               printk("i8042: PNP detection disabled\n");
+               printk(KERN_INFO "i8042: PNP detection disabled\n");
                return 0;
        }
 
@@ -241,7 +261,7 @@ static int i8042_pnp_init(void)
 #if defined(__ia64__)
                return -ENODEV;
 #else
-               printk(KERN_WARNING "PNP: No PS/2 controller found. Probing ports directly.\n");
+               printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n");
                return 0;
 #endif
        }
@@ -265,7 +285,7 @@ static int i8042_pnp_init(void)
                i8042_pnp_kbd_irq = i8042_kbd_irq;
        }
 
-       if (result_aux > 0 && !i8042_pnp_aux_irq) {
+       if (!i8042_pnp_aux_irq) {
                printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq);
                i8042_pnp_aux_irq = i8042_aux_irq;
        }
index 8e63e464d361e18a7040f9c3ab52a2eff781bfa5..5900de3c3f4f04b0936d2788edf5461681dc075e 100644 (file)
@@ -698,6 +698,26 @@ static void i8042_timer_func(unsigned long data)
        i8042_interrupt(0, NULL, NULL);
 }
 
+static int i8042_ctl_test(void)
+{
+       unsigned char param;
+
+       if (!i8042_reset)
+               return 0;
+
+       if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
+               printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
+               return -1;
+       }
+
+       if (param != I8042_RET_CTL_TEST) {
+               printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
+                        param, I8042_RET_CTL_TEST);
+               return -1;
+       }
+
+       return 0;
+}
 
 /*
  * i8042_controller init initializes the i8042 controller, and,
@@ -719,21 +739,8 @@ static int i8042_controller_init(void)
                return -1;
        }
 
-       if (i8042_reset) {
-
-               unsigned char param;
-
-               if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
-                       printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
-                       return -1;
-               }
-
-               if (param != I8042_RET_CTL_TEST) {
-                       printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
-                                param, I8042_RET_CTL_TEST);
-                       return -1;
-               }
-       }
+       if (i8042_ctl_test())
+               return -1;
 
 /*
  * Save the CTR for restoral on unload / reboot.
@@ -802,15 +809,11 @@ static int i8042_controller_init(void)
  */
 static void i8042_controller_reset(void)
 {
-       unsigned char param;
-
 /*
  * Reset the controller if requested.
  */
 
-       if (i8042_reset)
-               if (i8042_command(&param, I8042_CMD_CTL_TEST))
-                       printk(KERN_ERR "i8042.c: i8042 controller reset timeout.\n");
+       i8042_ctl_test();
 
 /*
  * Disable MUX mode if present.
@@ -922,8 +925,11 @@ static int i8042_resume(struct device *dev, u32 level)
        if (level != RESUME_ENABLE)
                return 0;
 
-       if (i8042_controller_init()) {
-               printk(KERN_ERR "i8042: resume failed\n");
+       if (i8042_ctl_test())
+               return -1;
+
+       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+               printk(KERN_ERR "i8042: Can't write CTR\n");
                return -1;
        }
 
index 3313e2daeab022dc1d391ddc19be97bd23b286b7..0beacb77ee18372585282a5aab58b04f06a615a9 100644 (file)
@@ -388,6 +388,24 @@ static ssize_t serio_show_id_extra(struct device *dev, char *buf)
        return sprintf(buf, "%02x\n", serio->id.extra);
 }
 
+static DEVICE_ATTR(type, S_IRUGO, serio_show_id_type, NULL);
+static DEVICE_ATTR(proto, S_IRUGO, serio_show_id_proto, NULL);
+static DEVICE_ATTR(id, S_IRUGO, serio_show_id_id, NULL);
+static DEVICE_ATTR(extra, S_IRUGO, serio_show_id_extra, NULL);
+
+static struct attribute *serio_device_id_attrs[] = {
+       &dev_attr_type.attr,
+       &dev_attr_proto.attr,
+       &dev_attr_id.attr,
+       &dev_attr_extra.attr,
+       NULL
+};
+
+static struct attribute_group serio_id_attr_group = {
+       .name   = "id",
+       .attrs  = serio_device_id_attrs,
+};
+
 static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t count)
 {
        struct serio *serio = to_serio_port(dev);
@@ -444,10 +462,6 @@ static ssize_t serio_set_bind_mode(struct device *dev, const char *buf, size_t c
 
 static struct device_attribute serio_device_attrs[] = {
        __ATTR(description, S_IRUGO, serio_show_description, NULL),
-       __ATTR(id_type, S_IRUGO, serio_show_id_type, NULL),
-       __ATTR(id_proto, S_IRUGO, serio_show_id_proto, NULL),
-       __ATTR(id_id, S_IRUGO, serio_show_id_id, NULL),
-       __ATTR(id_extra, S_IRUGO, serio_show_id_extra, NULL),
        __ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver),
        __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode),
        __ATTR_NULL
@@ -498,6 +512,7 @@ static void serio_add_port(struct serio *serio)
        if (serio->start)
                serio->start(serio);
        device_add(&serio->dev);
+       sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
        serio->registered = 1;
 }
 
@@ -526,6 +541,7 @@ static void serio_destroy_port(struct serio *serio)
        }
 
        if (serio->registered) {
+               sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group);
                device_del(&serio->dev);
                list_del_init(&serio->node);
                serio->registered = 0;
@@ -779,7 +795,6 @@ static int serio_resume(struct device *dev)
        struct serio *serio = to_serio_port(dev);
 
        if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
-               serio_disconnect_port(serio);
                /*
                 * Driver re-probing can take a while, so better let kseriod
                 * deal with it.
index 22f73683952bffaa99155e16f8a3bc666bb3e770..f6b85222ba3dc9033fff294d6f45e7cc2f6986e3 100644 (file)
@@ -27,11 +27,15 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS_LDISC(N_MOUSE);
 
 #define SERPORT_BUSY   1
+#define SERPORT_ACTIVE 2
+#define SERPORT_DEAD   3
 
 struct serport {
        struct tty_struct *tty;
        wait_queue_head_t wait;
        struct serio *serio;
+       struct serio_device_id id;
+       spinlock_t lock;
        unsigned long flags;
 };
 
@@ -45,11 +49,29 @@ static int serport_serio_write(struct serio *serio, unsigned char data)
        return -(serport->tty->driver->write(serport->tty, &data, 1) != 1);
 }
 
+static int serport_serio_open(struct serio *serio)
+{
+       struct serport *serport = serio->port_data;
+       unsigned long flags;
+
+       spin_lock_irqsave(&serport->lock, flags);
+       set_bit(SERPORT_ACTIVE, &serport->flags);
+       spin_unlock_irqrestore(&serport->lock, flags);
+
+       return 0;
+}
+
+
 static void serport_serio_close(struct serio *serio)
 {
        struct serport *serport = serio->port_data;
+       unsigned long flags;
+
+       spin_lock_irqsave(&serport->lock, flags);
+       clear_bit(SERPORT_ACTIVE, &serport->flags);
+       set_bit(SERPORT_DEAD, &serport->flags);
+       spin_unlock_irqrestore(&serport->lock, flags);
 
-       serport->serio->id.type = 0;
        wake_up_interruptible(&serport->wait);
 }
 
@@ -61,36 +83,21 @@ static void serport_serio_close(struct serio *serio)
 static int serport_ldisc_open(struct tty_struct *tty)
 {
        struct serport *serport;
-       struct serio *serio;
-       char name[64];
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       serport = kmalloc(sizeof(struct serport), GFP_KERNEL);
-       serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
-       if (unlikely(!serport || !serio)) {
-               kfree(serport);
-               kfree(serio);
+       serport = kcalloc(1, sizeof(struct serport), GFP_KERNEL);
+       if (!serport)
                return -ENOMEM;
-       }
 
-       memset(serport, 0, sizeof(struct serport));
-       serport->serio = serio;
-       set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
        serport->tty = tty;
-       tty->disc_data = serport;
-
-       memset(serio, 0, sizeof(struct serio));
-       strlcpy(serio->name, "Serial port", sizeof(serio->name));
-       snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name));
-       serio->id.type = SERIO_RS232;
-       serio->write = serport_serio_write;
-       serio->close = serport_serio_close;
-       serio->port_data = serport;
-
+       spin_lock_init(&serport->lock);
        init_waitqueue_head(&serport->wait);
 
+       tty->disc_data = serport;
+       set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+
        return 0;
 }
 
@@ -100,7 +107,8 @@ static int serport_ldisc_open(struct tty_struct *tty)
 
 static void serport_ldisc_close(struct tty_struct *tty)
 {
-       struct serport *serport = (struct serport*) tty->disc_data;
+       struct serport *serport = (struct serport *) tty->disc_data;
+
        kfree(serport);
 }
 
@@ -116,9 +124,19 @@ static void serport_ldisc_close(struct tty_struct *tty)
 static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
 {
        struct serport *serport = (struct serport*) tty->disc_data;
+       unsigned long flags;
        int i;
+
+       spin_lock_irqsave(&serport->lock, flags);
+
+       if (!test_bit(SERPORT_ACTIVE, &serport->flags))
+               goto out;
+
        for (i = 0; i < count; i++)
                serio_interrupt(serport->serio, cp[i], 0, NULL);
+
+out:
+       spin_unlock_irqrestore(&serport->lock, flags);
 }
 
 /*
@@ -141,16 +159,33 @@ static int serport_ldisc_room(struct tty_struct *tty)
 static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, unsigned char __user * buf, size_t nr)
 {
        struct serport *serport = (struct serport*) tty->disc_data;
+       struct serio *serio;
        char name[64];
 
        if (test_and_set_bit(SERPORT_BUSY, &serport->flags))
                return -EBUSY;
 
+       serport->serio = serio = kcalloc(1, sizeof(struct serio), GFP_KERNEL);
+       if (!serio)
+               return -ENOMEM;
+
+       strlcpy(serio->name, "Serial port", sizeof(serio->name));
+       snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name));
+       serio->id = serport->id;
+       serio->id.type = SERIO_RS232;
+       serio->write = serport_serio_write;
+       serio->open = serport_serio_open;
+       serio->close = serport_serio_close;
+       serio->port_data = serport;
+
        serio_register_port(serport->serio);
        printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name));
-       wait_event_interruptible(serport->wait, !serport->serio->id.type);
+
+       wait_event_interruptible(serport->wait, test_bit(SERPORT_DEAD, &serport->flags));
        serio_unregister_port(serport->serio);
+       serport->serio = NULL;
 
+       clear_bit(SERPORT_DEAD, &serport->flags);
        clear_bit(SERPORT_BUSY, &serport->flags);
 
        return 0;
@@ -163,16 +198,15 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u
 static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
        struct serport *serport = (struct serport*) tty->disc_data;
-       struct serio *serio = serport->serio;
        unsigned long type;
 
        if (cmd == SPIOCSTYPE) {
                if (get_user(type, (unsigned long __user *) arg))
                        return -EFAULT;
 
-               serio->id.proto = type & 0x000000ff;
-               serio->id.id    = (type & 0x0000ff00) >> 8;
-               serio->id.extra = (type & 0x00ff0000) >> 16;
+               serport->id.proto = type & 0x000000ff;
+               serport->id.id    = (type & 0x0000ff00) >> 8;
+               serport->id.extra = (type & 0x00ff0000) >> 16;
 
                return 0;
        }
@@ -182,9 +216,13 @@ static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsi
 
 static void serport_ldisc_write_wakeup(struct tty_struct * tty)
 {
-       struct serport *sp = (struct serport *) tty->disc_data;
+       struct serport *serport = (struct serport *) tty->disc_data;
+       unsigned long flags;
 
-       serio_drv_write_wakeup(sp->serio);
+       spin_lock_irqsave(&serport->lock, flags);
+       if (test_bit(SERPORT_ACTIVE, &serport->flags))
+               serio_drv_write_wakeup(serport->serio);
+       spin_unlock_irqrestore(&serport->lock, flags);
 }
 
 /*
index c9d0a153671c6a4e68dc62820e036b0faacb4bba..53a27e43dd235285d8b4c283c7c12364433ba102 100644 (file)
@@ -68,8 +68,7 @@ static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs)
 
        if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' ||
                (gunze->data[0] != 'T' && gunze->data[0] != 'R')) {
-               gunze->data[10] = 0;
-               printk(KERN_WARNING "gunze.c: bad packet: >%s<\n", gunze->data);
+               printk(KERN_WARNING "gunze.c: bad packet: >%.*s<\n", GUNZE_MAX_LENGTH, gunze->data);
                return;
        }
 
index e0ac63effa5546e69eb131c31050e9f344a496ff..d09308f30960533a25dc1fe0959236f0c144078a 100644 (file)
 #define MANUAL_MASK  0xe0
 #define AUTO_MASK    0x20
 
-static u8 TEMP_REG[3]    = {0x26, 0x25, 0x27}; /* local, cpu, gpu */
-static u8 LIMIT_REG[3]   = {0x6b, 0x6a, 0x6c}; /* local, cpu, gpu */
+static u8 TEMP_REG[3]    = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */
+static u8 LIMIT_REG[3]   = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */
 static u8 MANUAL_MODE[2] = {0x5c, 0x5d};       
 static u8 REM_CONTROL[2] = {0x00, 0x40};
 static u8 FAN_SPEED[2]   = {0x28, 0x2a};
 static u8 FAN_SPD_SET[2] = {0x30, 0x31};
 
-static u8 default_limits_local[3] = {70, 50, 70};    /* local, cpu, gpu */
-static u8 default_limits_chip[3] = {80, 65, 80};    /* local, cpu, gpu */
+static u8 default_limits_local[3] = {70, 50, 70};    /* local, sensor1, sensor2 */
+static u8 default_limits_chip[3] = {80, 65, 80};    /* local, sensor1, sensor2 */
+static char *sensor_location[3] = {NULL, NULL, NULL};
 
 static int limit_adjust = 0;
 static int fan_speed = -1;
@@ -58,7 +59,7 @@ MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and "
 MODULE_LICENSE("GPL");
 
 module_param(limit_adjust, int, 0644);
-MODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 cpu, 70 gpu) "
+MODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 sensor1, 70 sensor2) "
                 "by N degrees.");
 
 module_param(fan_speed, int, 0644);
@@ -213,10 +214,10 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
        if (th->last_speed[fan] != speed) {
                if (speed == -1)
                        printk(KERN_DEBUG "adt746x: Setting speed to automatic "
-                               "for %s fan.\n", fan?"GPU":"CPU");
+                               "for %s fan.\n", sensor_location[fan+1]);
                else
                        printk(KERN_DEBUG "adt746x: Setting speed to %d "
-                               "for %s fan.\n", speed, fan?"GPU":"CPU");
+                               "for %s fan.\n", speed, sensor_location[fan+1]);
        } else
                return;
        
@@ -300,11 +301,11 @@ static void update_fans_speed (struct thermostat *th)
                        printk(KERN_DEBUG "adt746x: setting fans speed to %d "
                                         "(limit exceeded by %d on %s) \n",
                                        new_speed, var,
-                                       fan_number?"GPU/pwr":"CPU");
+                                       sensor_location[fan_number+1]);
                        write_both_fan_speed(th, new_speed);
                        th->last_var[fan_number] = var;
                } else if (var < -2) {
-                       /* don't stop fan if GPU/power is cold and CPU is not
+                       /* don't stop fan if sensor2 is cold and sensor1 is not
                         * so cold (lastvar >= -1) */
                        if (i == 2 && lastvar < -1) {
                                if (th->last_speed[fan_number] != 0)
@@ -318,7 +319,7 @@ static void update_fans_speed (struct thermostat *th)
 
                if (started)
                        return; /* we don't want to re-stop the fan
-                               * if CPU is heating and GPU/power is not */
+                               * if sensor1 is heating and sensor2 is not */
        }
 }
 
@@ -353,7 +354,7 @@ static int monitor_task(void *arg)
 
 static void set_limit(struct thermostat *th, int i)
 {
-               /* Set CPU limit higher to avoid powerdowns */ 
+               /* Set sensor1 limit higher to avoid powerdowns */
                th->limits[i] = default_limits_chip[i] + limit_adjust;
                write_reg(th, LIMIT_REG[i], th->limits[i]);
                
@@ -461,6 +462,12 @@ static ssize_t show_##name(struct device *dev, char *buf)  \
        return sprintf(buf, "%d\n", data);                      \
 }
 
+#define BUILD_SHOW_FUNC_STR(name, data)                                \
+static ssize_t show_##name(struct device *dev, char *buf)      \
+{                                                              \
+       return sprintf(buf, "%s\n", data);                      \
+}
+
 #define BUILD_SHOW_FUNC_FAN(name, data)                                \
 static ssize_t show_##name(struct device *dev, char *buf)       \
 {                                                              \
@@ -476,7 +483,7 @@ static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \
        int val;                                                \
        int i;                                                  \
        val = simple_strtol(buf, NULL, 10);                     \
-       printk(KERN_INFO "Adjusting limits by %d°C\n", val);    \
+       printk(KERN_INFO "Adjusting limits by %d degrees\n", val);      \
        limit_adjust = val;                                     \
        for (i=0; i < 3; i++)                                   \
                set_limit(thermostat, i);                       \
@@ -495,35 +502,41 @@ static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \
        return n;                                               \
 }
 
-BUILD_SHOW_FUNC_INT(cpu_temperature,    (read_reg(thermostat, TEMP_REG[1])))
-BUILD_SHOW_FUNC_INT(gpu_temperature,    (read_reg(thermostat, TEMP_REG[2])))
-BUILD_SHOW_FUNC_INT(cpu_limit,          thermostat->limits[1])
-BUILD_SHOW_FUNC_INT(gpu_limit,          thermostat->limits[2])
+BUILD_SHOW_FUNC_INT(sensor1_temperature,        (read_reg(thermostat, TEMP_REG[1])))
+BUILD_SHOW_FUNC_INT(sensor2_temperature,        (read_reg(thermostat, TEMP_REG[2])))
+BUILD_SHOW_FUNC_INT(sensor1_limit,              thermostat->limits[1])
+BUILD_SHOW_FUNC_INT(sensor2_limit,              thermostat->limits[2])
+BUILD_SHOW_FUNC_STR(sensor1_location,           sensor_location[1])
+BUILD_SHOW_FUNC_STR(sensor2_location,           sensor_location[2])
 
 BUILD_SHOW_FUNC_INT(specified_fan_speed, fan_speed)
-BUILD_SHOW_FUNC_FAN(cpu_fan_speed,      0)
-BUILD_SHOW_FUNC_FAN(gpu_fan_speed,      1)
+BUILD_SHOW_FUNC_FAN(sensor1_fan_speed,  0)
+BUILD_SHOW_FUNC_FAN(sensor2_fan_speed,  1)
 
 BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed)
 BUILD_SHOW_FUNC_INT(limit_adjust,       limit_adjust)
 BUILD_STORE_FUNC_DEG(limit_adjust,      thermostat)
                
-static DEVICE_ATTR(cpu_temperature,    S_IRUGO,
-                  show_cpu_temperature,NULL);
-static DEVICE_ATTR(gpu_temperature,    S_IRUGO,
-                  show_gpu_temperature,NULL);
-static DEVICE_ATTR(cpu_limit,          S_IRUGO,
-                  show_cpu_limit,      NULL);
-static DEVICE_ATTR(gpu_limit,          S_IRUGO,
-                  show_gpu_limit,      NULL);
+static DEVICE_ATTR(sensor1_temperature,        S_IRUGO,
+                  show_sensor1_temperature,NULL);
+static DEVICE_ATTR(sensor2_temperature,        S_IRUGO,
+                  show_sensor2_temperature,NULL);
+static DEVICE_ATTR(sensor1_limit, S_IRUGO,
+                  show_sensor1_limit,  NULL);
+static DEVICE_ATTR(sensor2_limit, S_IRUGO,
+                  show_sensor2_limit,  NULL);
+static DEVICE_ATTR(sensor1_location, S_IRUGO,
+                  show_sensor1_location, NULL);
+static DEVICE_ATTR(sensor2_location, S_IRUGO,
+                  show_sensor2_location, NULL);
 
 static DEVICE_ATTR(specified_fan_speed,        S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
                   show_specified_fan_speed,store_specified_fan_speed);
 
-static DEVICE_ATTR(cpu_fan_speed,      S_IRUGO,
-                  show_cpu_fan_speed,  NULL);
-static DEVICE_ATTR(gpu_fan_speed,      S_IRUGO,
-                  show_gpu_fan_speed,  NULL);
+static DEVICE_ATTR(sensor1_fan_speed,  S_IRUGO,
+                  show_sensor1_fan_speed,      NULL);
+static DEVICE_ATTR(sensor2_fan_speed,  S_IRUGO,
+                  show_sensor2_fan_speed,      NULL);
 
 static DEVICE_ATTR(limit_adjust,       S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
                   show_limit_adjust,   store_limit_adjust);
@@ -534,6 +547,7 @@ thermostat_init(void)
 {
        struct device_node* np;
        u32 *prop;
+       int i = 0, offset = 0;
        
        np = of_find_node_by_name(NULL, "fan");
        if (!np)
@@ -545,6 +559,12 @@ thermostat_init(void)
        else
                return -ENODEV;
 
+       prop = (u32 *)get_property(np, "hwsensor-params-version", NULL);
+       printk(KERN_INFO "adt746x: version %d (%ssupported)\n", *prop,
+                        (*prop == 1)?"":"un");
+       if (*prop != 1)
+               return -ENODEV;
+
        prop = (u32 *)get_property(np, "reg", NULL);
        if (!prop)
                return -ENODEV;
@@ -563,6 +583,23 @@ thermostat_init(void)
                         "limit_adjust: %d, fan_speed: %d\n",
                         therm_bus, therm_address, limit_adjust, fan_speed);
 
+       if (get_property(np, "hwsensor-location", NULL)) {
+               for (i = 0; i < 3; i++) {
+                       sensor_location[i] = get_property(np,
+                                       "hwsensor-location", NULL) + offset;
+
+                       if (sensor_location[i] == NULL)
+                               sensor_location[i] = "";
+
+                       printk(KERN_INFO "sensor %d: %s\n", i, sensor_location[i]);
+                       offset += strlen(sensor_location[i]) + 1;
+               }
+       } else {
+               sensor_location[0] = "?";
+               sensor_location[1] = "?";
+               sensor_location[2] = "?";
+       }
+
        of_dev = of_platform_device_create(np, "temperatures");
        
        if (of_dev == NULL) {
@@ -570,15 +607,17 @@ thermostat_init(void)
                return -ENODEV;
        }
        
-       device_create_file(&of_dev->dev, &dev_attr_cpu_temperature);
-       device_create_file(&of_dev->dev, &dev_attr_gpu_temperature);
-       device_create_file(&of_dev->dev, &dev_attr_cpu_limit);
-       device_create_file(&of_dev->dev, &dev_attr_gpu_limit);
+       device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
+       device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
+       device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
+       device_create_file(&of_dev->dev, &dev_attr_sensor2_limit);
+       device_create_file(&of_dev->dev, &dev_attr_sensor1_location);
+       device_create_file(&of_dev->dev, &dev_attr_sensor2_location);
        device_create_file(&of_dev->dev, &dev_attr_limit_adjust);
        device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed);
-       device_create_file(&of_dev->dev, &dev_attr_cpu_fan_speed);
+       device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
        if(therm_type == ADT7460)
-               device_create_file(&of_dev->dev, &dev_attr_gpu_fan_speed);
+               device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
 
 #ifndef CONFIG_I2C_KEYWEST
        request_module("i2c-keywest");
@@ -591,17 +630,19 @@ static void __exit
 thermostat_exit(void)
 {
        if (of_dev) {
-               device_remove_file(&of_dev->dev, &dev_attr_cpu_temperature);
-               device_remove_file(&of_dev->dev, &dev_attr_gpu_temperature);
-               device_remove_file(&of_dev->dev, &dev_attr_cpu_limit);
-               device_remove_file(&of_dev->dev, &dev_attr_gpu_limit);
+               device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature);
+               device_remove_file(&of_dev->dev, &dev_attr_sensor2_temperature);
+               device_remove_file(&of_dev->dev, &dev_attr_sensor1_limit);
+               device_remove_file(&of_dev->dev, &dev_attr_sensor2_limit);
+               device_remove_file(&of_dev->dev, &dev_attr_sensor1_location);
+               device_remove_file(&of_dev->dev, &dev_attr_sensor2_location);
                device_remove_file(&of_dev->dev, &dev_attr_limit_adjust);
                device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed);
-               device_remove_file(&of_dev->dev, &dev_attr_cpu_fan_speed);
+               device_remove_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
 
                if(therm_type == ADT7460)
                        device_remove_file(&of_dev->dev,
-                                          &dev_attr_gpu_fan_speed);
+                                          &dev_attr_sensor2_fan_speed);
 
                of_device_unregister(of_dev);
        }
index e654aa5eecd4946aa822b36659a5be8df8ced43f..b941ee220997adbc96b50b48862d0e47c687afda 100644 (file)
@@ -2421,7 +2421,7 @@ pmac_wakeup_devices(void)
 
        /* Re-enable local CPU interrupts */
        local_irq_enable();
-       mdelay(100);
+       mdelay(10);
        preempt_enable();
 
        /* Re-enable clock spreading on some machines */
@@ -2549,7 +2549,9 @@ powerbook_sleep_Core99(void)
                return ret;
        }
 
-       printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
+       /* Stop environment and ADB interrupts */
+       pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0);
+       pmu_wait_complete(&req);
 
        /* Tell PMU what events will wake us up */
        pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS,
@@ -2591,6 +2593,9 @@ powerbook_sleep_Core99(void)
        /* Restore VIA */
        restore_via_state();
 
+       /* tweak LPJ before cpufreq is there */
+       loops_per_jiffy *= 2;
+
        /* Restore video */
        pmac_call_early_video_resume();
 
@@ -2611,7 +2616,8 @@ powerbook_sleep_Core99(void)
        pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
        pmu_wait_complete(&req);
 
-       printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
+       /* Restore LPJ, cpufreq will adjust the cpu frequency */
+       loops_per_jiffy /= 2;
 
        pmac_wakeup_devices();
 
index 7006586645943b81d6b21bd7281b88380c62201a..c7067674dcb77ca8d1a2e4ee51f032a2bfb9aac8 100644 (file)
@@ -223,8 +223,10 @@ static struct emc_handler *alloc_emc_handler(void)
 {
        struct emc_handler *h = kmalloc(sizeof(*h), GFP_KERNEL);
 
-       if (h)
+       if (h) {
+               memset(h, 0, sizeof(*h));
                spin_lock_init(&h->lock);
+       }
 
        return h;
 }
@@ -259,8 +261,6 @@ static int emc_create(struct hw_handler *hwh, unsigned argc, char **argv)
        if (!h)
                return -ENOMEM;
 
-       memset(h, 0, sizeof(*h));
-
        hwh->context = h;
 
        if ((h->short_trespass = short_trespass))
index ae63772e44c9c9f2b359e127704335f110aec12e..4cc0010e01569a16f0fd3bc53c2f3a365bff3e07 100644 (file)
@@ -23,7 +23,7 @@ struct hwh_internal {
 static LIST_HEAD(_hw_handlers);
 static DECLARE_RWSEM(_hwh_lock);
 
-struct hwh_internal *__find_hw_handler_type(const char *name)
+static struct hwh_internal *__find_hw_handler_type(const char *name)
 {
        struct hwh_internal *hwhi;
 
index 43763a0bd0961f2bae1a52ef0582770fa4600b80..0c1b8520ef86f9105c20b45632eb00d9a114c8be 100644 (file)
@@ -101,6 +101,7 @@ typedef int (*action_fn) (struct pgpath *pgpath);
 
 static kmem_cache_t *_mpio_cache;
 
+struct workqueue_struct *kmultipathd;
 static void process_queued_ios(void *data);
 static void trigger_event(void *data);
 
@@ -308,7 +309,7 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
                bio_list_add(&m->queued_ios, bio);
                m->queue_size++;
                if (m->pg_init_required || !m->queue_io)
-                       schedule_work(&m->process_queued_ios);
+                       queue_work(kmultipathd, &m->process_queued_ios);
                pgpath = NULL;
                r = 0;
        } else if (!pgpath)
@@ -334,7 +335,7 @@ static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path)
 
        m->queue_if_no_path = queue_if_no_path;
        if (!m->queue_if_no_path)
-               schedule_work(&m->process_queued_ios);
+               queue_work(kmultipathd, &m->process_queued_ios);
 
        spin_unlock_irqrestore(&m->lock, flags);
 
@@ -800,7 +801,7 @@ static int fail_path(struct pgpath *pgpath)
        if (pgpath == m->current_pgpath)
                m->current_pgpath = NULL;
 
-       schedule_work(&m->trigger_event);
+       queue_work(kmultipathd, &m->trigger_event);
 
 out:
        spin_unlock_irqrestore(&m->lock, flags);
@@ -837,9 +838,9 @@ static int reinstate_path(struct pgpath *pgpath)
 
        m->current_pgpath = NULL;
        if (!m->nr_valid_paths++)
-               schedule_work(&m->process_queued_ios);
+               queue_work(kmultipathd, &m->process_queued_ios);
 
-       schedule_work(&m->trigger_event);
+       queue_work(kmultipathd, &m->trigger_event);
 
 out:
        spin_unlock_irqrestore(&m->lock, flags);
@@ -883,7 +884,7 @@ static void bypass_pg(struct multipath *m, struct priority_group *pg,
 
        spin_unlock_irqrestore(&m->lock, flags);
 
-       schedule_work(&m->trigger_event);
+       queue_work(kmultipathd, &m->trigger_event);
 }
 
 /*
@@ -913,7 +914,7 @@ static int switch_pg_num(struct multipath *m, const char *pgstr)
        }
        spin_unlock_irqrestore(&m->lock, flags);
 
-       schedule_work(&m->trigger_event);
+       queue_work(kmultipathd, &m->trigger_event);
        return 0;
 }
 
@@ -968,7 +969,7 @@ void dm_pg_init_complete(struct path *path, unsigned err_flags)
                m->current_pgpath = NULL;
                m->current_pg = NULL;
        }
-       schedule_work(&m->process_queued_ios);
+       queue_work(kmultipathd, &m->process_queued_ios);
        spin_unlock_irqrestore(&m->lock, flags);
 }
 
@@ -984,6 +985,9 @@ static int do_end_io(struct multipath *m, struct bio *bio,
        if (!error)
                return 0;       /* I/O complete */
 
+       if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio))
+               return error;
+
        spin_lock(&m->lock);
        if (!m->nr_valid_paths) {
                if (!m->queue_if_no_path || m->suspended) {
@@ -1018,7 +1022,7 @@ static int do_end_io(struct multipath *m, struct bio *bio,
        bio_list_add(&m->queued_ios, bio);
        m->queue_size++;
        if (!m->queue_io)
-               schedule_work(&m->process_queued_ios);
+               queue_work(kmultipathd, &m->process_queued_ios);
        spin_unlock(&m->lock);
 
        return 1;       /* io not complete */
@@ -1057,7 +1061,7 @@ static void multipath_presuspend(struct dm_target *ti)
        spin_lock_irqsave(&m->lock, flags);
        m->suspended = 1;
        if (m->queue_if_no_path)
-               schedule_work(&m->process_queued_ios);
+               queue_work(kmultipathd, &m->process_queued_ios);
        spin_unlock_irqrestore(&m->lock, flags);
 }
 
@@ -1274,6 +1278,15 @@ static int __init dm_multipath_init(void)
                return -EINVAL;
        }
 
+       kmultipathd = create_workqueue("kmpathd");
+       if (!kmultipathd) {
+               DMERR("%s: failed to create workqueue kmpathd",
+                               multipath_target.name);
+               dm_unregister_target(&multipath_target);
+               kmem_cache_destroy(_mpio_cache);
+               return -ENOMEM;
+       }
+
        DMINFO("dm-multipath version %u.%u.%u loaded",
               multipath_target.version[0], multipath_target.version[1],
               multipath_target.version[2]);
@@ -1285,6 +1298,8 @@ static void __exit dm_multipath_exit(void)
 {
        int r;
 
+       destroy_workqueue(kmultipathd);
+
        r = dm_unregister_target(&multipath_target);
        if (r < 0)
                DMERR("%s: target unregister failed %d",
index ac5c4bbec6c188b547ce1804be38e80bebf5a33d..a28c1c2b4ef5c703d2d5ce4f5c67bb2858483542 100644 (file)
@@ -26,7 +26,7 @@ struct ps_internal {
 static LIST_HEAD(_path_selectors);
 static DECLARE_RWSEM(_ps_lock);
 
-struct ps_internal *__find_path_selector_type(const char *name)
+static struct ps_internal *__find_path_selector_type(const char *name)
 {
        struct ps_internal *psi;
 
index ee175d4906c4de556aaddbcd4c4921a4799f3008..18e9b9953fcd32489a208b273927616da7dd4627 100644 (file)
@@ -242,7 +242,7 @@ static void free_devices(struct list_head *devices)
        }
 }
 
-void table_destroy(struct dm_table *t)
+static void table_destroy(struct dm_table *t)
 {
        unsigned int i;
 
index 7febc2cac73d893c37734ac2bf7d832ec4b42ed9..51c0639b248770e25405af6b07fbade900318df7 100644 (file)
@@ -55,7 +55,7 @@ static struct target_type zero_target = {
        .map    = zero_map,
 };
 
-int __init dm_zero_init(void)
+static int __init dm_zero_init(void)
 {
        int r = dm_register_target(&zero_target);
 
@@ -65,7 +65,7 @@ int __init dm_zero_init(void)
        return r;
 }
 
-void __exit dm_zero_exit(void)
+static void __exit dm_zero_exit(void)
 {
        int r = dm_unregister_target(&zero_target);
 
index 243ff6884e83f4c0b44d1bbbfbb14ddb5384ffa8..f6b03957efc7b8bbd70f28f8ca1230b95ffeb4a3 100644 (file)
@@ -97,6 +97,7 @@ struct mapped_device {
         * freeze/thaw support require holding onto a super block
         */
        struct super_block *frozen_sb;
+       struct block_device *frozen_bdev;
 };
 
 #define MIN_IOS 256
@@ -990,44 +991,50 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table)
  */
 static int __lock_fs(struct mapped_device *md)
 {
-       struct block_device *bdev;
+       int error = -ENOMEM;
 
        if (test_and_set_bit(DMF_FS_LOCKED, &md->flags))
                return 0;
 
-       bdev = bdget_disk(md->disk, 0);
-       if (!bdev) {
+       md->frozen_bdev = bdget_disk(md->disk, 0);
+       if (!md->frozen_bdev) {
                DMWARN("bdget failed in __lock_fs");
-               return -ENOMEM;
+               goto out;
        }
 
        WARN_ON(md->frozen_sb);
-       md->frozen_sb = freeze_bdev(bdev);
+
+       md->frozen_sb = freeze_bdev(md->frozen_bdev);
+       if (IS_ERR(md->frozen_sb)) {
+               error = PTR_ERR(md->frozen_sb);
+               goto out_bdput;
+       }
+
        /* don't bdput right now, we don't want the bdev
         * to go away while it is locked.  We'll bdput
         * in __unlock_fs
         */
        return 0;
+
+out_bdput:
+       bdput(md->frozen_bdev);
+       md->frozen_sb = NULL;
+       md->frozen_bdev = NULL;
+out:
+       clear_bit(DMF_FS_LOCKED, &md->flags);
+       return error;
 }
 
-static int __unlock_fs(struct mapped_device *md)
+static void __unlock_fs(struct mapped_device *md)
 {
-       struct block_device *bdev;
-
        if (!test_and_clear_bit(DMF_FS_LOCKED, &md->flags))
-               return 0;
+               return;
 
-       bdev = bdget_disk(md->disk, 0);
-       if (!bdev) {
-               DMWARN("bdget failed in __unlock_fs");
-               return -ENOMEM;
-       }
+       thaw_bdev(md->frozen_bdev, md->frozen_sb);
+       bdput(md->frozen_bdev);
 
-       thaw_bdev(bdev, md->frozen_sb);
        md->frozen_sb = NULL;
-       bdput(bdev);
-       bdput(bdev);
-       return 0;
+       md->frozen_bdev = NULL;
 }
 
 /*
@@ -1041,37 +1048,37 @@ int dm_suspend(struct mapped_device *md)
 {
        struct dm_table *map;
        DECLARE_WAITQUEUE(wait, current);
+       int error = -EINVAL;
 
        /* Flush I/O to the device. */
        down_read(&md->lock);
-       if (test_bit(DMF_BLOCK_IO, &md->flags)) {
-               up_read(&md->lock);
-               return -EINVAL;
-       }
+       if (test_bit(DMF_BLOCK_IO, &md->flags))
+               goto out_read_unlock;
+
+       error = __lock_fs(md);
+       if (error)
+               goto out_read_unlock;
 
        map = dm_get_table(md);
        if (map)
                dm_table_presuspend_targets(map);
-       __lock_fs(md);
 
        up_read(&md->lock);
 
        /*
-        * First we set the BLOCK_IO flag so no more ios will be
-        * mapped.
+        * First we set the BLOCK_IO flag so no more ios will be mapped.
+        *
+        * If the flag is already set we know another thread is trying to
+        * suspend as well, so we leave the fs locked for this thread.
         */
+       error = -EINVAL;
        down_write(&md->lock);
-       if (test_bit(DMF_BLOCK_IO, &md->flags)) {
-               /*
-                * If we get here we know another thread is
-                * trying to suspend as well, so we leave the fs
-                * locked for this thread.
-                */
-               up_write(&md->lock);
-               return -EINVAL;
+       if (test_and_set_bit(DMF_BLOCK_IO, &md->flags)) {
+               if (map)
+                       dm_table_put(map);
+               goto out_write_unlock;
        }
 
-       set_bit(DMF_BLOCK_IO, &md->flags);
        add_wait_queue(&md->wait, &wait);
        up_write(&md->lock);
 
@@ -1099,12 +1106,9 @@ int dm_suspend(struct mapped_device *md)
        remove_wait_queue(&md->wait, &wait);
 
        /* were we interrupted ? */
-       if (atomic_read(&md->pending)) {
-               __unlock_fs(md);
-               clear_bit(DMF_BLOCK_IO, &md->flags);
-               up_write(&md->lock);
-               return -EINTR;
-       }
+       error = -EINTR;
+       if (atomic_read(&md->pending))
+               goto out_unfreeze;
 
        set_bit(DMF_SUSPENDED, &md->flags);
 
@@ -1115,6 +1119,18 @@ int dm_suspend(struct mapped_device *md)
        up_write(&md->lock);
 
        return 0;
+
+out_unfreeze:
+       /* FIXME Undo dm_table_presuspend_targets */
+       __unlock_fs(md);
+       clear_bit(DMF_BLOCK_IO, &md->flags);
+out_write_unlock:
+       up_write(&md->lock);
+       return error;
+
+out_read_unlock:
+       up_read(&md->lock);
+       return error;
 }
 
 int dm_resume(struct mapped_device *md)
index 161e9aa872917da3cc3bb2cc4719850317e7b9e1..b1941b887f46fd6f7f5a991cbb969778ecd31c61 100644 (file)
@@ -269,9 +269,8 @@ static int linear_make_request (request_queue_t *q, struct bio *bio)
                 * split it.
                 */
                struct bio_pair *bp;
-               bp = bio_split(bio, bio_split_pool, 
-                              (bio->bi_sector + (bio->bi_size >> 9) -
-                               (tmp_dev->offset + tmp_dev->size))<<1);
+               bp = bio_split(bio, bio_split_pool,
+                              ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector);
                if (linear_make_request(q, &bp->bio1))
                        generic_make_request(&bp->bio1);
                if (linear_make_request(q, &bp->bio2))
index 97af857d8a8865a00fcdca6ea882699f852ed8b6..d899204d3743372b68ae04f92f6cefd350db99e5 100644 (file)
@@ -957,7 +957,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
 }
 
 
-struct super_type super_types[] = {
+static struct super_type super_types[] = {
        [0] = {
                .name   = "0.90.0",
                .owner  = THIS_MODULE,
@@ -2740,7 +2740,7 @@ static struct block_device_operations md_fops =
        .revalidate_disk= md_revalidate,
 };
 
-int md_thread(void * arg)
+static int md_thread(void * arg)
 {
        mdk_thread_t *thread = arg;
 
@@ -3232,7 +3232,7 @@ void md_handle_safemode(mddev_t *mddev)
 }
 
 
-DECLARE_WAIT_QUEUE_HEAD(resync_wait);
+static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
 
 #define SYNC_MARKS     10
 #define        SYNC_MARK_STEP  (3*HZ)
@@ -3575,8 +3575,8 @@ void md_check_recovery(mddev_t *mddev)
        }
 }
 
-int md_notify_reboot(struct notifier_block *this,
-                                       unsigned long code, void *x)
+static int md_notify_reboot(struct notifier_block *this,
+                           unsigned long code, void *x)
 {
        struct list_head *tmp;
        mddev_t *mddev;
@@ -3599,7 +3599,7 @@ int md_notify_reboot(struct notifier_block *this,
        return NOTIFY_DONE;
 }
 
-struct notifier_block md_notifier = {
+static struct notifier_block md_notifier = {
        .notifier_call  = md_notify_reboot,
        .next           = NULL,
        .priority       = INT_MAX, /* before any real devices */
@@ -3616,7 +3616,7 @@ static void md_geninit(void)
                p->proc_fops = &md_seq_fops;
 }
 
-int __init md_init(void)
+static int __init md_init(void)
 {
        int minor;
 
index 1891e4930dcc0799ba35fb409b07d3a2d9565bb8..2ae2d709cb1582256699b7c915436a2476129966 100644 (file)
@@ -103,7 +103,8 @@ static void multipath_end_bh_io (struct multipath_bh *mp_bh, int err)
        mempool_free(mp_bh, conf->pool);
 }
 
-int multipath_end_request(struct bio *bio, unsigned int bytes_done, int error)
+static int multipath_end_request(struct bio *bio, unsigned int bytes_done,
+                                int error)
 {
        int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
        struct multipath_bh * mp_bh = (struct multipath_bh *)(bio->bi_private);
@@ -461,10 +462,6 @@ static int multipath_run (mddev_t *mddev)
        }
        memset(conf->multipaths, 0, sizeof(struct multipath_info)*mddev->raid_disks);
 
-       mddev->queue->unplug_fn = multipath_unplug;
-
-       mddev->queue->issue_flush_fn = multipath_issue_flush;
-
        conf->working_disks = 0;
        ITERATE_RDEV(mddev,rdev,tmp) {
                disk_idx = rdev->raid_disk;
@@ -527,6 +524,10 @@ static int multipath_run (mddev_t *mddev)
         * Ok, everything is just fine now
         */
        mddev->array_size = mddev->size;
+
+       mddev->queue->unplug_fn = multipath_unplug;
+       mddev->queue->issue_flush_fn = multipath_issue_flush;
+
        return 0;
 
 out_free_conf:
index 83380b5d6593d25531a178a9aa29db17169f3a5e..1db5de52d37665e2ec1aa28c2f8678a5565fbb84 100644 (file)
@@ -1197,10 +1197,6 @@ static int run(mddev_t *mddev)
        if (!conf->r1bio_pool)
                goto out_no_mem;
 
-       mddev->queue->unplug_fn = raid1_unplug;
-
-       mddev->queue->issue_flush_fn = raid1_issue_flush;
-
        ITERATE_RDEV(mddev, rdev, tmp) {
                disk_idx = rdev->raid_disk;
                if (disk_idx >= mddev->raid_disks
@@ -1282,6 +1278,9 @@ static int run(mddev_t *mddev)
         */
        mddev->array_size = mddev->size;
 
+       mddev->queue->unplug_fn = raid1_unplug;
+       mddev->queue->issue_flush_fn = raid1_issue_flush;
+
        return 0;
 
 out_no_mem:
index e9dc2876a6269be27b0f726b83e468545be4be88..3c37be6423d75a1a576cd545d80c0d76e25a246e 100644 (file)
@@ -1639,9 +1639,6 @@ static int run(mddev_t *mddev)
                        mdname(mddev));
                goto out_free_conf;
        }
-       mddev->queue->unplug_fn = raid10_unplug;
-
-       mddev->queue->issue_flush_fn = raid10_issue_flush;
 
        ITERATE_RDEV(mddev, rdev, tmp) {
                disk_idx = rdev->raid_disk;
@@ -1713,6 +1710,9 @@ static int run(mddev_t *mddev)
        mddev->array_size = size/2;
        mddev->resync_max_sectors = size;
 
+       mddev->queue->unplug_fn = raid10_unplug;
+       mddev->queue->issue_flush_fn = raid10_issue_flush;
+
        /* Calculate max read-ahead size.
         * We need to readahead at least twice a whole stripe....
         * maybe...
index e96e2a10a9c96e53ebb63d562d951bba0258a380..3cb11ac232fa8ca9ada29fb9cdb99e15cf1ba0f2 100644 (file)
@@ -1620,9 +1620,6 @@ static int run (mddev_t *mddev)
        atomic_set(&conf->active_stripes, 0);
        atomic_set(&conf->preread_active_stripes, 0);
 
-       mddev->queue->unplug_fn = raid5_unplug_device;
-       mddev->queue->issue_flush_fn = raid5_issue_flush;
-
        PRINTK("raid5: run(%s) called.\n", mdname(mddev));
 
        ITERATE_RDEV(mddev,rdev,tmp) {
@@ -1728,6 +1725,10 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
        }
 
        /* Ok, everything is just fine now */
+
+       mddev->queue->unplug_fn = raid5_unplug_device;
+       mddev->queue->issue_flush_fn = raid5_issue_flush;
+
        mddev->array_size =  mddev->size * (mddev->raid_disks - 1);
        return 0;
 abort:
index 8a33f351e0920f3cd4d4189b86bae39b4462e593..908edd78a792b35740844a5048f507cb13f1285b 100644 (file)
@@ -1779,9 +1779,6 @@ static int run (mddev_t *mddev)
        atomic_set(&conf->active_stripes, 0);
        atomic_set(&conf->preread_active_stripes, 0);
 
-       mddev->queue->unplug_fn = raid6_unplug_device;
-       mddev->queue->issue_flush_fn = raid6_issue_flush;
-
        PRINTK("raid6: run(%s) called.\n", mdname(mddev));
 
        ITERATE_RDEV(mddev,rdev,tmp) {
@@ -1895,6 +1892,9 @@ static int run (mddev_t *mddev)
 
        /* Ok, everything is just fine now */
        mddev->array_size =  mddev->size * (mddev->raid_disks - 2);
+
+       mddev->queue->unplug_fn = raid6_unplug_device;
+       mddev->queue->issue_flush_fn = raid6_issue_flush;
        return 0;
 abort:
        if (conf) {
index 9f6c19ac1285354c60b024197bd65ac932f2ce6d..50e8b865401883331741896bea4eae2afc739f99 100644 (file)
@@ -23,9 +23,9 @@
 LIST_HEAD(saa7146_devices);
 DECLARE_MUTEX(saa7146_devices_lock);
 
-static int saa7146_num = 0;
+static int saa7146_num;
 
-unsigned int saa7146_debug = 0;
+unsigned int saa7146_debug;
 
 module_param(saa7146_debug, int, 0644);
 MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)");
index 883ec08490f417e59a36df2cc15cf37469bed49d..4983e1b1bb1d2a7ac137f56d65365544c4fbb791 100644 (file)
@@ -33,7 +33,7 @@ source "drivers/media/dvb/dibusb/Kconfig"
 source "drivers/media/dvb/cinergyT2/Kconfig"
 
 comment "Supported FlexCopII (B2C2) Adapters"
-       depends on DVB_CORE && PCI
+       depends on DVB_CORE && (PCI || USB)
 source "drivers/media/dvb/b2c2/Kconfig"
 
 comment "Supported BT878 Adapters"
index 52596907a0be59c09e32f6f52c04010fd3fddbc9..99bd675df955ba49c61041ec35e379f75e907d76 100644 (file)
@@ -1,26 +1,50 @@
-config DVB_B2C2_SKYSTAR
-       tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
-       depends on DVB_CORE && PCI
+config DVB_B2C2_FLEXCOP
+       tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
+       depends on DVB_CORE
        select DVB_STV0299
        select DVB_MT352
        select DVB_MT312
        select DVB_NXT2002
+       select DVB_STV0297
        help
-         Support for the Skystar2 PCI DVB card by Technisat, which
-         is equipped with the FlexCopII chipset by B2C2, and
-         for the B2C2/BBTI Air2PC-ATSC card.
+         Support for the digital TV receiver chip made by B2C2 Inc. included in
+         Technisats PCI cards and USB boxes.
 
          Say Y if you own such a device and want to use it.
 
-config DVB_B2C2_USB
-       tristate "B2C2/Technisat Air/Sky/Cable2PC USB"
-       depends on DVB_CORE && USB && EXPERIMENTAL
+config DVB_B2C2_FLEXCOP_PCI
+       tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI"
+       depends on DVB_B2C2_FLEXCOP && PCI
+       help
+         Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2.
+
+         Say Y if you own such a device and want to use it.
+
+config DVB_B2C2_FLEXCOP_USB
+       tristate "Technisat/B2C2 Air/Sky/Cable2PC USB"
+       depends on DVB_B2C2_FLEXCOP && USB
+       help
+         Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2,
+
+         Say Y if you own such a device and want to use it.
+
+config DVB_B2C2_FLEXCOP_DEBUG
+       bool "Enable debug for the B2C2 FlexCop drivers"
+       depends on DVB_B2C2_FLEXCOP
+       help
+         Say Y if you want to enable the module option to control debug messages
+         of all B2C2 FlexCop drivers.
+
+config DVB_B2C2_SKYSTAR
+       tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
+       depends on DVB_CORE && PCI
        select DVB_STV0299
        select DVB_MT352
+       select DVB_MT312
+       select DVB_NXT2002
        help
-         Support for the Air/Sky/Cable2PC USB DVB device by B2C2. Currently
-         the does nothing, but providing basic function for the used usb 
-         protocol.
+         Support for the Skystar2 PCI DVB card by Technisat, which
+         is equipped with the FlexCopII chipset by B2C2, and
+         for the B2C2/BBTI Air2PC-ATSC card.
 
          Say Y if you own such a device and want to use it.
-
index 9fb1247bfab88db84427d28429f3b4bc3ad469a2..7703812af34f9f9001de8fcb9820bf83350e4a53 100644 (file)
@@ -1,6 +1,14 @@
-obj-b2c2-usb = b2c2-usb-core.o b2c2-common.o
+b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
+       flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o \
+       flexcop-dma.o
+obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
+
+b2c2-flexcop-pci-objs = flexcop-pci.o
+obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
+
+b2c2-flexcop-usb-objs = flexcop-usb.o
+obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
 
 obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
-obj-$(CONFIG_DVB_B2C2_USB) + = b2c2-usb.o
 
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/b2c2/b2c2-common.c b/drivers/media/dvb/b2c2/b2c2-common.c
deleted file mode 100644 (file)
index 000d60c..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * b2c2-common.c - common methods for the B2C2/Technisat SkyStar2 PCI DVB card and
- *                 for the B2C2/Technisat Sky/Cable/AirStar USB devices
- *                 based on the FlexCopII/FlexCopIII by B2C2, Inc.
- *
- * Copyright (C) 2003  Vadim Catana, skystar@moldova.cc
- *
- * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
- * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
- *     Vincenzo Di Massa, hawk.it at tiscalinet.it
- *
- * Converted to Linux coding style
- * Misc reorganization, polishing, restyling
- *     Roberto Ragusa, r.ragusa at libero.it
- *
- * Added hardware filtering support,
- *     Niklas Peinecke, peinecke at gdv.uni-hannover.de
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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 "stv0299.h"
-#include "mt352.h"
-#include "mt312.h"
-
-static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-
-       if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
-       else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
-       else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
-       else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
-       else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
-       else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
-
-       stv0299_writereg (fe, 0x13, aclk);
-       stv0299_writereg (fe, 0x14, bclk);
-       stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
-       stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
-
-       return 0;
-}
-
-static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
-       u8 buf[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
-//     struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-       div = params->frequency / 125;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0x84;  // 0xC4
-       buf[3] = 0x08;
-
-       if (params->frequency < 1500000) buf[3] |= 0x10;
-
-//     if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static u8 samsung_tbmu24112_inittab[] = {
-            0x01, 0x15,
-            0x02, 0x30,
-            0x03, 0x00,
-            0x04, 0x7D,
-            0x05, 0x35,
-            0x06, 0x02,
-            0x07, 0x00,
-            0x08, 0xC3,
-            0x0C, 0x00,
-            0x0D, 0x81,
-            0x0E, 0x23,
-            0x0F, 0x12,
-            0x10, 0x7E,
-            0x11, 0x84,
-            0x12, 0xB9,
-            0x13, 0x88,
-            0x14, 0x89,
-            0x15, 0xC9,
-            0x16, 0x00,
-            0x17, 0x5C,
-            0x18, 0x00,
-            0x19, 0x00,
-            0x1A, 0x00,
-            0x1C, 0x00,
-            0x1D, 0x00,
-            0x1E, 0x00,
-            0x1F, 0x3A,
-            0x20, 0x2E,
-            0x21, 0x80,
-            0x22, 0xFF,
-            0x23, 0xC1,
-            0x28, 0x00,
-            0x29, 0x1E,
-            0x2A, 0x14,
-            0x2B, 0x0F,
-            0x2C, 0x09,
-            0x2D, 0x05,
-            0x31, 0x1F,
-            0x32, 0x19,
-            0x33, 0xFE,
-            0x34, 0x93,
-            0xff, 0xff,
-};
-
-static struct stv0299_config samsung_tbmu24112_config = {
-       .demod_address = 0x68,
-       .inittab = samsung_tbmu24112_inittab,
-       .mclk = 88000000UL,
-       .invert = 0,
-       .enhanced_tuning = 0,
-       .skip_reinit = 0,
-       .lock_output = STV0229_LOCKOUTPUT_LK,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
-       .pll_set = samsung_tbmu24112_pll_set,
-};
-
-
-
-
-
-static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
-{
-       static u8 mt352_clock_config [] = { 0x89, 0x10, 0x2d };
-       static u8 mt352_reset [] = { 0x50, 0x80 };
-       static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
-       static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
-       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
-       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
-       udelay(2000);
-       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
-       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
-
-       mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
-       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
-
-       return 0;
-}
-
-static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
-{
-       u32 div;
-       unsigned char bs = 0;
-
-       #define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
-       div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-
-       if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
-       if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
-       if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
-
-       pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
-       pllbuf[1] = div >> 8;
-       pllbuf[2] = div & 0xff;
-       pllbuf[3] = 0xcc;
-       pllbuf[4] = bs;
-
-       return 0;
-}
-
-static struct mt352_config samsung_tdtc9251dh0_config = {
-
-       .demod_address = 0x0f,
-       .demod_init = samsung_tdtc9251dh0_demod_init,
-       .pll_set = samsung_tdtc9251dh0_pll_set,
-};
-
-static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
-       u8 buf[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
-//     struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-       div = (params->frequency + (125/2)) / 125;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = (div >> 0) & 0xff;
-       buf[2] = 0x84 | ((div >> 10) & 0x60);
-       buf[3] = 0x80;
-
-       if (params->frequency < 1550000)
-               buf[3] |= 0x02;
-
-       //if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static struct mt312_config skystar23_samsung_tbdu18132_config = {
-
-       .demod_address = 0x0e,
-       .pll_set = skystar23_samsung_tbdu18132_pll_set,
-};
diff --git a/drivers/media/dvb/b2c2/b2c2-usb-core.c b/drivers/media/dvb/b2c2/b2c2-usb-core.c
deleted file mode 100644 (file)
index 9306da0..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * Copyright (C) 2004 Patrick Boettcher <patrick.boettcher@desy.de>,
- *                    Luca Bertagnolio <>,
- *
- * based on information provided by John Jurrius from BBTI, 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, version 2.
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/moduleparam.h>
-#include <linux/pci.h>
-#include <linux/version.h>
-
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_filter.h"
-#include "dvb_net.h"
-#include "dvb_frontend.h"
-
-/* debug */
-#define dprintk(level,args...) \
-           do { if ((debug & level)) { printk(args); } } while (0)
-#define debug_dump(b,l) if (debug) {\
-       int i; deb_xfer("%s: %d > ",__FUNCTION__,l); \
-       for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
-       deb_xfer("\n");\
-}
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4 (or-able)).");
-
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_ts(args...)   dprintk(0x02,args)
-#define deb_ctrl(args...) dprintk(0x04,args)
-
-/* Version information */
-#define DRIVER_VERSION "0.0"
-#define DRIVER_DESC "Driver for B2C2/Technisat Air/Cable/Sky-2-PC USB devices"
-#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
-
-/* transfer parameters */
-#define B2C2_USB_FRAMES_PER_ISO                4
-#define B2C2_USB_NUM_ISO_URB           4    /* TODO check out a good value */
-
-#define B2C2_USB_CTRL_PIPE_IN          usb_rcvctrlpipe(b2c2->udev,0)
-#define B2C2_USB_CTRL_PIPE_OUT         usb_sndctrlpipe(b2c2->udev,0)
-#define B2C2_USB_DATA_PIPE                     usb_rcvisocpipe(b2c2->udev,0x81)
-
-struct usb_b2c2_usb {
-       struct usb_device *udev;
-       struct usb_interface *uintf;
-
-       u8 *iso_buffer;
-       int buffer_size;
-       dma_addr_t iso_dma_handle;
-       struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
-};
-
-
-/*
- * USB
- * 10 90 34 12 78 56 04 00
- * usb_control_msg(udev, usb_sndctrlpipe(udev,0),
- * 0x90,
- * 0x10,
- * 0x1234,
- * 0x5678,
- * buf,
- * 4,
- * 5*HZ);
- *
- * extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
- * __u8 request,
- * __u8 requesttype,
- * __u16 value,
- * __u16 index,
- * void *data,
- * __u16 size,
- * int timeout);
- *
- */
-
-/* request types */
-typedef enum {
-
-/* something is wrong with this part
-       RTYPE_READ_DW         = (1 << 6),
-       RTYPE_WRITE_DW_1      = (3 << 6),
-       RTYPE_READ_V8_MEMORY  = (6 << 6),
-       RTYPE_WRITE_V8_MEMORY = (7 << 6),
-       RTYPE_WRITE_V8_FLASH  = (8 << 6),
-       RTYPE_GENERIC         = (9 << 6),
-*/
-       RTYPE_READ_DW = (3 << 6),
-       RTYPE_WRITE_DW_1 = (1 << 6),
-       
-       RTYPE_READ_V8_MEMORY  = (6 << 6),
-       RTYPE_WRITE_V8_MEMORY = (7 << 6),
-       RTYPE_WRITE_V8_FLASH  = (8 << 6),
-       RTYPE_GENERIC         = (9 << 6),
-} b2c2_usb_request_type_t;
-
-/* request */
-typedef enum {
-       B2C2_USB_WRITE_V8_MEM = 0x04,
-       B2C2_USB_READ_V8_MEM  = 0x05,
-       B2C2_USB_READ_REG     = 0x08,
-       B2C2_USB_WRITE_REG    = 0x0A,
-/*     B2C2_USB_WRITEREGLO   = 0x0A, */
-       B2C2_USB_WRITEREGHI   = 0x0B,
-       B2C2_USB_FLASH_BLOCK  = 0x10,
-       B2C2_USB_I2C_REQUEST  = 0x11,
-       B2C2_USB_UTILITY      = 0x12,
-} b2c2_usb_request_t;
-
-/* function definition for I2C_REQUEST */
-typedef enum {
-       USB_FUNC_I2C_WRITE       = 0x01,
-       USB_FUNC_I2C_MULTIWRITE  = 0x02,
-       USB_FUNC_I2C_READ        = 0x03,
-       USB_FUNC_I2C_REPEATWRITE = 0x04,
-       USB_FUNC_GET_DESCRIPTOR  = 0x05,
-       USB_FUNC_I2C_REPEATREAD  = 0x06,
-/* DKT 020208 - add this to support special case of DiSEqC */
-       USB_FUNC_I2C_CHECKWRITE  = 0x07,
-       USB_FUNC_I2C_CHECKRESULT = 0x08,
-} b2c2_usb_i2c_function_t;
-
-/*
- * function definition for UTILITY request 0x12
- * DKT 020304 - new utility function
- */
-typedef enum {
-       UTILITY_SET_FILTER          = 0x01,
-       UTILITY_DATA_ENABLE         = 0x02,
-       UTILITY_FLEX_MULTIWRITE     = 0x03,
-       UTILITY_SET_BUFFER_SIZE     = 0x04,
-       UTILITY_FLEX_OPERATOR       = 0x05,
-       UTILITY_FLEX_RESET300_START = 0x06,
-       UTILITY_FLEX_RESET300_STOP  = 0x07,
-       UTILITY_FLEX_RESET300       = 0x08,
-       UTILITY_SET_ISO_SIZE        = 0x09,
-       UTILITY_DATA_RESET          = 0x0A,
-       UTILITY_GET_DATA_STATUS     = 0x10,
-       UTILITY_GET_V8_REG          = 0x11,
-/* DKT 020326 - add function for v1.14 */
-       UTILITY_SRAM_WRITE          = 0x12,
-       UTILITY_SRAM_READ           = 0x13,
-       UTILITY_SRAM_TESTFILL       = 0x14,
-       UTILITY_SRAM_TESTSET        = 0x15,
-       UTILITY_SRAM_TESTVERIFY     = 0x16,
-} b2c2_usb_utility_function_t;
-
-#define B2C2_WAIT_FOR_OPERATION_RW  1  // 1 s
-#define B2C2_WAIT_FOR_OPERATION_RDW 3  // 3 s
-#define B2C2_WAIT_FOR_OPERATION_WDW 1  // 1 s
-
-#define B2C2_WAIT_FOR_OPERATION_V8READ   3  // 3 s
-#define B2C2_WAIT_FOR_OPERATION_V8WRITE  3  // 3 s
-#define B2C2_WAIT_FOR_OPERATION_V8FLASH  3  // 3 s
-
-/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
- * in the IBI address, to make the V8 code simpler.
- * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
- *                  in general: 0000 0HHH 000L LL00
- * IBI ADDRESS FORMAT:                    RHHH BLLL
- *
- * where R is the read(1)/write(0) bit, B is the busy bit
- * and HHH and LLL are the two sets of three bits from the PCI address.
- */
-#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
-#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
-
-/*
- * DKT 020228 - forget about this VENDOR_BUFFER_SIZE, read and write register
- * deal with DWORD or 4 bytes, that should be should from now on
- */
-static u32 b2c2_usb_read_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI)
-{
-       u32 val;
-       u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | 0x0080;
-       int len = usb_control_msg(b2c2->udev,
-                       B2C2_USB_CTRL_PIPE_IN,
-                       B2C2_USB_READ_REG,
-                       RTYPE_READ_DW,
-                       wAddress,
-                       0,
-                       &val,
-                       sizeof(u32),
-                       B2C2_WAIT_FOR_OPERATION_RDW * 1000);
-
-       if (len != sizeof(u32)) {
-               err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
-               return -EIO;
-       } else
-               return val;
-}
-
-/*
- * DKT 020228 - from now on, we don't support anything older than firm 1.00
- * I eliminated the write register as a 2 trip of writing hi word and lo word
- * and force this to write only 4 bytes at a time.
- * NOTE: this should work with all the firmware from 1.00 and newer
- */
-static int b2c2_usb_write_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI, u32 val)
-{
-       u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI);
-       int len = usb_control_msg(b2c2->udev,
-                       B2C2_USB_CTRL_PIPE_OUT,
-                       B2C2_USB_WRITE_REG,
-                       RTYPE_WRITE_DW_1,
-                       wAddress,
-                       0,
-                       &val,
-                       sizeof(u32),
-                       B2C2_WAIT_FOR_OPERATION_RDW * 1000);
-
-       if (len != sizeof(u32)) {
-               err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
-               return -EIO;
-       } else
-               return 0;
-}
-
-/*
- * DKT 010817 - add support for V8 memory read/write and flash update
- */
-static int b2c2_usb_v8_memory_req(struct usb_b2c2_usb *b2c2,
-               b2c2_usb_request_t req, u8 page, u16 wAddress,
-               u16 buflen, u8 *pbBuffer)
-{
-       u8 dwRequestType;
-       u16 wIndex;
-       int nWaitTime,pipe,len;
-
-       wIndex = page << 8;
-
-       switch (req) {
-               case B2C2_USB_READ_V8_MEM:
-                       nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
-                       dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
-                       pipe = B2C2_USB_CTRL_PIPE_IN;
-               break;
-               case B2C2_USB_WRITE_V8_MEM:
-                       wIndex |= pbBuffer[0];
-                       nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
-                       dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
-                       pipe = B2C2_USB_CTRL_PIPE_OUT;
-               break;
-               case B2C2_USB_FLASH_BLOCK:
-                       nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
-                       dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
-                       pipe = B2C2_USB_CTRL_PIPE_OUT;
-               break;
-               default:
-                       deb_info("unsupported request for v8_mem_req %x.\n",req);
-               return -EINVAL;
-       }
-       len = usb_control_msg(b2c2->udev,pipe,
-                       req,
-                       dwRequestType,
-                       wAddress,
-                       wIndex,
-                       pbBuffer,
-                       buflen,
-                       nWaitTime * 1000);
-       return len == buflen ? 0 : -EIO;
-}
-
-static int b2c2_usb_i2c_req(struct usb_b2c2_usb *b2c2,
-               b2c2_usb_request_t req, b2c2_usb_i2c_function_t func,
-               u8 port, u8 chipaddr, u8 addr, u8 buflen, u8 *buf)
-{
-       u16 wValue, wIndex;
-       int nWaitTime,pipe,len;
-       u8 dwRequestType;
-
-       switch (func) {
-               case USB_FUNC_I2C_WRITE:
-               case USB_FUNC_I2C_MULTIWRITE:
-               case USB_FUNC_I2C_REPEATWRITE:
-               /* DKT 020208 - add this to support special case of DiSEqC */
-               case USB_FUNC_I2C_CHECKWRITE:
-                       pipe = B2C2_USB_CTRL_PIPE_OUT;
-                       nWaitTime = 2;
-                       dwRequestType = (u8) RTYPE_GENERIC;
-               break;
-               case USB_FUNC_I2C_READ:
-               case USB_FUNC_I2C_REPEATREAD:
-                       pipe = B2C2_USB_CTRL_PIPE_IN;
-                       nWaitTime = 2;
-                       dwRequestType = (u8) RTYPE_GENERIC;
-               break;
-               default:
-                       deb_info("unsupported function for i2c_req %x\n",func);
-                       return -EINVAL;
-       }
-       wValue = (func << 8 ) | port;
-       wIndex = (chipaddr << 8 ) | addr;
-
-       len = usb_control_msg(b2c2->udev,pipe,
-                       req,
-                       dwRequestType,
-                       addr,
-                       wIndex,
-                       buf,
-                       buflen,
-                       nWaitTime * 1000);
-       return len == buflen ? 0 : -EIO;
-}
-
-int static b2c2_usb_utility_req(struct usb_b2c2_usb *b2c2, int set,
-               b2c2_usb_utility_function_t func, u8 extra, u16 wIndex,
-               u16 buflen, u8 *pvBuffer)
-{
-       u16 wValue;
-       int nWaitTime = 2,
-               pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
-               len;
-
-       wValue = (func << 8) | extra;
-
-       len = usb_control_msg(b2c2->udev,pipe,
-                       B2C2_USB_UTILITY,
-                       (u8) RTYPE_GENERIC,
-                       wValue,
-                       wIndex,
-                       pvBuffer,
-                       buflen,
-                       nWaitTime * 1000);
-       return len == buflen ? 0 : -EIO;
-}
-
-
-
-static void b2c2_dumpfourreg(struct usb_b2c2_usb *b2c2, u16 offs)
-{
-       u32 r0,r1,r2,r3;
-       r0 = r1 = r2 = r3 = 0;
-       r0 = b2c2_usb_read_dw(b2c2,offs);
-       r1 = b2c2_usb_read_dw(b2c2,offs + 0x04);
-       r2 = b2c2_usb_read_dw(b2c2,offs + 0x08);
-       r3 = b2c2_usb_read_dw(b2c2,offs + 0x0c);
-       deb_ctrl("dump: offset: %03x, %08x, %08x, %08x, %08x\n",offs,r0,r1,r2,r3);
-}
-
-static void b2c2_urb_complete(struct urb *urb, struct pt_regs *ptregs)
-{
-       struct usb_b2c2_usb *b2c2 = urb->context;
-       deb_ts("urb completed, bufsize: %d\n",urb->transfer_buffer_length);
-
-//     urb_submit_urb(urb,GFP_ATOMIC); enable for real action
-}
-
-static void b2c2_exit_usb(struct usb_b2c2_usb *b2c2)
-{
-       int i;
-       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
-               if (b2c2->iso_urb[i] != NULL) { /* not sure about unlink_urb and iso-urbs TODO */
-                       deb_info("unlinking/killing urb no. %d\n",i);
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7)
-                       usb_unlink_urb(b2c2->iso_urb[i]);
-#else
-                       usb_kill_urb(b2c2->iso_urb[i]);
-#endif
-                       usb_free_urb(b2c2->iso_urb[i]);
-               }
-
-       if (b2c2->iso_buffer != NULL)
-               pci_free_consistent(NULL,b2c2->buffer_size, b2c2->iso_buffer, b2c2->iso_dma_handle);
-
-}
-
-static int b2c2_init_usb(struct usb_b2c2_usb *b2c2)
-{
-       u16 frame_size = le16_to_cpu(b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
-       int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
-       int buffer_offset = 0;
-
-       deb_info("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
-                       B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
-
-       b2c2->iso_buffer = pci_alloc_consistent(NULL,bufsize,&b2c2->iso_dma_handle);
-       if (b2c2->iso_buffer == NULL)
-               return -ENOMEM;
-       memset(b2c2->iso_buffer, 0, bufsize);
-       b2c2->buffer_size = bufsize;
-
-       /* creating iso urbs */
-       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
-               if (!(b2c2->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
-                       ret = -ENOMEM;
-                       goto urb_error;
-               }
-       /* initialising and submitting iso urbs */
-       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
-               int frame_offset = 0;
-               struct urb *urb = b2c2->iso_urb[i];
-               deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
-
-               urb->dev = b2c2->udev;
-               urb->context = b2c2;
-               urb->complete = b2c2_urb_complete;
-               urb->pipe = B2C2_USB_DATA_PIPE;
-               urb->transfer_flags = URB_ISO_ASAP;
-               urb->interval = 1;
-               urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO;
-               urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO;
-               urb->transfer_buffer = b2c2->iso_buffer + buffer_offset;
-
-               buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
-               for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
-                       deb_info("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
-                       urb->iso_frame_desc[j].offset = frame_offset;
-                       urb->iso_frame_desc[j].length = frame_size;
-                       frame_offset += frame_size;
-               }
-
-               if ((ret = usb_submit_urb(b2c2->iso_urb[i],GFP_ATOMIC))) {
-                       err("submitting urb %d failed with %d.",i,ret);
-                       goto urb_error;
-               }
-               deb_info("submitted urb no. %d.\n",i);
-       }
-
-       ret = 0;
-       goto success;
-urb_error:
-       b2c2_exit_usb(b2c2);
-success:
-       return ret;
-}
-
-static int b2c2_usb_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct usb_b2c2_usb *b2c2 = NULL;
-       int ret;
-
-       b2c2 = kmalloc(sizeof(struct usb_b2c2_usb),GFP_KERNEL);
-       if (b2c2 == NULL) {
-               err("no memory");
-               return -ENOMEM;
-       }
-       b2c2->udev = udev;
-       b2c2->uintf = intf;
-
-       /* use the alternate setting with the larges buffer */
-       usb_set_interface(udev,0,1);
-
-       if ((ret = b2c2_init_usb(b2c2)))
-               goto usb_init_error;
-
-       usb_set_intfdata(intf,b2c2);
-
-       switch (udev->speed) {
-               case USB_SPEED_LOW:
-                       err("cannot handle USB speed because it is to sLOW.");
-                       break;
-               case USB_SPEED_FULL:
-                       info("running at FULL speed.");
-                       break;
-               case USB_SPEED_HIGH:
-                       info("running at HIGH speed.");
-                       break;
-               case USB_SPEED_UNKNOWN: /* fall through */
-               default:
-                       err("cannot handle USB speed because it is unkown.");
-               break;
-       }
-
-       b2c2_dumpfourreg(b2c2,0x200);
-       b2c2_dumpfourreg(b2c2,0x300);
-       b2c2_dumpfourreg(b2c2,0x400);
-       b2c2_dumpfourreg(b2c2,0x700);
-
-
-       if (ret == 0)
-               info("%s successfully initialized and connected.",DRIVER_DESC);
-       else
-               info("%s error while loading driver (%d)",DRIVER_DESC,ret);
-
-       ret = 0;
-       goto success;
-
-usb_init_error:
-       kfree(b2c2);
-success:
-       return ret;
-}
-
-static void b2c2_usb_disconnect(struct usb_interface *intf)
-{
-       struct usb_b2c2_usb *b2c2 = usb_get_intfdata(intf);
-       usb_set_intfdata(intf,NULL);
-       if (b2c2 != NULL) {
-               b2c2_exit_usb(b2c2);
-               kfree(b2c2);
-       }
-       info("%s successfully deinitialized and disconnected.",DRIVER_DESC);
-
-}
-
-static struct usb_device_id b2c2_usb_table [] = {
-           { USB_DEVICE(0x0af7, 0x0101) }
-};
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver b2c2_usb_driver = {
-       .owner          = THIS_MODULE,
-       .name           = "dvb_b2c2_usb",
-       .probe          = b2c2_usb_probe,
-       .disconnect = b2c2_usb_disconnect,
-       .id_table       = b2c2_usb_table,
-};
-
-/* module stuff */
-static int __init b2c2_usb_init(void)
-{
-       int result;
-       if ((result = usb_register(&b2c2_usb_driver))) {
-               err("usb_register failed. Error number %d",result);
-               return result;
-       }
-
-       return 0;
-}
-
-static void __exit b2c2_usb_exit(void)
-{
-       /* deregister this driver from the USB subsystem */
-       usb_deregister(&b2c2_usb_driver);
-}
-
-module_init (b2c2_usb_init);
-module_exit (b2c2_usb_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(usb, b2c2_usb_table);
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
new file mode 100644 (file)
index 0000000..773d158
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-common.h - common header file for device-specific source files also.
+ *
+ * see flexcop.c for copyright information.
+ */
+#ifndef __FLEXCOP_COMMON_H__
+#define __FLEXCOP_COMMON_H__
+
+#include <linux/config.h>
+#include <linux/pci.h>
+
+#include "flexcop-reg.h"
+
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_filter.h"
+#include "dvb_net.h"
+#include "dvb_frontend.h"
+
+#define FC_MAX_FEED 256
+
+#ifndef FC_LOG_PREFIX
+#warning please define a log prefix for your file, using a default one
+#define FC_LOG_PREFIX "b2c2-undef"
+#endif
+
+/* Steal from usb.h */
+#undef err
+#define err(format,  arg...) printk(KERN_ERR     FC_LOG_PREFIX ": " format "\n" , ## arg)
+#undef info
+#define info(format, arg...) printk(KERN_INFO    FC_LOG_PREFIX ": " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
+
+struct flexcop_dma {
+       struct pci_dev *pdev;
+
+       u8 *cpu_addr0;
+       dma_addr_t dma_addr0;
+       u8 *cpu_addr1;
+       dma_addr_t dma_addr1;
+       u32 size; /* size of each address in bytes */
+};
+
+/* Control structure for data definitions that are common to
+ * the B2C2-based PCI and USB devices.
+ */
+struct flexcop_device {
+       /* general */
+       struct device *dev; /* for firmware_class */
+
+#define FC_STATE_DVB_INIT 0x01
+#define FC_STATE_I2C_INIT 0x02
+#define FC_STATE_FE_INIT  0x04
+       int init_state;
+
+       /* device information */
+       int has_32_hw_pid_filter;
+       flexcop_revision_t rev;
+       flexcop_device_type_t dev_type;
+       flexcop_bus_t bus_type;
+
+       /* dvb stuff */
+       struct dvb_adapter dvb_adapter;
+       struct dvb_frontend *fe;
+       struct dvb_net dvbnet;
+       struct dvb_demux demux;
+       struct dmxdev dmxdev;
+       struct dmx_frontend hw_frontend;
+       struct dmx_frontend mem_frontend;
+       int (*fe_sleep) (struct dvb_frontend *);
+
+       struct i2c_adapter i2c_adap;
+       struct semaphore i2c_sem;
+
+       struct module *owner;
+
+       /* options and status */
+       int extra_feedcount;
+       int feedcount;
+       int pid_filtering;
+       int fullts_streaming_state;
+
+       /* bus specific callbacks */
+       flexcop_ibi_value (*read_ibi_reg)  (struct flexcop_device *, flexcop_ibi_register);
+       int               (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value);
+
+
+       int (*i2c_request) (struct flexcop_device*, flexcop_access_op_t, flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
+       int (*stream_control) (struct flexcop_device*, int);
+
+       int (*get_mac_addr) (struct flexcop_device *fc, int extended);
+
+       void *bus_specific;
+};
+
+/* exported prototypes */
+
+/* from flexcop.c */
+void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len);
+void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
+
+struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
+void flexcop_device_kfree(struct flexcop_device*);
+
+int  flexcop_device_initialize(struct flexcop_device*);
+void flexcop_device_exit(struct flexcop_device *fc);
+
+/* from flexcop-dma.c */
+int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size);
+void flexcop_dma_free(struct flexcop_dma *dma);
+
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
+int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
+int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
+int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index);
+int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
+int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets);
+
+/* from flexcop-eeprom.c */
+/* the PCI part uses this call to get the MAC address, the USB part has its own */
+int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended);
+
+/* from flexcop-i2c.c */
+/* the PCI part uses this a i2c_request callback, whereas the usb part has its own
+ * one. We have it in flexcop-i2c.c, because it is going via the actual
+ * I2C-channel of the flexcop.
+ */
+int flexcop_i2c_request(struct flexcop_device*, flexcop_access_op_t,
+                       flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
+
+/* from flexcop-sram.c */
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target);
+void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
+void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill);
+
+/* global prototypes for the flexcop-chip */
+/* from flexcop-fe-tuner.c */
+int flexcop_frontend_init(struct flexcop_device *card);
+void flexcop_frontend_exit(struct flexcop_device *fc);
+
+/* from flexcop-i2c.c */
+int flexcop_i2c_init(struct flexcop_device *fc);
+void flexcop_i2c_exit(struct flexcop_device *fc);
+
+/* from flexcop-sram.c */
+int flexcop_sram_init(struct flexcop_device *fc);
+
+/* from flexcop-misc.c */
+void flexcop_determine_revision(struct flexcop_device *fc);
+void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix);
+
+/* from flexcop-hw-filter.c */
+int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);
+void flexcop_hw_filter_init(struct flexcop_device *fc);
+
+void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
+
+void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]);
+void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff);
+
+#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
new file mode 100644 (file)
index 0000000..8d27060
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-dma.c - methods for configuring and controlling the DMA of the FlexCop.
+ *
+ * see flexcop.c for copyright information.
+ */
+#include "flexcop.h"
+
+int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size)
+{
+       u8 *tcpu;
+       dma_addr_t tdma;
+
+       if (size % 2) {
+               err("dma buffersize has to be even.");
+               return -EINVAL;
+       }
+
+       if ((tcpu = pci_alloc_consistent(pdev, size, &tdma)) != NULL) {
+               dma->pdev = pdev;
+               dma->cpu_addr0 = tcpu;
+               dma->dma_addr0 = tdma;
+               dma->cpu_addr1 = tcpu + size/2;
+               dma->dma_addr1 = tdma + size/2;
+               dma->size = size/2;
+               return 0;
+       }
+       return -ENOMEM;
+}
+EXPORT_SYMBOL(flexcop_dma_allocate);
+
+void flexcop_dma_free(struct flexcop_dma *dma)
+{
+       pci_free_consistent(dma->pdev, dma->size*2,dma->cpu_addr0, dma->dma_addr0);
+       memset(dma,0,sizeof(struct flexcop_dma));
+}
+EXPORT_SYMBOL(flexcop_dma_free);
+
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+{
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
+
+       if (no & FC_DMA_1)
+               v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
+
+       if (no & FC_DMA_2)
+               v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
+
+       fc->write_ibi_reg(fc,ctrl_208,v);
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
+
+int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+{
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
+
+       if (no & FC_DMA_1)
+               v.ctrl_208.DMA1_IRQ_Enable_sig = onoff;
+
+       if (no & FC_DMA_2)
+               v.ctrl_208.DMA2_IRQ_Enable_sig = onoff;
+
+       fc->write_ibi_reg(fc,ctrl_208,v);
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_control_size_irq);
+
+int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+{
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
+
+       if (no & FC_DMA_1)
+               v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
+
+       if (no & FC_DMA_2)
+               v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
+
+       fc->write_ibi_reg(fc,ctrl_208,v);
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
+
+int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index)
+{
+
+       flexcop_ibi_value v0x0,v0x4,v0xc;
+       v0x0.raw = v0x4.raw = v0xc.raw = 0;
+
+       v0x0.dma_0x0.dma_address0        = dma->dma_addr0 >> 2;
+       v0xc.dma_0xc.dma_address1        = dma->dma_addr1 >> 2;
+       v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
+
+       if (index & FC_DMA_SUBADDR_0)
+               v0x0.dma_0x0.dma_0start = 1;
+
+       if (index & FC_DMA_SUBADDR_1)
+               v0xc.dma_0xc.dma_1start = 1;
+
+       if (dma_idx & FC_DMA_1) {
+               fc->write_ibi_reg(fc,dma1_000,v0x0);
+               fc->write_ibi_reg(fc,dma1_004,v0x4);
+               fc->write_ibi_reg(fc,dma1_00c,v0xc);
+       } else { /* (dma_idx & FC_DMA_2) */
+               fc->write_ibi_reg(fc,dma2_010,v0x0);
+               fc->write_ibi_reg(fc,dma2_014,v0x4);
+               fc->write_ibi_reg(fc,dma2_01c,v0xc);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_config);
+
+static int flexcop_dma_remap(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, int onoff)
+{
+       flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+       v.dma_0xc.remap_enable = onoff;
+       fc->write_ibi_reg(fc,r,v);
+       return 0;
+}
+
+/* 1 cycles = 1.97 msec */
+int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles)
+{
+       flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+
+       flexcop_dma_remap(fc,dma_idx,0);
+
+       v.dma_0x4_write.dmatimer = cycles >> 1;
+       fc->write_ibi_reg(fc,r,v);
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_config_timer);
+
+int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets)
+{
+       flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+
+       flexcop_dma_remap(fc,dma_idx,1);
+
+       v.dma_0x4_remap.DMA_maxpackets = packets;
+       fc->write_ibi_reg(fc,r,v);
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_config_packet_count);
diff --git a/drivers/media/dvb/b2c2/flexcop-eeprom.c b/drivers/media/dvb/b2c2/flexcop-eeprom.c
new file mode 100644 (file)
index 0000000..bbcf070
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used)
+ *
+ * see flexcop.c for copyright information.
+ */
+#include "flexcop.h"
+
+#if 0
+/*EEPROM (Skystar2 has one "24LC08B" chip on board) */
+static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
+{
+       return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
+}
+
+static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
+{
+       int i;
+
+       for (i = 0; i < retries; i++) {
+               if (eeprom_write(adapter, addr, wbuf, len) == len) {
+                       if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
+                               return 1;
+               }
+       }
+
+       return 0;
+}
+
+/* These functions could be used to unlock SkyStar2 cards. */
+
+static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
+{
+       u8 rbuf[20];
+       u8 wbuf[20];
+
+       if (len != 16)
+               return 0;
+
+       memcpy(wbuf, key, len);
+
+       wbuf[16] = 0;
+       wbuf[17] = 0;
+       wbuf[18] = 0;
+       wbuf[19] = calc_lrc(wbuf, 19);
+
+       return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
+}
+
+static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
+{
+       u8 buf[20];
+
+       if (len != 16)
+               return 0;
+
+       if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
+               return 0;
+
+       memcpy(key, buf, len);
+
+       return 1;
+}
+
+static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
+{
+       u8 tmp[8];
+
+       if (type != 0) {
+               tmp[0] = mac[0];
+               tmp[1] = mac[1];
+               tmp[2] = mac[2];
+               tmp[3] = mac[5];
+               tmp[4] = mac[6];
+               tmp[5] = mac[7];
+
+       } else {
+
+               tmp[0] = mac[0];
+               tmp[1] = mac[1];
+               tmp[2] = mac[2];
+               tmp[3] = mac[3];
+               tmp[4] = mac[4];
+               tmp[5] = mac[5];
+       }
+
+       tmp[6] = 0;
+       tmp[7] = calc_lrc(tmp, 7);
+
+       if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
+               return 1;
+
+       return 0;
+}
+
+static int flexcop_eeprom_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len)
+{
+       return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
+}
+
+#endif
+
+static u8 calc_lrc(u8 *buf, int len)
+{
+       int i;
+       u8 sum = 0;
+       for (i = 0; i < len; i++)
+               sum = sum ^ buf[i];
+       return sum;
+}
+
+static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
+{
+       int i,ret = 0;
+       u8 chipaddr =  0x50 | ((addr >> 8) & 3);
+       for (i = 0; i < retries; i++)
+               if ((ret = fc->i2c_request(fc,op,FC_I2C_PORT_EEPROM,chipaddr,addr & 0xff,buf,len)) == 0)
+                       break;
+       return ret;
+}
+
+static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries)
+{
+       int ret = flexcop_eeprom_request(fc,FC_READ,addr,buf,len,retries);
+       if (ret == 0)
+               if (calc_lrc(buf, len - 1) != buf[len - 1])
+                       ret = -EINVAL;
+       return ret;
+}
+
+/* JJ's comment about extended == 1: it is not presently used anywhere but was
+ * added to the low-level functions for possible support of EUI64
+ */
+int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
+{
+       u8 buf[8];
+       int ret = 0;
+
+       if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
+               if (extended != 0) {
+                       err("TODO: extended (EUI64) MAC addresses aren't completely supported yet");
+                       ret = -EINVAL;
+/*                     memcpy(fc->dvb_adapter.proposed_mac,buf,3);
+                       mac[3] = 0xfe;
+                       mac[4] = 0xff;
+                       memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */
+               } else
+                       memcpy(fc->dvb_adapter.proposed_mac,buf,6);
+       }
+       return ret;
+}
+EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr);
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
new file mode 100644 (file)
index 0000000..71be400
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-fe-tuner.c - methods for attaching a frontend and controlling DiSEqC.
+ *
+ * see flexcop.c for copyright information.
+ */
+#include "flexcop.h"
+
+#include "stv0299.h"
+#include "mt352.h"
+#include "nxt2002.h"
+#include "stv0297.h"
+#include "mt312.h"
+
+/* lnb control */
+
+static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct flexcop_device *fc = fe->dvb->priv;
+       flexcop_ibi_value v;
+       deb_tuner("polarity/voltage = %u\n", voltage);
+
+       v = fc->read_ibi_reg(fc, misc_204);
+       switch (voltage) {
+               case SEC_VOLTAGE_OFF:
+                       v.misc_204.ACPI1_sig = 1;
+                       break;
+               case SEC_VOLTAGE_13:
+                       v.misc_204.ACPI1_sig = 0;
+                       v.misc_204.LNB_L_H_sig = 0;
+                       break;
+               case SEC_VOLTAGE_18:
+                       v.misc_204.ACPI1_sig = 0;
+                       v.misc_204.LNB_L_H_sig = 1;
+                       break;
+               default:
+                       err("unknown SEC_VOLTAGE value");
+                       return -EINVAL;
+       }
+       return fc->write_ibi_reg(fc, misc_204, v);
+}
+
+static int flexcop_sleep(struct dvb_frontend* fe)
+{
+       struct flexcop_device *fc = fe->dvb->priv;
+/*     flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */
+
+       if (fc->fe_sleep)
+               return fc->fe_sleep(fe);
+
+/*     v.misc_204.ACPI3_sig = 1;
+       fc->write_ibi_reg(fc,misc_204,v);*/
+
+       return 0;
+}
+
+static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
+       struct flexcop_device *fc = fe->dvb->priv;
+       flexcop_ibi_value v;
+       u16 ax;
+       v.raw = 0;
+
+       deb_tuner("tone = %u\n",tone);
+
+       switch (tone) {
+               case SEC_TONE_ON:
+                       ax = 0x01ff;
+                       break;
+               case SEC_TONE_OFF:
+                       ax = 0;
+                       break;
+               default:
+                       err("unknown SEC_TONE value");
+                       return -EINVAL;
+       }
+
+       v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
+
+       v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
+       v.lnb_switch_freq_200.LNB_CTLLowCount_sig  = ax == 0 ? 0x1ff : ax;
+
+       return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
+}
+
+static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
+{
+       flexcop_set_tone(fe, SEC_TONE_ON);
+       udelay(data ? 500 : 1000);
+       flexcop_set_tone(fe, SEC_TONE_OFF);
+       udelay(data ? 1000 : 500);
+}
+
+static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
+{
+       int i, par = 1, d;
+
+       for (i = 7; i >= 0; i--) {
+               d = (data >> i) & 1;
+               par ^= d;
+               flexcop_diseqc_send_bit(fe, d);
+       }
+
+       flexcop_diseqc_send_bit(fe, par);
+}
+
+static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst)
+{
+       int i;
+
+       flexcop_set_tone(fe, SEC_TONE_OFF);
+       mdelay(16);
+
+       for (i = 0; i < len; i++)
+               flexcop_diseqc_send_byte(fe,msg[i]);
+
+       mdelay(16);
+
+       if (burst != -1) {
+               if (burst)
+                       flexcop_diseqc_send_byte(fe, 0xff);
+               else {
+                       flexcop_set_tone(fe, SEC_TONE_ON);
+                       udelay(12500);
+                       flexcop_set_tone(fe, SEC_TONE_OFF);
+               }
+               msleep(20);
+       }
+       return 0;
+}
+
+static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+{
+       return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
+}
+
+static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+       return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
+}
+
+/* dvb-s stv0299 */
+static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
+{
+       u8 aclk = 0;
+       u8 bclk = 0;
+
+       if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
+       else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
+       else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
+       else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
+       else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
+       else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
+
+       stv0299_writereg (fe, 0x13, aclk);
+       stv0299_writereg (fe, 0x14, bclk);
+       stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
+       stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
+
+       return 0;
+}
+
+static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+       u8 buf[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
+       struct flexcop_device *fc = fe->dvb->priv;
+
+       div = params->frequency / 125;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0x84;  /* 0xC4 */
+       buf[3] = 0x08;
+
+       if (params->frequency < 1500000) buf[3] |= 0x10;
+
+       if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static u8 samsung_tbmu24112_inittab[] = {
+            0x01, 0x15,
+            0x02, 0x30,
+            0x03, 0x00,
+            0x04, 0x7D,
+            0x05, 0x35,
+            0x06, 0x02,
+            0x07, 0x00,
+            0x08, 0xC3,
+            0x0C, 0x00,
+            0x0D, 0x81,
+            0x0E, 0x23,
+            0x0F, 0x12,
+            0x10, 0x7E,
+            0x11, 0x84,
+            0x12, 0xB9,
+            0x13, 0x88,
+            0x14, 0x89,
+            0x15, 0xC9,
+            0x16, 0x00,
+            0x17, 0x5C,
+            0x18, 0x00,
+            0x19, 0x00,
+            0x1A, 0x00,
+            0x1C, 0x00,
+            0x1D, 0x00,
+            0x1E, 0x00,
+            0x1F, 0x3A,
+            0x20, 0x2E,
+            0x21, 0x80,
+            0x22, 0xFF,
+            0x23, 0xC1,
+            0x28, 0x00,
+            0x29, 0x1E,
+            0x2A, 0x14,
+            0x2B, 0x0F,
+            0x2C, 0x09,
+            0x2D, 0x05,
+            0x31, 0x1F,
+            0x32, 0x19,
+            0x33, 0xFE,
+            0x34, 0x93,
+            0xff, 0xff,
+};
+
+static struct stv0299_config samsung_tbmu24112_config = {
+       .demod_address = 0x68,
+       .inittab = samsung_tbmu24112_inittab,
+       .mclk = 88000000UL,
+       .invert = 0,
+       .enhanced_tuning = 0,
+       .skip_reinit = 0,
+       .lock_output = STV0229_LOCKOUTPUT_LK,
+       .volt13_op0_op1 = STV0299_VOLT13_OP1,
+       .min_delay_ms = 100,
+       .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
+       .pll_set = samsung_tbmu24112_pll_set,
+};
+
+/* dvb-t mt352 */
+static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
+{
+       static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
+       static u8 mt352_reset [] = { 0x50, 0x80 };
+       static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+       static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
+       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
+
+       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+       udelay(2000);
+       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+
+       mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
+       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+       return 0;
+}
+
+static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
+{
+       u32 div;
+       unsigned char bs = 0;
+
+       #define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
+       div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
+
+       if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
+       if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
+       if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
+
+       pllbuf[0] = 0xc2; /* Note: non-linux standard PLL i2c address */
+       pllbuf[1] = div >> 8;
+       pllbuf[2] = div & 0xff;
+       pllbuf[3] = 0xcc;
+       pllbuf[4] = bs;
+
+       return 0;
+}
+
+static struct mt352_config samsung_tdtc9251dh0_config = {
+
+       .demod_address = 0x0f,
+       .demod_init = samsung_tdtc9251dh0_demod_init,
+       .pll_set = samsung_tdtc9251dh0_pll_set,
+};
+
+static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+{
+       struct flexcop_device *fc = fe->dvb->priv;
+       return request_firmware(fw, name, fc->dev);
+}
+
+static struct nxt2002_config samsung_tbmv_config = {
+       .demod_address = 0x0a,
+       .request_firmware = nxt2002_request_firmware,
+};
+
+static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+       u8 buf[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
+       struct flexcop_device *fc = fe->dvb->priv;
+
+       div = (params->frequency + (125/2)) / 125;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = (div >> 0) & 0xff;
+       buf[2] = 0x84 | ((div >> 10) & 0x60);
+       buf[3] = 0x80;
+
+       if (params->frequency < 1550000)
+               buf[3] |= 0x02;
+
+       if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct mt312_config skystar23_samsung_tbdu18132_config = {
+
+       .demod_address = 0x0e,
+       .pll_set = skystar23_samsung_tbdu18132_pll_set,
+};
+
+static struct stv0297_config alps_tdee4_stv0297_config = {
+       .demod_address = 0x1c,
+//     .invert = 1,
+//     .pll_set = alps_tdee4_stv0297_pll_set,
+};
+
+/* try to figure out the frontend, each card/box can have on of the following list */
+int flexcop_frontend_init(struct flexcop_device *fc)
+{
+       /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
+       if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
+               fc->fe->ops->set_voltage = flexcop_set_voltage;
+
+               fc->fe_sleep             = fc->fe->ops->sleep;
+               fc->fe->ops->sleep       = flexcop_sleep;
+
+               fc->dev_type          = FC_SKY;
+               info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
+       } else
+       /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
+       if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
+               fc->dev_type          = FC_AIR_DVB;
+               info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
+       } else
+       /* try the air atsc (nxt2002) */
+       if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
+               fc->dev_type          = FC_AIR_ATSC;
+               info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
+       } else
+       /* try the cable dvb (stv0297) */
+       if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) {
+               fc->dev_type                        = FC_CABLE;
+               info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
+       } else
+       /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
+       if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
+               fc->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
+               fc->fe->ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
+               fc->fe->ops->set_tone               = flexcop_set_tone;
+               fc->fe->ops->set_voltage            = flexcop_set_voltage;
+
+               fc->fe_sleep                        = fc->fe->ops->sleep;
+               fc->fe->ops->sleep                  = flexcop_sleep;
+
+               fc->dev_type                        = FC_SKY_OLD;
+               info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
+       }
+
+       if (fc->fe == NULL) {
+               err("no frontend driver found for this B2C2/FlexCop adapter");
+               return -ENODEV;
+       } else {
+               if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
+                       err("frontend registration failed!");
+                       if (fc->fe->ops->release != NULL)
+                               fc->fe->ops->release(fc->fe);
+                       fc->fe = NULL;
+                       return -EINVAL;
+               }
+       }
+       fc->init_state |= FC_STATE_FE_INIT;
+       return 0;
+}
+
+void flexcop_frontend_exit(struct flexcop_device *fc)
+{
+       if (fc->init_state & FC_STATE_FE_INIT)
+               dvb_unregister_frontend(fc->fe);
+
+       fc->init_state &= ~FC_STATE_FE_INIT;
+}
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
new file mode 100644 (file)
index 0000000..2baf43d
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions.
+ *
+ * see flexcop.c for copyright information.
+ */
+#include "flexcop.h"
+
+static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);
+}
+
+void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff);
+}
+
+void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff);
+}
+
+void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
+{
+       flexcop_ibi_value v418,v41c;
+       v41c = fc->read_ibi_reg(fc,mac_address_41c);
+
+       v418.mac_address_418.MAC1 = mac[0];
+       v418.mac_address_418.MAC2 = mac[1];
+       v418.mac_address_418.MAC3 = mac[2];
+       v418.mac_address_418.MAC6 = mac[3];
+       v41c.mac_address_41c.MAC7 = mac[4];
+       v41c.mac_address_41c.MAC8 = mac[5];
+
+       fc->write_ibi_reg(fc,mac_address_418,v418);
+       fc->write_ibi_reg(fc,mac_address_41c,v41c);
+}
+
+void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff);
+}
+
+static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask)
+{
+       /* index_reg_310.extra_index_reg need to 0 or 7 to work */
+       flexcop_ibi_value v30c;
+       v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
+       v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
+       fc->write_ibi_reg(fc,pid_filter_30c,v30c);
+}
+
+static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff);
+}
+
+/* this fancy define reduces the code size of the quite similar PID controlling of
+ * the first 6 PIDs
+ */
+
+#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
+       flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
+                                         v208 = fc->read_ibi_reg(fc, ctrl_208); \
+\
+       vpid.vregname.field = onoff ? pid : 0x1fff; \
+       vpid.vregname.trans_field = transval; \
+       v208.ctrl_208.enablefield = onoff; \
+\
+       fc->write_ibi_reg(fc,vregname,vpid); \
+       fc->write_ibi_reg(fc,ctrl_208,v208);
+
+static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0);
+}
+
+static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0);
+}
+
+static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0);
+}
+
+static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0);
+}
+
+static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0);
+}
+
+static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0);
+}
+
+static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff)
+{
+       if (pid == 0x2000)
+               return;
+
+       deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off");
+
+       /* We could use bit magic here to reduce source code size.
+        * I decided against it, but to use the real register names */
+       switch (index) {
+               case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break;
+               case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break;
+               case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break;
+               case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break;
+               case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break;
+               case 5: flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break;
+               default:
+                       if (fc->has_32_hw_pid_filter && index < 38) {
+                               flexcop_ibi_value vpid,vid;
+
+                               /* set the index */
+                               vid = fc->read_ibi_reg(fc,index_reg_310);
+                               vid.index_reg_310.index_reg = index - 6;
+                               fc->write_ibi_reg(fc,index_reg_310, vid);
+
+                               vpid = fc->read_ibi_reg(fc,pid_n_reg_314);
+                               vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
+                               vpid.pid_n_reg_314.PID_enable_bit = onoff;
+                               fc->write_ibi_reg(fc,pid_n_reg_314, vpid);
+                       }
+                       break;
+       }
+}
+
+static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff)
+{
+       if (fc->fullts_streaming_state != onoff) {
+               deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
+               flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
+               flexcop_pid_group_filter_ctrl(fc,onoff);
+               fc->fullts_streaming_state = onoff;
+       }
+       return 0;
+}
+
+int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff)
+{
+       int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
+
+       fc->feedcount += onoff ? 1 : -1;
+       if (dvbdmxfeed->index >= max_pid_filter)
+               fc->extra_feedcount += onoff ? 1 : -1;
+
+       /* toggle complete-TS-streaming when:
+        * - pid_filtering is not enabled and it is the first or last feed requested
+        * - pid_filtering is enabled,
+        *   - but the number of requested feeds is exceeded
+        *   - or the requested pid is 0x2000 */
+
+       if (!fc->pid_filtering && fc->feedcount == onoff)
+               flexcop_toggle_fullts_streaming(fc,onoff);
+
+       if (fc->pid_filtering) {
+               flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+
+               if (fc->extra_feedcount > 0)
+                       flexcop_toggle_fullts_streaming(fc,1);
+               else if (dvbdmxfeed->pid == 0x2000)
+                       flexcop_toggle_fullts_streaming(fc,onoff);
+               else
+                       flexcop_toggle_fullts_streaming(fc,0);
+       }
+
+       /* if it was the first or last feed request change the stream-status */
+       if (fc->feedcount == onoff) {
+               flexcop_rcv_data_ctrl(fc,onoff);
+               if (fc->stream_control)
+                       fc->stream_control(fc,onoff);
+       }
+
+       return 0;
+}
+
+void flexcop_hw_filter_init(struct flexcop_device *fc)
+{
+       int i;
+       flexcop_ibi_value v;
+       for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
+               flexcop_pid_control(fc,i,0x1fff,0);
+
+       flexcop_pid_group_filter(fc, 0, 0x1fe0);
+       flexcop_pid_group_filter_ctrl(fc,0);
+
+       v = fc->read_ibi_reg(fc,pid_filter_308);
+       v.pid_filter_308.EMM_filter_4 = 1;
+       v.pid_filter_308.EMM_filter_6 = 0;
+       fc->write_ibi_reg(fc,pid_filter_308,v);
+
+       flexcop_null_filter_ctrl(fc, 1);
+}
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c
new file mode 100644 (file)
index 0000000..be4266d
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
+ *
+ * see flexcop.c for copyright information.
+ */
+#include "flexcop.h"
+
+#define FC_MAX_I2C_RETRIES 100000
+
+static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100)
+{
+       int i;
+       flexcop_ibi_value r;
+
+       r100->tw_sm_c_100.working_start = 1;
+       deb_i2c("r100 before: %08x\n",r100->raw);
+
+       fc->write_ibi_reg(fc, tw_sm_c_100, ibi_zero);
+       fc->write_ibi_reg(fc, tw_sm_c_100, *r100); /* initiating i2c operation */
+
+       for (i = 0; i < FC_MAX_I2C_RETRIES; i++) {
+               r = fc->read_ibi_reg(fc, tw_sm_c_100);
+
+               if (!r.tw_sm_c_100.no_base_addr_ack_error) {
+                       if (r.tw_sm_c_100.st_done) {  /* && !r.tw_sm_c_100.working_start */
+                               *r100 = r;
+                               deb_i2c("i2c success\n");
+                               return 0;
+                       }
+               } else {
+                       deb_i2c("suffering from an i2c ack_error\n");
+                       return -EREMOTEIO;
+               }
+       }
+       deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i);
+       return -EREMOTEIO;
+}
+
+static int flexcop_i2c_read4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf)
+{
+       flexcop_ibi_value r104;
+       int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */
+               ret;
+
+       if ((ret = flexcop_i2c_operation(fc,&r100)) != 0) {
+               /* The Cablestar needs a different kind of i2c-transfer (does not
+                * support "Repeat Start"):
+                * wait for the ACK failure,
+                * and do a subsequent read with the Bit 30 enabled
+                */
+               r100.tw_sm_c_100.no_base_addr_ack_error = 1;
+               if ((ret = flexcop_i2c_operation(fc,&r100)) != 0) {
+                       deb_i2c("no_base_addr read failed. %d\n",ret);
+                       return ret;
+               }
+       }
+
+       buf[0] = r100.tw_sm_c_100.data1_reg;
+
+       if (len > 0) {
+               r104 = fc->read_ibi_reg(fc,tw_sm_c_104);
+               deb_i2c("read: r100: %08x, r104: %08x\n",r100.raw,r104.raw);
+
+               /* there is at least one more byte, otherwise we wouldn't be here */
+               buf[1] = r104.tw_sm_c_104.data2_reg;
+               if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
+               if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
+       }
+
+       return 0;
+}
+
+static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf)
+{
+       flexcop_ibi_value r104;
+       int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
+       r104.raw = 0;
+
+       /* there is at least one byte, otherwise we wouldn't be here */
+       r100.tw_sm_c_100.data1_reg = buf[0];
+
+       r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
+       r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
+       r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
+
+       deb_i2c("write: r100: %08x, r104: %08x\n",r100.raw,r104.raw);
+
+       /* write the additional i2c data before doing the actual i2c operation */
+       fc->write_ibi_reg(fc,tw_sm_c_104,r104);
+       return flexcop_i2c_operation(fc,&r100);
+}
+
+int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op,
+               flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+{
+       int ret;
+       u16 bytes_to_transfer;
+       flexcop_ibi_value r100;
+
+       deb_i2c("op = %d\n",op);
+       r100.raw = 0;
+       r100.tw_sm_c_100.chipaddr = chipaddr;
+       r100.tw_sm_c_100.twoWS_rw = op;
+       r100.tw_sm_c_100.twoWS_port_reg = port;
+
+       while (len != 0) {
+               bytes_to_transfer = len > 4 ? 4 : len;
+
+               r100.tw_sm_c_100.total_bytes = bytes_to_transfer - 1;
+               r100.tw_sm_c_100.baseaddr = addr;
+
+               if (op == FC_READ)
+                       ret = flexcop_i2c_read4(fc, r100, buf);
+               else
+                       ret = flexcop_i2c_write4(fc,r100, buf);
+
+               if (ret < 0)
+                       return ret;
+
+               buf  += bytes_to_transfer;
+               addr += bytes_to_transfer;
+               len  -= bytes_to_transfer;
+       };
+
+       return 0;
+}
+/* exported for PCI i2c */
+EXPORT_SYMBOL(flexcop_i2c_request);
+
+/* master xfer callback for demodulator */
+static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+{
+       struct flexcop_device *fc = i2c_get_adapdata(i2c_adap);
+       int i, ret = 0;
+
+       if (down_interruptible(&fc->i2c_sem))
+               return -ERESTARTSYS;
+
+       /* reading */
+       if (num == 2 &&
+               msgs[0].flags == 0 &&
+               msgs[1].flags == I2C_M_RD &&
+               msgs[0].buf != NULL &&
+               msgs[1].buf != NULL) {
+
+               ret = fc->i2c_request(fc, FC_READ, FC_I2C_PORT_DEMOD, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
+
+       } else for (i = 0; i < num; i++) { /* writing command */
+               if (msgs[i].flags != 0 || msgs[i].buf == NULL || msgs[i].len < 2) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               ret = fc->i2c_request(fc, FC_WRITE, FC_I2C_PORT_DEMOD, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1);
+       }
+
+       if (ret < 0)
+               err("i2c master_xfer failed");
+       else
+               ret = num;
+
+       up(&fc->i2c_sem);
+
+       return ret;
+}
+
+static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm flexcop_algo = {
+       .name                   = "FlexCop I2C algorithm",
+       .id                             = I2C_ALGO_BIT,
+       .master_xfer    = flexcop_master_xfer,
+       .functionality  = flexcop_i2c_func,
+};
+
+int flexcop_i2c_init(struct flexcop_device *fc)
+{
+       int ret;
+
+       sema_init(&fc->i2c_sem,1);
+
+       memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter));
+       strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE);
+
+       i2c_set_adapdata(&fc->i2c_adap,fc);
+
+       fc->i2c_adap.class          = I2C_CLASS_TV_DIGITAL;
+       fc->i2c_adap.algo       = &flexcop_algo;
+       fc->i2c_adap.algo_data  = NULL;
+       fc->i2c_adap.id         = I2C_ALGO_BIT;
+
+       if ((ret = i2c_add_adapter(&fc->i2c_adap)) < 0)
+               return ret;
+
+       fc->init_state |= FC_STATE_I2C_INIT;
+       return 0;
+}
+
+void flexcop_i2c_exit(struct flexcop_device *fc)
+{
+       if (fc->init_state & FC_STATE_I2C_INIT)
+               i2c_del_adapter(&fc->i2c_adap);
+
+       fc->init_state &= ~FC_STATE_I2C_INIT;
+}
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
new file mode 100644 (file)
index 0000000..19e06da
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-misc.c - miscellaneous functions.
+ *
+ * see flexcop.c for copyright information.
+ */
+#include "flexcop.h"
+
+void flexcop_determine_revision(struct flexcop_device *fc)
+{
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
+
+       switch (v.misc_204.Rev_N_sig_revision_hi) {
+               case 0x2:
+                       deb_info("found a FlexCopII.\n");
+                       fc->rev = FLEXCOP_II;
+                       break;
+               case 0x3:
+                       deb_info("found a FlexCopIIb.\n");
+                       fc->rev = FLEXCOP_IIB;
+                       break;
+               case 0x0:
+                       deb_info("found a FlexCopIII.\n");
+                       fc->rev = FLEXCOP_III;
+                       break;
+               default:
+                       err("unkown FlexCop Revision: %x. Please report the linux-dvb@linuxtv.org.",v.misc_204.Rev_N_sig_revision_hi);
+                       break;
+       }
+
+       if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
+               deb_info("this FlexCop has the additional 32 hardware pid filter.\n");
+       else
+               deb_info("this FlexCop has only the 6 basic main hardware pid filter.\n");
+       /* bus parts have to decide if hw pid filtering is used or not. */
+}
+
+const char *flexcop_revision_names[] = {
+       "Unkown chip",
+       "FlexCopII",
+       "FlexCopIIb",
+       "FlexCopIII",
+};
+
+const char *flexcop_device_names[] = {
+       "Unkown device",
+       "AirStar 2 DVB-T",
+       "AirStar 2 ATSC",
+       "SkyStar 2 DVB-S",
+       "SkyStar 2 DVB-S (old version)",
+       "CableStar 2 DVB-C",
+};
+
+const char *flexcop_bus_names[] = {
+       "USB",
+       "PCI",
+};
+
+void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const
+               char *suffix)
+{
+       info("%s '%s' at the '%s' bus controlled by a '%s' %s",prefix,
+                       flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type],
+                       flexcop_revision_names[fc->rev],suffix);
+}
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
new file mode 100644 (file)
index 0000000..ed717c0
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-pci.c - covers the PCI part including DMA transfers.
+ *
+ * see flexcop.c for copyright information.
+ */
+
+#define FC_LOG_PREFIX "flexcop-pci"
+#include "flexcop-common.h"
+
+static int enable_pid_filtering = 1;
+module_param(enable_pid_filtering, int, 0444);
+MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
+
+#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
+#define dprintk(level,args...) \
+       do { if ((debug & level)) printk(args); } while (0)
+#define DEBSTATUS ""
+#else
+#define dprintk(level,args...)
+#define DEBSTATUS " (debugging is not enabled)"
+#endif
+
+#define deb_info(args...)  dprintk(0x01,args)
+#define deb_reg(args...)   dprintk(0x02,args)
+#define deb_ts(args...)    dprintk(0x04,args)
+#define deb_irq(args...)   dprintk(0x08,args)
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS);
+
+#define DRIVER_VERSION "0.1"
+#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
+#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
+
+struct flexcop_pci {
+       struct pci_dev *pdev;
+
+#define FC_PCI_INIT     0x01
+#define FC_PCI_DMA_INIT 0x02
+       int init_state;
+
+       void __iomem *io_mem;
+       u32 irq;
+/* buffersize (at least for DMA1, need to be % 188 == 0,
+ * this logic is required */
+#define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188)
+#define FC_DEFAULT_DMA2_BUFSIZE (10 * 188)
+       struct flexcop_dma dma[2];
+
+       int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
+       u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
+       int count;
+
+       spinlock_t irq_lock;
+
+       struct flexcop_device *fc_dev;
+};
+
+static int lastwreg,lastwval,lastrreg,lastrval;
+
+static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r)
+{
+       struct flexcop_pci *fc_pci = fc->bus_specific;
+       flexcop_ibi_value v;
+       v.raw = readl(fc_pci->io_mem + r);
+
+       if (lastrreg != r || lastrval != v.raw) {
+               lastrreg = r; lastrval = v.raw;
+               deb_reg("new rd: %3x: %08x\n",r,v.raw);
+       }
+
+       return v;
+}
+
+static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v)
+{
+       struct flexcop_pci *fc_pci = fc->bus_specific;
+
+       if (lastwreg != r || lastwval != v.raw) {
+               lastwreg = r; lastwval = v.raw;
+               deb_reg("new wr: %3x: %08x\n",r,v.raw);
+       }
+
+       writel(v.raw, fc_pci->io_mem + r);
+       return 0;
+}
+
+/* When PID filtering is turned on, we use the timer IRQ, because small amounts
+ * of data need to be passed to the user space instantly as well. When PID
+ * filtering is turned off, we use the page-change-IRQ */
+static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct flexcop_pci *fc_pci = dev_id;
+       struct flexcop_device *fc = fc_pci->fc_dev;
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,irq_20c);
+       irqreturn_t ret = IRQ_HANDLED;
+
+       spin_lock_irq(&fc_pci->irq_lock);
+
+       if (v.irq_20c.DMA1_IRQ_Status == 1) {
+               if (fc_pci->active_dma1_addr == 0)
+                       flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
+               else
+                       flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188);
+
+               deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr);
+               fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr;
+       } else if (v.irq_20c.DMA1_Timer_Status == 1) {
+               /* for the timer IRQ we only can use buffer dmx feeding, because we don't have
+                * complete TS packets when reading from the DMA memory */
+               dma_addr_t cur_addr =
+                       fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
+               u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
+
+               deb_irq("irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
+                               v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+
+               /* buffer end was reached, restarted from the beginning
+                * pass the data from last_cur_pos to the buffer end to the demux
+                */
+               if (cur_pos < fc_pci->last_dma1_cur_pos) {
+                       deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos);
+                       flexcop_pass_dmx_data(fc_pci->fc_dev,
+                                       fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
+                                       (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos);
+                       fc_pci->last_dma1_cur_pos = 0;
+                       fc_pci->count = 0;
+               }
+
+               if (cur_pos > fc_pci->last_dma1_cur_pos) {
+                       deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos);
+                       flexcop_pass_dmx_data(fc_pci->fc_dev,
+                                       fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
+                                       cur_pos - fc_pci->last_dma1_cur_pos);
+               }
+               deb_irq("\n");
+
+               fc_pci->last_dma1_cur_pos = cur_pos;
+       } else
+               ret = IRQ_NONE;
+
+       spin_unlock_irq(&fc_pci->irq_lock);
+
+/* packet count would be ideal for hw filtering, but it isn't working. Either
+ * the data book is wrong, or I'm unable to read it correctly */
+
+/*     if (v.irq_20c.DMA1_Size_IRQ_Status == 1) { packet counter */
+
+       return ret;
+}
+
+static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
+{
+       struct flexcop_pci *fc_pci = fc->bus_specific;
+       if (onoff) {
+               flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1);
+               flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1);
+               flexcop_dma_config_timer(fc,FC_DMA_1,1);
+
+               if (fc_pci->fc_dev->pid_filtering) {
+                       fc_pci->last_dma1_cur_pos = 0;
+                       flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
+               } else {
+                       fc_pci->active_dma1_addr = 0;
+                       flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
+               }
+
+/*             flexcop_dma_config_packet_count(fc,FC_DMA_1,0xc0);
+               flexcop_dma_control_packet_irq(fc,FC_DMA_1,1); */
+
+               deb_irq("irqs enabled\n");
+       } else {
+               if (fc_pci->fc_dev->pid_filtering)
+                       flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
+               else
+                       flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
+
+//             flexcop_dma_control_packet_irq(fc,FC_DMA_1,0);
+               deb_irq("irqs disabled\n");
+       }
+
+       return 0;
+}
+
+static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
+{
+       int ret;
+       if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0)
+               return ret;
+
+       if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0)
+               goto dma1_free;
+
+       flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
+       flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO   | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
+
+       fc_pci->init_state |= FC_PCI_DMA_INIT;
+       goto success;
+dma1_free:
+       flexcop_dma_free(&fc_pci->dma[0]);
+
+success:
+       return ret;
+}
+
+static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci)
+{
+       if (fc_pci->init_state & FC_PCI_DMA_INIT) {
+               flexcop_dma_free(&fc_pci->dma[0]);
+               flexcop_dma_free(&fc_pci->dma[1]);
+       }
+       fc_pci->init_state &= ~FC_PCI_DMA_INIT;
+}
+
+static int flexcop_pci_init(struct flexcop_pci *fc_pci)
+{
+       int ret;
+       u8 card_rev;
+
+       pci_read_config_byte(fc_pci->pdev, PCI_CLASS_REVISION, &card_rev);
+       info("card revision %x", card_rev);
+
+       if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
+               return ret;
+
+       pci_set_master(fc_pci->pdev);
+
+       /* enable interrupts */
+       // pci_write_config_dword(pdev, 0x6c, 0x8000);
+
+       if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
+               goto err_pci_disable_device;
+
+       fc_pci->io_mem = pci_iomap(fc_pci->pdev, 0, 0x800);
+
+       if (!fc_pci->io_mem) {
+               err("cannot map io memory\n");
+               ret = -EIO;
+               goto err_pci_release_regions;
+       }
+
+       pci_set_drvdata(fc_pci->pdev, fc_pci);
+
+       if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_irq,
+                                       SA_SHIRQ, DRIVER_NAME, fc_pci)) != 0)
+               goto err_pci_iounmap;
+
+       spin_lock_init(&fc_pci->irq_lock);
+
+       fc_pci->init_state |= FC_PCI_INIT;
+       goto success;
+
+err_pci_iounmap:
+       pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
+       pci_set_drvdata(fc_pci->pdev, NULL);
+err_pci_release_regions:
+       pci_release_regions(fc_pci->pdev);
+err_pci_disable_device:
+       pci_disable_device(fc_pci->pdev);
+
+success:
+       return ret;
+}
+
+static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
+{
+       if (fc_pci->init_state & FC_PCI_INIT) {
+               free_irq(fc_pci->pdev->irq, fc_pci);
+               pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
+               pci_set_drvdata(fc_pci->pdev, NULL);
+               pci_release_regions(fc_pci->pdev);
+               pci_disable_device(fc_pci->pdev);
+       }
+       fc_pci->init_state &= ~FC_PCI_INIT;
+}
+
+
+static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+       struct flexcop_device *fc;
+       struct flexcop_pci *fc_pci;
+       int ret = -ENOMEM;
+
+       if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_pci))) == NULL) {
+               err("out of memory\n");
+               return -ENOMEM;
+       }
+
+/* general flexcop init */
+       fc_pci = fc->bus_specific;
+       fc_pci->fc_dev = fc;
+
+       fc->read_ibi_reg = flexcop_pci_read_ibi_reg;
+       fc->write_ibi_reg = flexcop_pci_write_ibi_reg;
+       fc->i2c_request = flexcop_i2c_request;
+       fc->get_mac_addr = flexcop_eeprom_check_mac_addr;
+
+       fc->stream_control = flexcop_pci_stream_control;
+
+       if (enable_pid_filtering)
+               info("will use the HW PID filter.");
+       else
+               info("will pass the complete TS to the demuxer.");
+
+       fc->pid_filtering = enable_pid_filtering;
+       fc->bus_type = FC_PCI;
+
+       fc->dev = &pdev->dev;
+       fc->owner = THIS_MODULE;
+
+/* bus specific part */
+       fc_pci->pdev = pdev;
+       if ((ret = flexcop_pci_init(fc_pci)) != 0)
+               goto err_kfree;
+
+/* init flexcop */
+       if ((ret = flexcop_device_initialize(fc)) != 0)
+               goto err_pci_exit;
+
+/* init dma */
+       if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
+               goto err_fc_exit;
+
+       goto success;
+err_fc_exit:
+       flexcop_device_exit(fc);
+err_pci_exit:
+       flexcop_pci_exit(fc_pci);
+err_kfree:
+       flexcop_device_kfree(fc);
+success:
+       return ret;
+}
+
+/* in theory every _exit function should be called exactly two times,
+ * here and in the bail-out-part of the _init-function
+ */
+static void flexcop_pci_remove(struct pci_dev *pdev)
+{
+       struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
+
+       flexcop_pci_dma_exit(fc_pci);
+       flexcop_device_exit(fc_pci->fc_dev);
+       flexcop_pci_exit(fc_pci);
+       flexcop_device_kfree(fc_pci->fc_dev);
+}
+
+static struct pci_device_id flexcop_pci_tbl[] = {
+       { PCI_DEVICE(0x13d0, 0x2103) },
+/*     { PCI_DEVICE(0x13d0, 0x2200) }, PCI FlexCopIII ? */
+       { },
+};
+
+MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl);
+
+static struct pci_driver flexcop_pci_driver = {
+       .name = "Technisat/B2C2 FlexCop II/IIb/III PCI",
+       .id_table = flexcop_pci_tbl,
+       .probe = flexcop_pci_probe,
+       .remove = flexcop_pci_remove,
+};
+
+static int __init flexcop_pci_module_init(void)
+{
+       return pci_register_driver(&flexcop_pci_driver);
+}
+
+static void __exit flexcop_pci_module_exit(void)
+{
+       pci_unregister_driver(&flexcop_pci_driver);
+}
+
+module_init(flexcop_pci_module_init);
+module_exit(flexcop_pci_module_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_NAME);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
new file mode 100644 (file)
index 0000000..5e131be
--- /dev/null
@@ -0,0 +1,701 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
+ *
+ * see flexcop.c for copyright information.
+ */
+#ifndef __FLEXCOP_REG_H__
+#define __FLEXCOP_REG_H__
+
+
+typedef enum {
+       FLEXCOP_UNK = 0,
+       FLEXCOP_II,
+       FLEXCOP_IIB,
+       FLEXCOP_III,
+} flexcop_revision_t;
+
+extern const char *flexcop_revision_names[];
+
+typedef enum {
+       FC_UNK = 0,
+       FC_AIR_DVB,
+       FC_AIR_ATSC,
+       FC_SKY,
+       FC_SKY_OLD,
+       FC_CABLE,
+} flexcop_device_type_t;
+
+typedef enum {
+       FC_USB = 0,
+       FC_PCI,
+} flexcop_bus_t;
+
+extern const char *flexcop_device_names[];
+
+/* FlexCop IBI Registers */
+
+/* flexcop_ibi_reg - a huge union representing the register structure */
+typedef union {
+       u32 raw;
+
+/* DMA 0x000 to 0x01c
+ * DMA1 0x000 to 0x00c
+ * DMA2 0x010 to 0x01c
+ */
+       struct {
+               u32 dma_0start        : 1;   /* set: data will be delivered to dma1_address0 */
+        u32 dma_0No_update    : 1;   /* set: dma1_cur_address will be updated, unset: no update */
+        u32 dma_address0      :30;   /* physical/virtual host memory address0 DMA */
+       } dma_0x0;
+
+       struct {
+               u32 DMA_maxpackets    : 8;   /* (remapped) PCI DMA1 Packet Count Interrupt. This variable
+                                                                               is able to be read and written while bit(1) of register
+                                                                               0x00c (remap_enable) is set. This variable represents
+                                                                               the number of packets that will be transmitted to the PCI
+                                                                               host using PCI DMA1 before an interrupt to the PCI is
+                                                                               asserted. This functionality may be enabled using bit(20)
+                                                                               of register 0x208. N=0 disables the IRQ. */
+               u32 dma_addr_size     :24;   /* size of memory buffer in DWORDs (bytesize / 4) for DMA */
+       } dma_0x4_remap;
+
+       struct {
+               u32 dma1timer         : 7;   /* reading PCI DMA1 timer ... when remap_enable is 0 */
+               u32 unused            : 1;
+               u32 dma_addr_size     :24;
+       } dma_0x4_read;
+
+       struct {
+               u32 unused            : 1;
+               u32 dmatimer          : 7;   /* writing PCI DMA1 timer ... when remap_enable is 0 */
+               u32 dma_addr_size     :24;
+       } dma_0x4_write;
+
+       struct {
+               u32 unused            : 2;
+               u32 dma_cur_addr      :30;   /* current physical host memory address pointer for DMA */
+       } dma_0x8;
+
+       struct {
+               u32 dma_1start        : 1;   /* set: data will be delivered to dma_address1, when dma_address0 is full */
+               u32 remap_enable      : 1;   /* remap enable for 0x0x4(7:0) */
+               u32 dma_address1      :30;   /* Physical/virtual address 1 on DMA */
+       } dma_0xc;
+
+/* Two-wire Serial Master and Clock 0x100-0x110 */
+       struct {
+//             u32 slave_transmitter : 1;   /* ???*/
+               u32 chipaddr          : 7;   /* two-line serial address of the target slave */
+               u32 reserved1         : 1;
+               u32 baseaddr          : 8;   /* address of the location of the read/write operation */
+               u32 data1_reg         : 8;   /* first byte in two-line serial read/write operation */
+               u32 working_start     : 1;  /* when doing a write operation this indicator is 0 when ready
+                                                                         * set to 1 when doing a write operation */
+               u32 twoWS_rw          : 1;   /* read/write indicator (1 = read, 0 write) */
+               u32 total_bytes       : 2;   /* number of data bytes in each two-line serial transaction (0 = 1 byte, 11 = 4byte)*/
+               u32 twoWS_port_reg    : 2;   /* port selection: 01 - Front End/Demod, 10 - EEPROM, 11 - Tuner */
+               u32 no_base_addr_ack_error : 1;   /* writing: write-req: frame is produced w/o baseaddr, read-req: read-cycles w/o
+                                                                         * preceding address assignment write frame
+                                                                         * ACK_ERROR = 1 when no ACK from slave in the last transaction */
+               u32 st_done           : 1;   /* indicator for transaction is done */
+       } tw_sm_c_100;
+
+       struct {
+               u32 data2_reg         : 8;   /* 2nd data byte */
+               u32 data3_reg         : 8;   /* 3rd data byte */
+               u32 data4_reg         : 8;   /* 4th data byte */
+               u32 exlicit_stops     : 1;   /* when set, transactions are produced w/o trailing STOP flag, then send isolated STOP flags */
+               u32 force_stop        : 1;   /* isolated stop flag */
+               u32 unused            : 6;
+       } tw_sm_c_104;
+
+/* Clock. The register allows the FCIII to convert an incoming Master clock
+ * (MCLK) signal into a lower frequency clock through the use of a LowCounter
+ * (TLO) and a High- Counter (THI). The time counts for THI and TLO are
+ * measured in MCLK; each count represents 4 MCLK input clock cycles.
+ *
+ * The default output for port #1 is set for Front End Demod communication. (0x108)
+ * The default output for port #2 is set for EEPROM communication. (0x10c)
+ * The default output for port #3 is set for Tuner communication. (0x110)
+ */
+       struct {
+               u32 thi1              : 6;   /* Thi for port #1 (def: 100110b; 38) */
+               u32 reserved1         : 2;
+               u32 tlo1              : 5;   /* Tlo for port #1 (def: 11100b; 28) */
+               u32 reserved2         :19;
+       } tw_sm_c_108;
+
+       struct {
+               u32 thi1              : 6;   /* Thi for port #2 (def: 111001b; 57) */
+               u32 reserved1         : 2;
+               u32 tlo1              : 5;   /* Tlo for port #2 (def: 11100b; 28) */
+               u32 reserved2         :19;
+       } tw_sm_c_10c;
+
+       struct {
+               u32 thi1              : 6;   /* Thi for port #3 (def: 111001b; 57) */
+               u32 reserved1         : 2;
+               u32 tlo1              : 5;   /* Tlo for port #3 (def: 11100b; 28) */
+               u32 reserved2         :19;
+       } tw_sm_c_110;
+
+/* LNB Switch Frequency 0x200
+ * Clock that creates the LNB switch tone. The default is set to have a fixed
+ * low output (not oscillating) to the LNB_CTL line.
+ */
+       struct {
+               u32 LNB_CTLHighCount_sig :15; /* It is the number of pre-scaled clock cycles that will be low. */
+               u32 LNB_CTLLowCount_sig  :15; /* For example, to obtain a 22KHz output given a 45 Mhz Master
+                                                                               Clock signal (MCLK), set PreScalar=01 and LowCounter value to 0x1ff. */
+               u32 LNB_CTLPrescaler_sig : 2; /* pre-scaler divides MCLK: 00 (no division), 01 by 2, 10 by 4, 11 by 12 */
+       } lnb_switch_freq_200;
+
+/* ACPI, Peripheral Reset, LNB Polarity
+ * ACPI power conservation mode, LNB polarity selection (low or high voltage),
+ * and peripheral reset.
+ */
+       struct {
+               u32 ACPI1_sig         : 1;   /* turn of the power of tuner and LNB, not implemented in FCIII */
+               u32 ACPI3_sig         : 1;   /* turn of power of the complete satelite receiver board (except FCIII) */
+               u32 LNB_L_H_sig       : 1;   /* low or high voltage for LNB. (0 = low, 1 = high) */
+               u32 Per_reset_sig     : 1;   /* misc. init reset (default: 1), to reset set to low and back to high */
+               u32 reserved          :20;
+               u32 Rev_N_sig_revision_hi : 4;/* 0xc in case of FCIII */
+               u32 Rev_N_sig_reserved1 : 2;
+               u32 Rev_N_sig_caps    : 1;   /* if 1, FCIII has 32 PID- and MAC-filters and is capable of IP multicast */
+               u32 Rev_N_sig_reserved2 : 1;
+       } misc_204;
+
+/* Control and Status 0x208 to 0x21c */
+/* Gross enable and disable control */
+       struct {
+               u32 Stream1_filter_sig : 1;  /* Stream1 PID filtering */
+               u32 Stream2_filter_sig : 1;  /* Stream2 PID filtering */
+               u32 PCR_filter_sig    : 1;   /* PCR PID filter */
+               u32 PMT_filter_sig    : 1;   /* PMT PID filter */
+
+               u32 EMM_filter_sig    : 1;   /* EMM PID filter */
+               u32 ECM_filter_sig    : 1;   /* ECM PID filter */
+               u32 Null_filter_sig   : 1;   /* Filters null packets, PID=0x1fff. */
+               u32 Mask_filter_sig   : 1;   /* mask PID filter */
+
+               u32 WAN_Enable_sig    : 1;   /* WAN output line through V8 memory space is activated. */
+               u32 WAN_CA_Enable_sig : 1;   /* not in FCIII */
+               u32 CA_Enable_sig     : 1;   /* not in FCIII */
+               u32 SMC_Enable_sig    : 1;   /* CI stream data (CAI) goes directly to the smart card intf (opposed IBI 0x600 or SC-cmd buf). */
+
+               u32 Per_CA_Enable_sig : 1;   /* not in FCIII */
+               u32 Multi2_Enable_sig : 1;   /* ? */
+               u32 MAC_filter_Mode_sig : 1; /* (MAC_filter_enable) Globally enables MAC filters for Net PID filteres. */
+               u32 Rcv_Data_sig      : 1;   /* PID filtering module enable. When this bit is a one, the PID filter will
+                                                                               examine and process packets according to all other (individual) PID
+                                                                               filtering controls. If it a zero, no packet processing of any kind will
+                                                                               take place. All data from the tuner will be thrown away. */
+
+               u32 DMA1_IRQ_Enable_sig : 1; /* When set, a DWORD counter is enabled on PCI DMA1 that asserts the PCI
+                                                                         * interrupt after the specified count for filling the buffer. */
+               u32 DMA1_Timer_Enable_sig : 1; /* When set, a timer is enabled on PCI DMA1 that asserts the PCI interrupt
+                                                                                       after a specified amount of time. */
+               u32 DMA2_IRQ_Enable_sig : 1;   /* same as DMA1_IRQ_Enable_sig but for DMA2 */
+               u32 DMA2_Timer_Enable_sig : 1;   /* same as DMA1_Timer_Enable_sig but for DMA2 */
+
+               u32 DMA1_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA1 that asserts the PCI interrupt. */
+               u32 DMA2_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA2 that asserts the PCI interrupt. */
+               u32 Mailbox_from_V8_Enable_sig: 1; /* When set, writes to the mailbox register produce an interrupt to the
+                                                                                       PCI host to indicate that mailbox data is available. */
+
+               u32 unused            : 9;
+       } ctrl_208;
+
+/* General status. When a PCI interrupt occurs, this register is read to
+ * discover the reason for the interrupt.
+ */
+       struct {
+               u32 DMA1_IRQ_Status   : 1;   /* When set(1) the DMA1 counter had generated an IRQ. Read Only. */
+               u32 DMA1_Timer_Status : 1;   /* When set(1) the DMA1 timer had generated an IRQ. Read Only. */
+               u32 DMA2_IRQ_Status   : 1;   /* When set(1) the DMA2 counter had generated an IRQ. Read Only. */
+               u32 DMA2_Timer_Status : 1;   /* When set(1) the DMA2 timer had generated an IRQ. Read Only. */
+               u32 DMA1_Size_IRQ_Status : 1; /* (Read only). This register is read after an interrupt to */
+               u32 DMA2_Size_IRQ_Status : 1; /* find out why we had an IRQ. Reading this register will clear this bit. Packet count*/
+               u32 Mailbox_from_V8_Status_sig: 1; /* Same as above. Reading this register will clear this bit. */
+               u32 Data_receiver_error : 1; /* 1 indicate an error in the receiver Front End (Tuner module) */
+               u32 Continuity_error_flag : 1;   /* 1 indicates a continuity error in the TS stream. */
+               u32 LLC_SNAP_FLAG_set : 1;   /* 1 indicates that the LCC_SNAP_FLAG was set. */
+               u32 Transport_Error   : 1;   /*  When set indicates that an unexpected packet was received. */
+               u32 reserved          :21;
+       } irq_20c;
+
+
+/* Software reset register */
+       struct {
+               u32 reset_blocks      : 8;   /* Enabled when Block_reset_enable = 0xB2 and 0x208 bits 15:8 = 0x00.
+                                                                               Each bit location represents a 0x100 block of registers. Writing
+                                                                               a one in a bit location resets that block of registers and the logic
+                                                                               that it controls. */
+               u32 Block_reset_enable : 8;  /* This variable is set to 0xB2 when the register is written. */
+               u32 Special_controls  :16;   /* Asserts Reset_V8 => 0xC258; Turns on pci encryption => 0xC25A;
+                                                                               Turns off pci encryption => 0xC259 Note: pci_encryption default
+                                                                               at power-up is ON. */
+       } sw_reset_210;
+
+       struct {
+               u32 vuart_oe_sig      : 1;   /* When clear, the V8 processor has sole control of the serial UART
+                                                                               (RS-232 Smart Card interface). When set, the IBI interface
+                                                                               defined by register 0x600 controls the serial UART. */
+               u32 v2WS_oe_sig       : 1;   /* When clear, the V8 processor has direct control of the Two-line
+                                                                               Serial Master EEPROM target. When set, the Two-line Serial Master
+                                                                               EEPROM target interface is controlled by IBI register 0x100. */
+               u32 halt_V8_sig       : 1;   /* When set, contiguous wait states are applied to the V8-space
+                                                                               bus masters. Once this signal is cleared, normal V8-space
+                                                                               operations resume. */
+               u32 section_pkg_enable_sig: 1; /* When set, this signal enables the front end translation circuitry
+                                                                                 to process section packed transport streams. */
+               u32 s2p_sel_sig       : 1;   /* Serial to parallel conversion. When set, polarized transport data
+                                                                               within the FlexCop3 front end circuitry is converted from a serial
+                                                                               stream into parallel data before downstream processing otherwise
+                                                                               interprets the data. */
+               u32 unused1           : 3;
+               u32 polarity_PS_CLK_sig: 1;  /* This signal is used to invert the input polarity of the tranport
+                                                                               stream CLOCK signal before any processing occurs on the transport
+                                                                               stream within FlexCop3. */
+               u32 polarity_PS_VALID_sig: 1; /* This signal is used to invert the input polarity of the tranport
+                                                                               stream VALID signal before any processing occurs on the transport
+                                                                               stream within FlexCop3. */
+               u32 polarity_PS_SYNC_sig: 1; /* This signal is used to invert the input polarity of the tranport
+                                                                               stream SYNC signal before any processing occurs on the transport
+                                                                               stream within FlexCop3. */
+               u32 polarity_PS_ERR_sig: 1;  /* This signal is used to invert the input polarity of the tranport
+                                                                               stream ERROR signal before any processing occurs on the transport
+                                                                               stream within FlexCop3. */
+               u32 unused2           :20;
+       } misc_214;
+
+/* Mailbox from V8 to host */
+       struct {
+               u32 Mailbox_from_V8   :32;   /* When this register is written by either the V8 processor or by an
+                                                                               end host, an interrupt is generated to the PCI host to indicate
+                                                                               that mailbox data is available. Reading register 20c will clear
+                                                                               the IRQ. */
+       } mbox_v8_to_host_218;
+
+/* Mailbox from host to v8 Mailbox_to_V8
+ * Mailbox_to_V8 mailbox storage register
+ * used to send messages from PCI to V8. Writing to this register will send an
+ * IRQ to the V8. Then it can read the data from here. Reading this register
+ * will clear the IRQ. If the V8 is halted and bit 31 of this register is set,
+ * then this register is used instead as a direct interface to access the
+ * V8space memory.
+ */
+       struct {
+               u32 sysramaccess_data : 8;   /* Data byte written or read from the specified address in V8 SysRAM. */
+               u32 sysramaccess_addr :15;   /* 15 bit address used to access V8 Sys-RAM. */
+               u32 unused            : 7;
+               u32 sysramaccess_write: 1;   /* Write flag used to latch data into the V8 SysRAM. */
+               u32 sysramaccess_busmuster: 1; /* Setting this bit when the V8 is halted at 0x214 Bit(2) allows
+                                                                                 this IBI register interface to directly drive the V8-space memory. */
+       } mbox_host_to_v8_21c;
+
+
+/* PIDs, Translation Bit, SMC Filter Select 0x300 to 0x31c */
+       struct {
+               u32 Stream1_PID       :13;   /* Primary use is receiving Net data, so these 13 bits normally
+                                                                               hold the PID value for the desired network stream. */
+               u32 Stream1_trans     : 1;   /* When set, Net translation will take place for Net data ferried in TS packets. */
+               u32 MAC_Multicast_filter : 1;   /* When clear, multicast MAC filtering is not allowed for Stream1 and PID_n filters. */
+               u32 debug_flag_pid_saved : 1;
+               u32 Stream2_PID       :13;   /* 13 bits for Stream 2 PID filter value. General use. */
+               u32 Stream2_trans     : 1;   /* When set Tables/CAI translation will take place for the data ferried in
+                                                                               Stream2_PID TS packets. */
+               u32 debug_flag_write_status00 : 1;
+               u32 debug_fifo_problem : 1;
+       } pid_filter_300;
+
+       struct {
+               u32 PCR_PID           :13;   /* PCR stream PID filter value. Primary use is Program Clock Reference stream filtering. */
+               u32 PCR_trans         : 1;   /* When set, Tables/CAI translation will take place for these packets. */
+               u32 debug_overrun3    : 1;
+               u32 debug_overrun2    : 1;
+               u32 PMT_PID           :13;   /* stream PID filter value. Primary use is Program Management Table segment filtering. */
+               u32 PMT_trans         : 1;   /* When set, Tables/CAI translation will take place for these packets. */
+               u32 reserved          : 2;
+       } pid_filter_304;
+
+       struct {
+               u32 EMM_PID           :13;   /* EMM PID filter value. Primary use is Entitlement Management Messaging for
+                                                                               conditional access-related data. */
+               u32 EMM_trans         : 1;   /* When set, Tables/CAI translation will take place for these packets. */
+               u32 EMM_filter_4      : 1;   /* When set will pass only EMM data possessing the same ID code as the
+                                                                               first four bytes (32 bits) of the end-user s 6-byte Smart Card ID number Select */
+               u32 EMM_filter_6      : 1;   /* When set will pass only EMM data possessing the same 6-byte code as the end-users
+                                                                               complete 6-byte Smart Card ID number. */
+               u32 ECM_PID           :13;   /* ECM PID filter value. Primary use is Entitlement Control Messaging for conditional
+                                                                               access-related data. */
+               u32 ECM_trans         : 1;   /* When set, Tables/CAI translation will take place for these packets. */
+               u32 reserved          : 2;
+       } pid_filter_308;
+
+       struct {
+               u32 Group_PID     :13;   /* PID value for group filtering. */
+               u32 Group_trans   : 1;   /* When set, Tables/CAI translation will take place for these packets. */
+               u32 unused1       : 2;
+               u32 Group_mask    :13;   /* Mask value used in logical "and" equation that defines group filtering */
+               u32 unused2       : 3;
+       } pid_filter_30c_ext_ind_0_7;
+
+       struct {
+               u32 net_master_read :17;
+               u32 unused        :15;
+       } pid_filter_30c_ext_ind_1;
+
+       struct {
+               u32 net_master_write :17;
+               u32 unused        :15;
+       } pid_filter_30c_ext_ind_2;
+
+       struct {
+               u32 next_net_master_write :17;
+               u32 unused        :15;
+       } pid_filter_30c_ext_ind_3;
+
+       struct {
+               u32 unused1       : 1;
+               u32 state_write   :10;
+               u32 reserved1     : 6;   /* default: 000100 */
+               u32 stack_read    :10;
+               u32 reserved2     : 5;   /* default: 00100 */
+       } pid_filter_30c_ext_ind_4;
+
+       struct {
+               u32 stack_cnt     :10;
+               u32 unused        :22;
+       } pid_filter_30c_ext_ind_5;
+
+       struct {
+               u32 pid_fsm_save_reg0 : 2;
+               u32 pid_fsm_save_reg1 : 2;
+               u32 pid_fsm_save_reg2 : 2;
+               u32 pid_fsm_save_reg3 : 2;
+               u32 pid_fsm_save_reg4 : 2;
+               u32 pid_fsm_save_reg300 : 2;
+               u32 write_status1 : 2;
+               u32 write_status4 : 2;
+               u32 data_size_reg :12;
+               u32 unused        : 4;
+       } pid_filter_30c_ext_ind_6;
+
+       struct {
+               u32 index_reg         : 5;   /* (Index pointer) Points at an internal PIDn register. A binary code
+                                                                               representing one of 32 internal PIDn registers as well as its
+                                                                               corresponding internal MAC_lown register. */
+               u32 extra_index_reg   : 3;   /* This vector is used to select between sets of debug signals routed to register 0x30c. */
+               u32 AB_select         : 1;   /* Used in conjunction with 0x31c. read/write to the MAC_highA or MAC_highB register
+                                                                               0=MAC_highB register, 1=MAC_highA */
+               u32 pass_alltables    : 1;   /* 1=Net packets are not filtered against the Network Table ID found in register 0x400.
+                                                                               All types of networks (DVB, ATSC, ISDB) are passed. */
+               u32 unused            :22;
+       } index_reg_310;
+
+       struct {
+               u32 PID               :13;   /* PID value */
+               u32 PID_trans         : 1;   /* translation will take place for packets filtered */
+               u32 PID_enable_bit    : 1;   /* When set this PID filter is enabled */
+               u32 reserved          :17;
+       } pid_n_reg_314;
+
+       struct {
+               u32 A4_byte           : 8;
+               u32 A5_byte           : 8;
+               u32 A6_byte           : 8;
+               u32 Enable_bit        : 1;   /* enabled (1) or disabled (1) */
+               u32 HighAB_bit        : 1;   /* use MAC_highA (1) or MAC_highB (0) as MSB */
+               u32 reserved          : 6;
+       } mac_low_reg_318;
+
+       struct {
+               u32 A1_byte           : 8;
+               u32 A2_byte           : 8;
+               u32 A3_byte           : 8;
+               u32 reserved          : 8;
+       } mac_high_reg_31c;
+
+/* Table, SMCID,MACDestination Filters 0x400 to 0x41c */
+       struct {
+               u32 reserved          :16;
+#define fc_data_Tag_ID_DVB  0x3e
+#define fc_data_Tag_ID_ATSC 0x3f
+#define fc_data_Tag_ID_IDSB 0x8b
+               u32 data_Tag_ID       :16;
+       } data_tag_400;
+
+       struct {
+               u32 Card_IDbyte6      : 8;
+               u32 Card_IDbyte5      : 8;
+               u32 Card_IDbyte4      : 8;
+               u32 Card_IDbyte3      : 8;
+       } card_id_408;
+
+       struct {
+               u32 Card_IDbyte2      : 8;
+               u32 Card_IDbyte1      : 8;
+       } card_id_40c;
+
+       /* holding the unique mac address of the receiver which houses the FlexCopIII */
+       struct {
+               u32 MAC1              : 8;
+               u32 MAC2              : 8;
+               u32 MAC3              : 8;
+               u32 MAC6              : 8;
+       } mac_address_418;
+
+       struct {
+               u32 MAC7              : 8;
+               u32 MAC8              : 8;
+               u32 reserved          : 16;
+       } mac_address_41c;
+
+       struct {
+               u32 transmitter_data_byte : 8;
+               u32 ReceiveDataReady  : 1;
+               u32 ReceiveByteFrameError: 1;
+               u32 txbuffempty       : 1;
+               u32 reserved          :21;
+       } ci_600;
+
+       struct {
+               u32 pi_d              : 8;
+               u32 pi_ha             :20;
+               u32 pi_rw             : 1;
+               u32 pi_component_reg  : 3;
+       } pi_604;
+
+       struct {
+               u32 serialReset       : 1;
+               u32 oncecycle_read    : 1;
+               u32 Timer_Read_req    : 1;
+               u32 Timer_Load_req    : 1;
+               u32 timer_data        : 7;
+               u32 unused            : 1; /* ??? not mentioned in data book */
+               u32 Timer_addr        : 5;
+               u32 reserved          : 3;
+               u32 pcmcia_a_mod_pwr_n : 1;
+               u32 pcmcia_b_mod_pwr_n : 1;
+               u32 config_Done_stat  : 1;
+               u32 config_Init_stat  : 1;
+               u32 config_Prog_n     : 1;
+               u32 config_wr_n       : 1;
+               u32 config_cs_n       : 1;
+               u32 config_cclk       : 1;
+               u32 pi_CiMax_IRQ_n    : 1;
+               u32 pi_timeout_status : 1;
+               u32 pi_wait_n         : 1;
+               u32 pi_busy_n         : 1;
+       } pi_608;
+
+       struct {
+               u32 PID               :13;
+               u32 key_enable        : 1;
+#define fc_key_code_default 0x1
+#define fc_key_code_even    0x2
+#define fc_key_code_odd     0x3
+               u32 key_code          : 2;
+               u32 key_array_col     : 3;
+               u32 key_array_row     : 5;
+               u32 dvb_en            : 1; /* 0=TS bypasses the Descrambler */
+               u32 rw_flag           : 1;
+               u32 reserved          : 6;
+       } dvb_reg_60c;
+
+/* SRAM and Output Destination 0x700 to 0x714 */
+       struct {
+               u32 sram_addr         :15;
+               u32 sram_rw           : 1;   /* 0=write, 1=read */
+               u32 sram_data         : 8;
+               u32 sc_xfer_bit       : 1;
+               u32 reserved1         : 3;
+               u32 oe_pin_reg        : 1;
+               u32 ce_pin_reg        : 1;
+               u32 reserved2         : 1;
+               u32 start_sram_ibi    : 1;
+       } sram_ctrl_reg_700;
+
+       struct {
+               u32 net_addr_read     :16;
+               u32 net_addr_write    :16;
+       } net_buf_reg_704;
+
+       struct {
+               u32 cai_read          :11;
+               u32 reserved1         : 5;
+               u32 cai_write         :11;
+               u32 reserved2         : 6;
+               u32 cai_cnt           : 4;
+       } cai_buf_reg_708;
+
+       struct {
+               u32 cao_read          :11;
+               u32 reserved1         : 5;
+               u32 cap_write         :11;
+               u32 reserved2         : 6;
+               u32 cao_cnt           : 4;
+       } cao_buf_reg_70c;
+
+       struct {
+               u32 media_read        :11;
+               u32 reserved1         : 5;
+               u32 media_write       :11;
+               u32 reserved2         : 6;
+               u32 media_cnt         : 4;
+       } media_buf_reg_710;
+
+       struct {
+               u32 NET_Dest          : 2;
+               u32 CAI_Dest          : 2;
+               u32 CAO_Dest          : 2;
+               u32 MEDIA_Dest        : 2;
+               u32 net_ovflow_error  : 1;
+               u32 media_ovflow_error : 1;
+               u32 cai_ovflow_error  : 1;
+               u32 cao_ovflow_error  : 1;
+               u32 ctrl_usb_wan      : 1;
+               u32 ctrl_sramdma      : 1;
+               u32 ctrl_maximumfill  : 1;
+               u32 reserved          :17;
+       } sram_dest_reg_714;
+
+       struct {
+               u32 net_cnt           :12;
+               u32 reserved1         : 4;
+               u32 net_addr_read     : 1;
+               u32 reserved2         : 3;
+               u32 net_addr_write    : 1;
+               u32 reserved3         :11;
+       } net_buf_reg_718;
+
+       struct {
+               u32 wan_speed_sig     : 2;
+               u32 reserved1         : 6;
+               u32 wan_wait_state    : 8;
+               u32 sram_chip         : 2;
+               u32 sram_memmap       : 2;
+               u32 reserved2         : 4;
+               u32 wan_pkt_frame     : 4;
+               u32 reserved3         : 4;
+       } wan_ctrl_reg_71c;
+} flexcop_ibi_value;
+
+extern flexcop_ibi_value ibi_zero;
+
+typedef enum {
+       FC_I2C_PORT_DEMOD  = 1,
+       FC_I2C_PORT_EEPROM = 2,
+       FC_I2C_PORT_TUNER  = 3,
+} flexcop_i2c_port_t;
+
+typedef enum {
+       FC_WRITE = 0,
+       FC_READ  = 1,
+} flexcop_access_op_t;
+
+typedef enum {
+       FC_SRAM_DEST_NET   = 1,
+       FC_SRAM_DEST_CAI   = 2,
+       FC_SRAM_DEST_CAO   = 4,
+       FC_SRAM_DEST_MEDIA = 8
+} flexcop_sram_dest_t;
+
+typedef enum {
+       FC_SRAM_DEST_TARGET_WAN_USB = 0,
+       FC_SRAM_DEST_TARGET_DMA1    = 1,
+       FC_SRAM_DEST_TARGET_DMA2    = 2,
+       FC_SRAM_DEST_TARGET_FC3_CA  = 3
+} flexcop_sram_dest_target_t;
+
+typedef enum {
+       FC_SRAM_2_32KB  = 0, /*  64KB */
+       FC_SRAM_1_32KB  = 1, /*  32KB - default fow FCII */
+       FC_SRAM_1_128KB = 2, /* 128KB */
+       FC_SRAM_1_48KB  = 3, /*  48KB - default for FCIII */
+} flexcop_sram_type_t;
+
+typedef enum {
+       FC_WAN_SPEED_4MBITS  = 0,
+       FC_WAN_SPEED_8MBITS  = 1,
+       FC_WAN_SPEED_12MBITS = 2,
+       FC_WAN_SPEED_16MBITS = 3,
+} flexcop_wan_speed_t;
+
+typedef enum {
+       FC_DMA_1 = 1,
+       FC_DMA_2 = 2,
+} flexcop_dma_index_t;
+
+typedef enum {
+       FC_DMA_SUBADDR_0 = 1,
+       FC_DMA_SUBADDR_1 = 2,
+} flexcop_dma_addr_index_t;
+
+/* names of the particular registers */
+typedef enum {
+       dma1_000            = 0x000,
+       dma1_004            = 0x004,
+       dma1_008            = 0x008,
+       dma1_00c            = 0x00c,
+       dma2_010            = 0x010,
+       dma2_014            = 0x014,
+       dma2_018            = 0x018,
+       dma2_01c            = 0x01c,
+
+       tw_sm_c_100         = 0x100,
+       tw_sm_c_104         = 0x104,
+       tw_sm_c_108         = 0x108,
+       tw_sm_c_10c         = 0x10c,
+       tw_sm_c_110         = 0x110,
+
+       lnb_switch_freq_200 = 0x200,
+       misc_204            = 0x204,
+       ctrl_208            = 0x208,
+       irq_20c             = 0x20c,
+       sw_reset_210        = 0x210,
+       misc_214            = 0x214,
+       mbox_v8_to_host_218 = 0x218,
+       mbox_host_to_v8_21c = 0x21c,
+
+       pid_filter_300      = 0x300,
+       pid_filter_304      = 0x304,
+       pid_filter_308      = 0x308,
+       pid_filter_30c      = 0x30c,
+       index_reg_310       = 0x310,
+       pid_n_reg_314       = 0x314,
+       mac_low_reg_318     = 0x318,
+       mac_high_reg_31c    = 0x31c,
+
+       data_tag_400        = 0x400,
+       card_id_408         = 0x408,
+       card_id_40c         = 0x40c,
+       mac_address_418     = 0x418,
+       mac_address_41c     = 0x41c,
+
+       ci_600              = 0x600,
+       pi_604              = 0x604,
+       pi_608              = 0x608,
+       dvb_reg_60c         = 0x60c,
+
+       sram_ctrl_reg_700   = 0x700,
+       net_buf_reg_704     = 0x704,
+       cai_buf_reg_708     = 0x708,
+       cao_buf_reg_70c     = 0x70c,
+       media_buf_reg_710   = 0x710,
+       sram_dest_reg_714   = 0x714,
+       net_buf_reg_718     = 0x718,
+       wan_ctrl_reg_71c    = 0x71c,
+} flexcop_ibi_register;
+
+#define flexcop_set_ibi_value(reg,attr,val) { \
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,reg); \
+       v.reg.attr = val; \
+       fc->write_ibi_reg(fc,reg,v); \
+}
+
+#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-sram.c b/drivers/media/dvb/b2c2/flexcop-sram.c
new file mode 100644 (file)
index 0000000..01570ec
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-sram.c - functions for controlling the SRAM.
+ *
+ * see flexcop.c for copyright information.
+ */
+#include "flexcop.h"
+
+static void flexcop_sram_set_chip (struct flexcop_device *fc, flexcop_sram_type_t type)
+{
+       flexcop_set_ibi_value(wan_ctrl_reg_71c,sram_chip,type);
+}
+
+int flexcop_sram_init(struct flexcop_device *fc)
+{
+       switch (fc->rev) {
+               case FLEXCOP_II:
+               case FLEXCOP_IIB:
+                       flexcop_sram_set_chip(fc,FC_SRAM_1_32KB);
+                       break;
+               case FLEXCOP_III:
+                       flexcop_sram_set_chip(fc,FC_SRAM_1_48KB);
+                       break;
+               default:
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target)
+{
+       flexcop_ibi_value v;
+
+       v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+
+       if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
+               err("SRAM destination target to available on FlexCopII(b)\n");
+               return -EINVAL;
+       }
+
+       deb_sram("sram dest: %x target: %x\n",dest, target);
+
+       if (dest & FC_SRAM_DEST_NET)
+               v.sram_dest_reg_714.NET_Dest = target;
+       if (dest & FC_SRAM_DEST_CAI)
+               v.sram_dest_reg_714.CAI_Dest = target;
+       if (dest & FC_SRAM_DEST_CAO)
+               v.sram_dest_reg_714.CAO_Dest = target;
+       if (dest & FC_SRAM_DEST_MEDIA)
+               v.sram_dest_reg_714.MEDIA_Dest = target;
+
+       fc->write_ibi_reg(fc,sram_dest_reg_714,v);
+       udelay(1000); /* TODO delay really necessary */
+
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_sram_set_dest);
+
+void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s)
+{
+       flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s);
+}
+EXPORT_SYMBOL(flexcop_wan_set_speed);
+
+void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill)
+{
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+       v.sram_dest_reg_714.ctrl_usb_wan = usb_wan;
+       v.sram_dest_reg_714.ctrl_sramdma = sramdma;
+       v.sram_dest_reg_714.ctrl_maximumfill = maximumfill;
+       fc->write_ibi_reg(fc,sram_dest_reg_714,v);
+}
+EXPORT_SYMBOL(flexcop_sram_ctrl);
+
+#if 0
+static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
+{
+       int i, retries;
+       u32 command;
+
+       for (i = 0; i < len; i++) {
+               command = bank | addr | 0x04000000 | (*buf << 0x10);
+
+               retries = 2;
+
+               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
+                       mdelay(1);
+                       retries--;
+               };
+
+               if (retries == 0)
+                       printk("%s: SRAM timeout\n", __FUNCTION__);
+
+               write_reg_dw(adapter, 0x700, command);
+
+               buf++;
+               addr++;
+       }
+}
+
+static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
+{
+       int i, retries;
+       u32 command, value;
+
+       for (i = 0; i < len; i++) {
+               command = bank | addr | 0x04008000;
+
+               retries = 10000;
+
+               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
+                       mdelay(1);
+                       retries--;
+               };
+
+               if (retries == 0)
+                       printk("%s: SRAM timeout\n", __FUNCTION__);
+
+               write_reg_dw(adapter, 0x700, command);
+
+               retries = 10000;
+
+               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
+                       mdelay(1);
+                       retries--;
+               };
+
+               if (retries == 0)
+                       printk("%s: SRAM timeout\n", __FUNCTION__);
+
+               value = read_reg_dw(adapter, 0x700) >> 0x10;
+
+               *buf = (value & 0xff);
+
+               addr++;
+               buf++;
+       }
+}
+
+static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
+{
+       u32 bank;
+
+       bank = 0;
+
+       if (adapter->dw_sram_type == 0x20000) {
+               bank = (addr & 0x18000) << 0x0d;
+       }
+
+       if (adapter->dw_sram_type == 0x00000) {
+               if ((addr >> 0x0f) == 0)
+                       bank = 0x20000000;
+               else
+                       bank = 0x10000000;
+       }
+
+       flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
+}
+
+static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
+{
+       u32 bank;
+
+       bank = 0;
+
+       if (adapter->dw_sram_type == 0x20000) {
+               bank = (addr & 0x18000) << 0x0d;
+       }
+
+       if (adapter->dw_sram_type == 0x00000) {
+               if ((addr >> 0x0f) == 0)
+                       bank = 0x20000000;
+               else
+                       bank = 0x10000000;
+       }
+
+       flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
+}
+
+static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
+{
+       u32 length;
+
+       while (len != 0) {
+               length = len;
+
+               // check if the address range belongs to the same
+               // 32K memory chip. If not, the data is read from
+               // one chip at a time.
+               if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
+                       length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
+               }
+
+               sram_read_chunk(adapter, addr, buf, length);
+
+               addr = addr + length;
+               buf = buf + length;
+               len = len - length;
+       }
+}
+
+static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
+{
+       u32 length;
+
+       while (len != 0) {
+               length = len;
+
+               // check if the address range belongs to the same
+               // 32K memory chip. If not, the data is written to
+               // one chip at a time.
+               if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
+                       length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
+               }
+
+               sram_write_chunk(adapter, addr, buf, length);
+
+               addr = addr + length;
+               buf = buf + length;
+               len = len - length;
+       }
+}
+
+static void sram_set_size(struct adapter *adapter, u32 mask)
+{
+       write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
+}
+
+static void sram_init(struct adapter *adapter)
+{
+       u32 tmp;
+
+       tmp = read_reg_dw(adapter, 0x71c);
+
+       write_reg_dw(adapter, 0x71c, 1);
+
+       if (read_reg_dw(adapter, 0x71c) != 0) {
+               write_reg_dw(adapter, 0x71c, tmp);
+
+               adapter->dw_sram_type = tmp & 0x30000;
+
+               ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
+
+       } else {
+
+               adapter->dw_sram_type = 0x10000;
+
+               ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
+       }
+
+       /* return value is never used? */
+/*     return adapter->dw_sram_type; */
+}
+
+static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
+{
+       u8 tmp1, tmp2;
+
+       dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr);
+
+       sram_set_size(adapter, mask);
+       sram_init(adapter);
+
+       tmp2 = 0xa5;
+       tmp1 = 0x4f;
+
+       sram_write(adapter, addr, &tmp2, 1);
+       sram_write(adapter, addr + 4, &tmp1, 1);
+
+       tmp2 = 0;
+
+       mdelay(20);
+
+       sram_read(adapter, addr, &tmp2, 1);
+       sram_read(adapter, addr, &tmp2, 1);
+
+       dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2);
+
+       if (tmp2 != 0xa5)
+               return 0;
+
+       tmp2 = 0x5a;
+       tmp1 = 0xf4;
+
+       sram_write(adapter, addr, &tmp2, 1);
+       sram_write(adapter, addr + 4, &tmp1, 1);
+
+       tmp2 = 0;
+
+       mdelay(20);
+
+       sram_read(adapter, addr, &tmp2, 1);
+       sram_read(adapter, addr, &tmp2, 1);
+
+       dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2);
+
+       if (tmp2 != 0x5a)
+               return 0;
+
+       return 1;
+}
+
+static u32 sram_length(struct adapter *adapter)
+{
+       if (adapter->dw_sram_type == 0x10000)
+               return 32768;   //  32K
+       if (adapter->dw_sram_type == 0x00000)
+               return 65536;   //  64K
+       if (adapter->dw_sram_type == 0x20000)
+               return 131072;  // 128K
+
+       return 32768;           // 32K
+}
+
+/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
+    - for 128K there are 4x32K chips at bank 0,1,2,3.
+    - for  64K there are 2x32K chips at bank 1,2.
+    - for  32K there is one 32K chip at bank 0.
+
+   FlexCop works only with one bank at a time. The bank is selected
+   by bits 28-29 of the 0x700 register.
+
+   bank 0 covers addresses 0x00000-0x07fff
+   bank 1 covers addresses 0x08000-0x0ffff
+   bank 2 covers addresses 0x10000-0x17fff
+   bank 3 covers addresses 0x18000-0x1ffff
+*/
+
+static int flexcop_sram_detect(struct flexcop_device *fc)
+{
+       flexcop_ibi_value r208,r71c_0,vr71c_1;
+
+       r208 = fc->read_ibi_reg(fc, ctrl_208);
+       fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
+
+       r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
+
+       write_reg_dw(adapter, 0x71c, 1);
+
+       tmp3 = read_reg_dw(adapter, 0x71c);
+
+       dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
+
+       write_reg_dw(adapter, 0x71c, tmp2);
+
+       // check for internal SRAM ???
+       tmp3--;
+       if (tmp3 != 0) {
+               sram_set_size(adapter, 0x10000);
+               sram_init(adapter);
+               write_reg_dw(adapter, 0x208, tmp);
+
+               dprintk("%s: sram size = 32K\n", __FUNCTION__);
+
+               return 32;
+       }
+
+       if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
+               sram_set_size(adapter, 0x20000);
+               sram_init(adapter);
+               write_reg_dw(adapter, 0x208, tmp);
+
+               dprintk("%s: sram size = 128K\n", __FUNCTION__);
+
+               return 128;
+       }
+
+       if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
+               sram_set_size(adapter, 0x00000);
+               sram_init(adapter);
+               write_reg_dw(adapter, 0x208, tmp);
+
+               dprintk("%s: sram size = 64K\n", __FUNCTION__);
+
+               return 64;
+       }
+
+       if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
+               sram_set_size(adapter, 0x10000);
+               sram_init(adapter);
+               write_reg_dw(adapter, 0x208, tmp);
+
+               dprintk("%s: sram size = 32K\n", __FUNCTION__);
+
+               return 32;
+       }
+
+       sram_set_size(adapter, 0x10000);
+       sram_init(adapter);
+       write_reg_dw(adapter, 0x208, tmp);
+
+       dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__);
+
+       return 0;
+}
+
+static void sll_detect_sram_size(struct adapter *adapter)
+{
+       sram_detect_for_flex2(adapter);
+}
+
+#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
new file mode 100644 (file)
index 0000000..0113449
--- /dev/null
@@ -0,0 +1,577 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop-usb.c - covers the USB part.
+ *
+ * see flexcop.c for copyright information.
+ */
+
+#define FC_LOG_PREFIX "flexcop_usb"
+#include "flexcop-usb.h"
+#include "flexcop-common.h"
+
+/* Version information */
+#define DRIVER_VERSION "0.1"
+#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV USB Driver"
+#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
+
+/* debug */
+#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
+#define dprintk(level,args...) \
+           do { if ((debug & level)) { printk(args); } } while (0)
+#define debug_dump(b,l,method) {\
+       int i; \
+       for (i = 0; i < l; i++) method("%02x ", b[i]); \
+       method("\n");\
+}
+
+#define DEBSTATUS ""
+#else
+#define dprintk(level,args...)
+#define debug_dump(b,l,method)
+#define DEBSTATUS " (debugging is not enabled)"
+#endif
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
+#undef DEBSTATUS
+
+#define deb_info(args...) dprintk(0x01,args)
+#define deb_ts(args...)   dprintk(0x02,args)
+#define deb_ctrl(args...) dprintk(0x04,args)
+#define deb_i2c(args...)  dprintk(0x08,args)
+#define deb_v8(args...)   dprintk(0x10,args)
+
+/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
+ * in the IBI address, to make the V8 code simpler.
+ * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
+ *                  in general: 0000 0HHH 000L LL00
+ * IBI ADDRESS FORMAT:                    RHHH BLLL
+ *
+ * where R is the read(1)/write(0) bit, B is the busy bit
+ * and HHH and LLL are the two sets of three bits from the PCI address.
+ */
+#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
+#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
+
+/*
+ * DKT 020228
+ * - forget about this VENDOR_BUFFER_SIZE, read and write register
+ *   deal with DWORD or 4 bytes, that should be should from now on
+ * - from now on, we don't support anything older than firm 1.00
+ *   I eliminated the write register as a 2 trip of writing hi word and lo word
+ *   and force this to write only 4 bytes at a time.
+ *   NOTE: this should work with all the firmware from 1.00 and newer
+ */
+static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, u32 *val, u8 read)
+{
+       struct flexcop_usb *fc_usb = fc->bus_specific;
+       u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG;
+       u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
+       u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | (read ? 0x80 : 0);
+
+       int len = usb_control_msg(fc_usb->udev,
+                       read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
+                       request,
+                       request_type,  /* 0xc0 read or 0x40 write*/
+                       wAddress,
+                       0,
+                       val,
+                       sizeof(u32),
+                       B2C2_WAIT_FOR_OPERATION_RDW * HZ);
+
+       if (len != sizeof(u32)) {
+               err("error while %s dword from %d (%d).",read ? "reading" : "writing",
+                       wAddress,wRegOffsPCI);
+               return -EIO;
+       }
+       return 0;
+}
+
+/*
+ * DKT 010817 - add support for V8 memory read/write and flash update
+ */
+static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
+               flexcop_usb_request_t req, u8 page, u16 wAddress,
+               u8 *pbBuffer,u32 buflen)
+{
+//     u8 dwRequestType;
+       u8 request_type = USB_TYPE_VENDOR;
+       u16 wIndex;
+       int nWaitTime,pipe,len;
+
+       wIndex = page << 8;
+
+       switch (req) {
+               case B2C2_USB_READ_V8_MEM:
+                       nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
+                       request_type |= USB_DIR_IN;
+//                     dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
+                       pipe = B2C2_USB_CTRL_PIPE_IN;
+               break;
+               case B2C2_USB_WRITE_V8_MEM:
+                       wIndex |= pbBuffer[0];
+                       request_type |= USB_DIR_OUT;
+                       nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
+//                     dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
+                       pipe = B2C2_USB_CTRL_PIPE_OUT;
+               break;
+               case B2C2_USB_FLASH_BLOCK:
+                       request_type |= USB_DIR_OUT;
+                       nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
+//                     dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
+                       pipe = B2C2_USB_CTRL_PIPE_OUT;
+               break;
+               default:
+                       deb_info("unsupported request for v8_mem_req %x.\n",req);
+               return -EINVAL;
+       }
+       deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n",request_type,req,
+                       wAddress,wIndex,buflen);
+
+       len = usb_control_msg(fc_usb->udev,pipe,
+                       req,
+                       request_type,
+                       wAddress,
+                       wIndex,
+                       pbBuffer,
+                       buflen,
+                       nWaitTime * HZ);
+
+       debug_dump(pbBuffer,len,deb_v8);
+
+       return len == buflen ? 0 : -EIO;
+}
+
+#define bytes_left_to_read_on_page(paddr,buflen) \
+                       ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
+                       ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
+
+static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request_t req,
+               flexcop_usb_mem_page_t page_start, u32 addr, int extended, u8 *buf, u32 len)
+{
+       int i,ret = 0;
+       u16 wMax;
+       u32 pagechunk = 0;
+
+       switch(req) {
+               case B2C2_USB_READ_V8_MEM:  wMax = USB_MEM_READ_MAX; break;
+               case B2C2_USB_WRITE_V8_MEM:     wMax = USB_MEM_WRITE_MAX; break;
+               case B2C2_USB_FLASH_BLOCK:  wMax = USB_FLASH_MAX; break;
+               default:
+                       return -EINVAL;
+               break;
+       }
+       for (i = 0; i < len;) {
+               pagechunk = wMax < bytes_left_to_read_on_page(addr,len) ? wMax : bytes_left_to_read_on_page(addr,len);
+               deb_info("%x\n",(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended));
+               if ((ret = flexcop_usb_v8_memory_req(fc_usb,req,
+                               page_start + (addr / V8_MEMORY_PAGE_SIZE), /* actual page */
+                               (addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended),
+                               &buf[i],pagechunk)) < 0)
+                       return ret;
+
+               addr += pagechunk;
+               len -= pagechunk;
+       }
+       return 0;
+}
+
+static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
+{
+       return flexcop_usb_memory_req(fc->bus_specific,B2C2_USB_READ_V8_MEM,
+                       V8_MEMORY_PAGE_FLASH,0x1f010,1,fc->dvb_adapter.proposed_mac,6);
+}
+
+#if 0
+static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
+               flexcop_usb_utility_function_t func, u8 extra, u16 wIndex,
+               u16 buflen, u8 *pvBuffer)
+{
+       u16 wValue;
+       u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
+//     u8 dwRequestType = (u8) RTYPE_GENERIC,
+       int nWaitTime = 2,
+               pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
+               len;
+
+       wValue = (func << 8) | extra;
+
+       len = usb_control_msg(fc_usb->udev,pipe,
+                       B2C2_USB_UTILITY,
+                       request_type,
+                       wValue,
+                       wIndex,
+                       pvBuffer,
+                       buflen,
+                       nWaitTime * HZ);
+       return len == buflen ? 0 : -EIO;
+}
+#endif
+
+/* usb i2c stuff */
+static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb,
+               flexcop_usb_request_t req, flexcop_usb_i2c_function_t func,
+               flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u8 buflen)
+{
+       u16 wValue, wIndex;
+       int nWaitTime,pipe,len;
+//     u8 dwRequestType;
+       u8 request_type = USB_TYPE_VENDOR;
+
+       switch (func) {
+               case USB_FUNC_I2C_WRITE:
+               case USB_FUNC_I2C_MULTIWRITE:
+               case USB_FUNC_I2C_REPEATWRITE:
+               /* DKT 020208 - add this to support special case of DiSEqC */
+               case USB_FUNC_I2C_CHECKWRITE:
+                       pipe = B2C2_USB_CTRL_PIPE_OUT;
+                       nWaitTime = 2;
+//                     dwRequestType = (u8) RTYPE_GENERIC;
+                       request_type |= USB_DIR_OUT;
+               break;
+               case USB_FUNC_I2C_READ:
+               case USB_FUNC_I2C_REPEATREAD:
+                       pipe = B2C2_USB_CTRL_PIPE_IN;
+                       nWaitTime = 2;
+//                     dwRequestType = (u8) RTYPE_GENERIC;
+                       request_type |= USB_DIR_IN;
+               break;
+               default:
+                       deb_info("unsupported function for i2c_req %x\n",func);
+                       return -EINVAL;
+       }
+       wValue = (func << 8 ) | (port << 4);
+       wIndex = (chipaddr << 8 ) | addr;
+
+       deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req,
+                       ((wValue && 0xff) << 8),wValue >> 8,((wIndex && 0xff) << 8),wIndex >> 8);
+
+       len = usb_control_msg(fc_usb->udev,pipe,
+                       req,
+                       request_type,
+                       wValue,
+                       wIndex,
+                       buf,
+                       buflen,
+                       nWaitTime * HZ);
+
+       return len == buflen ? 0 : -EREMOTEIO;
+}
+
+/* actual bus specific access functions, make sure prototype are/will be equal to pci */
+static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg)
+{
+       flexcop_ibi_value val;
+       val.raw = 0;
+       flexcop_usb_readwrite_dw(fc,reg, &val.raw, 1);
+       return val;
+}
+
+static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg, flexcop_ibi_value val)
+{
+       return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0);
+}
+
+static int flexcop_usb_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op,
+               flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+{
+       if (op == FC_READ)
+               return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_READ,port,chipaddr,addr,buf,len);
+       else
+               return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_WRITE,port,chipaddr,addr,buf,len);
+}
+
+static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length)
+{
+       u8 *b;
+       int l;
+
+       deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length);
+
+       if (fc_usb->tmp_buffer_length > 0) {
+               memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length);
+               fc_usb->tmp_buffer_length += buffer_length;
+               b = fc_usb->tmp_buffer;
+               l = fc_usb->tmp_buffer_length;
+       } else {
+               b=buffer;
+               l=buffer_length;
+       }
+
+       while (l >= 190) {
+               if (*b == 0xff)
+                       switch (*(b+1) & 0x03) {
+                               case 0x01: /* media packet */
+                                       if ( *(b+2) == 0x47 )
+                                               flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1);
+                                       else
+                                               deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) );
+
+                                       b += 190;
+                                       l -= 190;
+                               break;
+                               default:
+                                       deb_ts("wrong packet type\n");
+                                       l = 0;
+                               break;
+                       }
+               else {
+                       deb_ts("wrong header\n");
+                       l = 0;
+               }
+       }
+
+       if (l>0)
+               memcpy(fc_usb->tmp_buffer, b, l);
+       fc_usb->tmp_buffer_length = l;
+}
+
+static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+{
+       struct flexcop_usb *fc_usb = urb->context;
+       int i;
+
+       if (urb->actual_length > 0)
+               deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length);
+
+       for (i = 0; i < urb->number_of_packets; i++) {
+               if (urb->iso_frame_desc[i].status < 0) {
+                       err("iso frame descriptor %d has an error: %d\n",i,urb->iso_frame_desc[i].status);
+               } else
+                       if (urb->iso_frame_desc[i].actual_length > 0) {
+                               deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length);
+
+                               flexcop_usb_process_frame(fc_usb,
+                                       urb->transfer_buffer + urb->iso_frame_desc[i].offset,
+                                       urb->iso_frame_desc[i].actual_length);
+               }
+               urb->iso_frame_desc[i].status = 0;
+               urb->iso_frame_desc[i].actual_length = 0;
+       }
+
+       usb_submit_urb(urb,GFP_ATOMIC);
+}
+
+static int flexcop_usb_stream_control(struct flexcop_device *fc, int onoff)
+{
+       /* submit/kill iso packets */
+       return 0;
+}
+
+static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb)
+{
+       int i;
+       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
+               if (fc_usb->iso_urb[i] != NULL) {
+                       deb_ts("unlinking/killing urb no. %d\n",i);
+                       usb_kill_urb(fc_usb->iso_urb[i]);
+                       usb_free_urb(fc_usb->iso_urb[i]);
+               }
+
+       if (fc_usb->iso_buffer != NULL)
+               pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr);
+}
+
+static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
+{
+       u16 frame_size = fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize;
+       int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
+       int buffer_offset = 0;
+
+       deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
+                       B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
+
+       fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr);
+       if (fc_usb->iso_buffer == NULL)
+               return -ENOMEM;
+       memset(fc_usb->iso_buffer, 0, bufsize);
+       fc_usb->buffer_size = bufsize;
+
+       /* creating iso urbs */
+       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
+               if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
+                       ret = -ENOMEM;
+                       goto urb_error;
+               }
+       /* initialising and submitting iso urbs */
+       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
+               int frame_offset = 0;
+               struct urb *urb = fc_usb->iso_urb[i];
+               deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
+
+               urb->dev = fc_usb->udev;
+               urb->context = fc_usb;
+               urb->complete = flexcop_usb_urb_complete;
+               urb->pipe = B2C2_USB_DATA_PIPE;
+               urb->transfer_flags = URB_ISO_ASAP;
+               urb->interval = 1;
+               urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO;
+               urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO;
+               urb->transfer_buffer = fc_usb->iso_buffer + buffer_offset;
+
+               buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
+               for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
+                       deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
+                       urb->iso_frame_desc[j].offset = frame_offset;
+                       urb->iso_frame_desc[j].length = frame_size;
+                       frame_offset += frame_size;
+               }
+
+               if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) {
+                       err("submitting urb %d failed with %d.",i,ret);
+                       goto urb_error;
+               }
+               deb_ts("submitted urb no. %d.\n",i);
+       }
+
+/* SRAM */
+
+       flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET |
+                       FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB);
+       flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS);
+       flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1);
+
+       ret = 0;
+       goto success;
+urb_error:
+       flexcop_usb_transfer_exit(fc_usb);
+success:
+       return ret;
+}
+
+static int flexcop_usb_init(struct flexcop_usb *fc_usb)
+{
+       /* use the alternate setting with the larges buffer */
+       usb_set_interface(fc_usb->udev,0,1);
+       switch (fc_usb->udev->speed) {
+               case USB_SPEED_LOW:
+                       err("cannot handle USB speed because it is to sLOW.");
+                       return -ENODEV;
+                       break;
+               case USB_SPEED_FULL:
+                       info("running at FULL speed.");
+                       break;
+               case USB_SPEED_HIGH:
+                       info("running at HIGH speed.");
+                       break;
+               case USB_SPEED_UNKNOWN: /* fall through */
+               default:
+                       err("cannot handle USB speed because it is unkown.");
+                       return -ENODEV;
+       }
+       usb_set_intfdata(fc_usb->uintf, fc_usb);
+       return 0;
+}
+
+static void flexcop_usb_exit(struct flexcop_usb *fc_usb)
+{
+       usb_set_intfdata(fc_usb->uintf, NULL);
+}
+
+static int flexcop_usb_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct flexcop_usb *fc_usb = NULL;
+       struct flexcop_device *fc = NULL;
+       int ret;
+
+       if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {
+               err("out of memory\n");
+               return -ENOMEM;
+       }
+
+/* general flexcop init */
+       fc_usb = fc->bus_specific;
+       fc_usb->fc_dev = fc;
+
+       fc->read_ibi_reg  = flexcop_usb_read_ibi_reg;
+       fc->write_ibi_reg = flexcop_usb_write_ibi_reg;
+       fc->i2c_request = flexcop_usb_i2c_request;
+       fc->get_mac_addr = flexcop_usb_get_mac_addr;
+
+       fc->stream_control = flexcop_usb_stream_control;
+
+       fc->pid_filtering = 1;
+       fc->bus_type = FC_USB;
+
+       fc->dev = &udev->dev;
+       fc->owner = THIS_MODULE;
+
+/* bus specific part */
+       fc_usb->udev = udev;
+       fc_usb->uintf = intf;
+       if ((ret = flexcop_usb_init(fc_usb)) != 0)
+               goto err_kfree;
+
+/* init flexcop */
+       if ((ret = flexcop_device_initialize(fc)) != 0)
+               goto err_usb_exit;
+
+/* xfer init */
+       if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)
+               goto err_fc_exit;
+
+       info("%s successfully initialized and connected.",DRIVER_NAME);
+       ret = 0;
+       goto success;
+err_fc_exit:
+       flexcop_device_exit(fc);
+err_usb_exit:
+       flexcop_usb_exit(fc_usb);
+err_kfree:
+       flexcop_device_kfree(fc);
+success:
+       return ret;
+}
+
+static void flexcop_usb_disconnect(struct usb_interface *intf)
+{
+       struct flexcop_usb *fc_usb = usb_get_intfdata(intf);
+       flexcop_usb_transfer_exit(fc_usb);
+       flexcop_device_exit(fc_usb->fc_dev);
+       flexcop_usb_exit(fc_usb);
+       flexcop_device_kfree(fc_usb->fc_dev);
+       info("%s successfully deinitialized and disconnected.",DRIVER_NAME);
+}
+
+static struct usb_device_id flexcop_usb_table [] = {
+           { USB_DEVICE(0x0af7, 0x0101) },
+           { }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver flexcop_usb_driver = {
+       .owner          = THIS_MODULE,
+       .name           = "Technisat/B2C2 FlexCop II/IIb/III USB",
+       .probe          = flexcop_usb_probe,
+       .disconnect = flexcop_usb_disconnect,
+       .id_table       = flexcop_usb_table,
+};
+
+/* module stuff */
+static int __init flexcop_usb_module_init(void)
+{
+       int result;
+       if ((result = usb_register(&flexcop_usb_driver))) {
+               err("usb_register failed. (%d)",result);
+               return result;
+       }
+
+       return 0;
+}
+
+static void __exit flexcop_usb_module_exit(void)
+{
+       /* deregister this driver from the USB subsystem */
+       usb_deregister(&flexcop_usb_driver);
+}
+
+module_init(flexcop_usb_module_init);
+module_exit(flexcop_usb_module_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_NAME);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/dvb/b2c2/flexcop-usb.h
new file mode 100644 (file)
index 0000000..630e647
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef __FLEXCOP_USB_H_INCLUDED__
+#define __FLEXCOP_USB_H_INCLUDED__
+
+#include <linux/usb.h>
+
+/* transfer parameters */
+#define B2C2_USB_FRAMES_PER_ISO                4
+#define B2C2_USB_NUM_ISO_URB           4
+
+#define B2C2_USB_CTRL_PIPE_IN          usb_rcvctrlpipe(fc_usb->udev,0)
+#define B2C2_USB_CTRL_PIPE_OUT         usb_sndctrlpipe(fc_usb->udev,0)
+#define B2C2_USB_DATA_PIPE                     usb_rcvisocpipe(fc_usb->udev,0x81)
+
+struct flexcop_usb {
+       struct usb_device *udev;
+       struct usb_interface *uintf;
+
+       u8 *iso_buffer;
+       int buffer_size;
+       dma_addr_t dma_addr;
+       struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
+
+       struct flexcop_device *fc_dev;
+
+       u8 tmp_buffer[1023+190];
+       int tmp_buffer_length;
+};
+
+#if 0
+/* request types TODO What is its use?*/
+typedef enum {
+
+/* something is wrong with this part
+       RTYPE_READ_DW         = (1 << 6),
+       RTYPE_WRITE_DW_1      = (3 << 6),
+       RTYPE_READ_V8_MEMORY  = (6 << 6),
+       RTYPE_WRITE_V8_MEMORY = (7 << 6),
+       RTYPE_WRITE_V8_FLASH  = (8 << 6),
+       RTYPE_GENERIC         = (9 << 6),
+*/
+} flexcop_usb_request_type_t;
+#endif
+
+/* request */
+typedef enum {
+       B2C2_USB_WRITE_V8_MEM = 0x04,
+       B2C2_USB_READ_V8_MEM  = 0x05,
+       B2C2_USB_READ_REG     = 0x08,
+       B2C2_USB_WRITE_REG    = 0x0A,
+/*     B2C2_USB_WRITEREGLO   = 0x0A, */
+       B2C2_USB_WRITEREGHI   = 0x0B,
+       B2C2_USB_FLASH_BLOCK  = 0x10,
+       B2C2_USB_I2C_REQUEST  = 0x11,
+       B2C2_USB_UTILITY      = 0x12,
+} flexcop_usb_request_t;
+
+/* function definition for I2C_REQUEST */
+typedef enum {
+       USB_FUNC_I2C_WRITE       = 0x01,
+       USB_FUNC_I2C_MULTIWRITE  = 0x02,
+       USB_FUNC_I2C_READ        = 0x03,
+       USB_FUNC_I2C_REPEATWRITE = 0x04,
+       USB_FUNC_GET_DESCRIPTOR  = 0x05,
+       USB_FUNC_I2C_REPEATREAD  = 0x06,
+/* DKT 020208 - add this to support special case of DiSEqC */
+       USB_FUNC_I2C_CHECKWRITE  = 0x07,
+       USB_FUNC_I2C_CHECKRESULT = 0x08,
+} flexcop_usb_i2c_function_t;
+
+/*
+ * function definition for UTILITY request 0x12
+ * DKT 020304 - new utility function
+ */
+typedef enum {
+       UTILITY_SET_FILTER          = 0x01,
+       UTILITY_DATA_ENABLE         = 0x02,
+       UTILITY_FLEX_MULTIWRITE     = 0x03,
+       UTILITY_SET_BUFFER_SIZE     = 0x04,
+       UTILITY_FLEX_OPERATOR       = 0x05,
+       UTILITY_FLEX_RESET300_START = 0x06,
+       UTILITY_FLEX_RESET300_STOP  = 0x07,
+       UTILITY_FLEX_RESET300       = 0x08,
+       UTILITY_SET_ISO_SIZE        = 0x09,
+       UTILITY_DATA_RESET          = 0x0A,
+       UTILITY_GET_DATA_STATUS     = 0x10,
+       UTILITY_GET_V8_REG          = 0x11,
+/* DKT 020326 - add function for v1.14 */
+       UTILITY_SRAM_WRITE          = 0x12,
+       UTILITY_SRAM_READ           = 0x13,
+       UTILITY_SRAM_TESTFILL       = 0x14,
+       UTILITY_SRAM_TESTSET        = 0x15,
+       UTILITY_SRAM_TESTVERIFY     = 0x16,
+} flexcop_usb_utility_function_t;
+
+#define B2C2_WAIT_FOR_OPERATION_RW  1*HZ       /* 1 s */
+#define B2C2_WAIT_FOR_OPERATION_RDW 3*HZ       /* 3 s */
+#define B2C2_WAIT_FOR_OPERATION_WDW 1*HZ       /* 1 s */
+
+#define B2C2_WAIT_FOR_OPERATION_V8READ   3*HZ  /* 3 s */
+#define B2C2_WAIT_FOR_OPERATION_V8WRITE  3*HZ  /* 3 s */
+#define B2C2_WAIT_FOR_OPERATION_V8FLASH  3*HZ  /* 3 s */
+
+typedef enum {
+       V8_MEMORY_PAGE_DVB_CI = 0x20,
+       V8_MEMORY_PAGE_DVB_DS = 0x40,
+       V8_MEMORY_PAGE_MULTI2 = 0x60,
+       V8_MEMORY_PAGE_FLASH  = 0x80
+} flexcop_usb_mem_page_t;
+
+#define V8_MEMORY_EXTENDED      (1 << 15)
+
+#define USB_MEM_READ_MAX                32
+#define USB_MEM_WRITE_MAX               1
+#define USB_FLASH_MAX                   8
+
+#define V8_MEMORY_PAGE_SIZE     0x8000      // 32K
+#define V8_MEMORY_PAGE_MASK     0x7FFF
+
+#endif
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
new file mode 100644 (file)
index 0000000..8b5d14d
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * flexcop.c - driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * based on the skystar2-driver
+ * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
+ *
+ * Acknowledgements:
+ *     John Jurrius from BBTI, Inc. for extensive support with
+ *         code examples and data books
+ *
+ *     Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
+ *
+ * Contributions to the skystar2-driver have been done by
+ *     Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
+ *     Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
+ *     Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac filtering)
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 "flexcop.h"
+
+#define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip"
+#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de"
+
+#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
+#define DEBSTATUS ""
+#else
+#define DEBSTATUS " (debugging is not enabled)"
+#endif
+
+int b2c2_flexcop_debug;
+module_param_named(debug, b2c2_flexcop_debug,  int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram (|-able))." DEBSTATUS);
+#undef DEBSTATUS
+
+/* global zero for ibi values */
+flexcop_ibi_value ibi_zero;
+
+static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct flexcop_device *fc = dvbdmxfeed->demux->priv;
+       return flexcop_pid_feed_control(fc,dvbdmxfeed,1);
+}
+
+static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct flexcop_device *fc = dvbdmxfeed->demux->priv;
+       return flexcop_pid_feed_control(fc,dvbdmxfeed,0);
+}
+
+static int flexcop_dvb_init(struct flexcop_device *fc)
+{
+       int ret;
+       if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner)) < 0) {
+               err("error registering DVB adapter");
+               return ret;
+       }
+       fc->dvb_adapter.priv = fc;
+
+       fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
+       fc->demux.priv = fc;
+
+       fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
+
+       fc->demux.start_feed = flexcop_dvb_start_feed;
+       fc->demux.stop_feed = flexcop_dvb_stop_feed;
+       fc->demux.write_to_decoder = NULL;
+
+       if ((ret = dvb_dmx_init(&fc->demux)) < 0) {
+               err("dvb_dmx failed: error %d",ret);
+               goto err_dmx;
+       }
+
+       fc->hw_frontend.source = DMX_FRONTEND_0;
+
+       fc->dmxdev.filternum = fc->demux.feednum;
+       fc->dmxdev.demux = &fc->demux.dmx;
+       fc->dmxdev.capabilities = 0;
+       if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) {
+               err("dvb_dmxdev_init failed: error %d",ret);
+               goto err_dmx_dev;
+       }
+
+       if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
+               err("adding hw_frontend to dmx failed: error %d",ret);
+               goto err_dmx_add_hw_frontend;
+       }
+
+       fc->mem_frontend.source = DMX_MEMORY_FE;
+       if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) {
+               err("adding mem_frontend to dmx failed: error %d",ret);
+               goto err_dmx_add_mem_frontend;
+       }
+
+       if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
+               err("connect frontend failed: error %d",ret);
+               goto err_connect_frontend;
+       }
+
+       dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx);
+
+       fc->init_state |= FC_STATE_DVB_INIT;
+       goto success;
+
+err_connect_frontend:
+       fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
+err_dmx_add_mem_frontend:
+       fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+err_dmx_add_hw_frontend:
+       dvb_dmxdev_release(&fc->dmxdev);
+err_dmx_dev:
+       dvb_dmx_release(&fc->demux);
+err_dmx:
+       dvb_unregister_adapter(&fc->dvb_adapter);
+       return ret;
+
+success:
+       return 0;
+}
+
+static void flexcop_dvb_exit(struct flexcop_device *fc)
+{
+       if (fc->init_state & FC_STATE_DVB_INIT) {
+               dvb_net_release(&fc->dvbnet);
+
+               fc->demux.dmx.close(&fc->demux.dmx);
+               fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
+               fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+               dvb_dmxdev_release(&fc->dmxdev);
+               dvb_dmx_release(&fc->demux);
+               dvb_unregister_adapter(&fc->dvb_adapter);
+
+               deb_info("deinitialized dvb stuff\n");
+       }
+       fc->init_state &= ~FC_STATE_DVB_INIT;
+}
+
+/* these methods are necessary to achieve the long-term-goal of hiding the
+ * struct flexcop_device from the bus-parts */
+void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len)
+{
+       dvb_dmx_swfilter(&fc->demux, buf, len);
+}
+EXPORT_SYMBOL(flexcop_pass_dmx_data);
+
+void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no)
+{
+       dvb_dmx_swfilter_packets(&fc->demux, buf, no);
+}
+EXPORT_SYMBOL(flexcop_pass_dmx_packets);
+
+static void flexcop_reset(struct flexcop_device *fc)
+{
+       flexcop_ibi_value v210,v204;
+
+/* reset the flexcop itself */
+       fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
+
+       v210.raw = 0;
+       v210.sw_reset_210.reset_blocks = 0xff;
+       v210.sw_reset_210.Block_reset_enable = 0xb2;
+       fc->write_ibi_reg(fc,sw_reset_210,v210);
+
+/* reset the periphical devices */
+
+       v204 = fc->read_ibi_reg(fc,misc_204);
+       v204.misc_204.Per_reset_sig = 0;
+       fc->write_ibi_reg(fc,misc_204,v204);
+       v204.misc_204.Per_reset_sig = 1;
+       fc->write_ibi_reg(fc,misc_204,v204);
+}
+
+struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
+{
+       void *bus;
+       struct flexcop_device *fc = kmalloc(sizeof(struct flexcop_device), GFP_KERNEL);
+       if (!fc) {
+               err("no memory");
+               return NULL;
+       }
+       memset(fc, 0, sizeof(struct flexcop_device));
+
+       bus = kmalloc(bus_specific_len, GFP_KERNEL);
+       if (!bus) {
+               err("no memory");
+               kfree(fc);
+               return NULL;
+       }
+       memset(bus, 0, bus_specific_len);
+
+       fc->bus_specific = bus;
+
+       return fc;
+}
+EXPORT_SYMBOL(flexcop_device_kmalloc);
+
+void flexcop_device_kfree(struct flexcop_device *fc)
+{
+       kfree(fc->bus_specific);
+       kfree(fc);
+}
+EXPORT_SYMBOL(flexcop_device_kfree);
+
+int flexcop_device_initialize(struct flexcop_device *fc)
+{
+       int ret;
+       ibi_zero.raw = 0;
+
+       flexcop_reset(fc);
+       flexcop_determine_revision(fc);
+       flexcop_sram_init(fc);
+       flexcop_hw_filter_init(fc);
+
+       flexcop_smc_ctrl(fc, 0);
+
+       if ((ret = flexcop_dvb_init(fc)))
+               goto error;
+
+       /* do the MAC address reading after initializing the dvb_adapter */
+       if (fc->get_mac_addr(fc, 0) == 0) {
+               u8 *b = fc->dvb_adapter.proposed_mac;
+               info("MAC address = %02x:%02x:%02x:%02x:%02x:%02x", b[0],b[1],b[2],b[3],b[4],b[5]);
+               flexcop_set_mac_filter(fc,b);
+               flexcop_mac_filter_ctrl(fc,1);
+       } else
+               warn("reading of MAC address failed.\n");
+
+
+       if ((ret = flexcop_i2c_init(fc)))
+               goto error;
+
+       if ((ret = flexcop_frontend_init(fc)))
+               goto error;
+
+       flexcop_device_name(fc,"initialization of","complete");
+
+       ret = 0;
+       goto success;
+error:
+       flexcop_device_exit(fc);
+success:
+       return ret;
+}
+EXPORT_SYMBOL(flexcop_device_initialize);
+
+void flexcop_device_exit(struct flexcop_device *fc)
+{
+       flexcop_frontend_exit(fc);
+       flexcop_i2c_exit(fc);
+       flexcop_dvb_exit(fc);
+}
+EXPORT_SYMBOL(flexcop_device_exit);
+
+static int flexcop_module_init(void)
+{
+       info(DRIVER_NAME " loaded successfully");
+       return 0;
+}
+
+static void flexcop_module_cleanup(void)
+{
+       info(DRIVER_NAME " unloaded successfully");
+}
+
+module_init(flexcop_module_init);
+module_exit(flexcop_module_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_NAME);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h
new file mode 100644 (file)
index 0000000..caa343a
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * flexcop.h - private header file for all flexcop-chip-source files.
+ *
+ * see flexcop.c for copyright information.
+ */
+#ifndef __FLEXCOP_H__
+#define __FLEXCOP_H___
+
+#define FC_LOG_PREFIX "b2c2-flexcop"
+#include "flexcop-common.h"
+
+extern int b2c2_flexcop_debug;
+
+/* debug */
+#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
+#define dprintk(level,args...) \
+       do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0)
+#else
+#define dprintk(level,args...)
+#endif
+
+#define deb_info(args...)  dprintk(0x01,args)
+#define deb_tuner(args...) dprintk(0x02,args)
+#define deb_i2c(args...)   dprintk(0x04,args)
+#define deb_ts(args...)    dprintk(0x08,args)
+#define deb_sram(args...)  dprintk(0x10,args)
+
+#endif
index 336c178fcd5fc51e4315a81af98df984b75a86fa..acbc4c34f72ab0f9abaa07ed80fad07d85de9658 100644 (file)
@@ -97,7 +97,7 @@ struct adapter {
        u8 mac_addr[8];
        u32 dw_sram_type;
 
-       struct dvb_adapter *dvb_adapter;
+       struct dvb_adapter dvb_adapter;
        struct dvb_demux demux;
        struct dmxdev dmxdev;
        struct dmx_frontend hw_frontend;
@@ -2461,7 +2461,7 @@ static void frontend_init(struct adapter *skystar2)
                       skystar2->pdev->subsystem_vendor,
                       skystar2->pdev->subsystem_device);
        } else {
-               if (dvb_register_frontend(skystar2->dvb_adapter, skystar2->fe)) {
+               if (dvb_register_frontend(&skystar2->dvb_adapter, skystar2->fe)) {
                        printk("skystar2: Frontend registration failed!\n");
                        if (skystar2->fe->ops->release)
                                skystar2->fe->ops->release(skystar2->fe);
@@ -2486,17 +2486,17 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (ret < 0)
                goto out;
 
-       ret = dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name,
+       adapter = pci_get_drvdata(pdev);
+       dvb_adapter = &adapter->dvb_adapter;
+
+       ret = dvb_register_adapter(dvb_adapter, skystar2_pci_driver.name,
                                   THIS_MODULE);
        if (ret < 0) {
                printk("%s: Error registering DVB adapter\n", __FUNCTION__);
                goto err_halt;
        }
 
-       adapter = pci_get_drvdata(pdev);
-
        dvb_adapter->priv = adapter;
-       adapter->dvb_adapter = dvb_adapter;
 
 
        init_MUTEX(&adapter->i2c_sem);
@@ -2541,7 +2541,7 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        adapter->dmxdev.demux = dmx;
        adapter->dmxdev.capabilities = 0;
 
-       ret = dvb_dmxdev_init(&adapter->dmxdev, adapter->dvb_adapter);
+       ret = dvb_dmxdev_init(&adapter->dmxdev, &adapter->dvb_adapter);
        if (ret < 0)
                goto err_dmx_release;
 
@@ -2559,7 +2559,7 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (ret < 0)
                goto err_remove_mem_frontend;
 
-       dvb_net_init(adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
+       dvb_net_init(&adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
 
        frontend_init(adapter);
 out:
@@ -2576,7 +2576,7 @@ err_dmx_release:
 err_i2c_del:
        i2c_del_adapter(&adapter->i2c_adap);
 err_dvb_unregister:
-       dvb_unregister_adapter(adapter->dvb_adapter);
+       dvb_unregister_adapter(&adapter->dvb_adapter);
 err_halt:
        driver_halt(pdev);
        goto out;
@@ -2605,7 +2605,7 @@ static void skystar2_remove(struct pci_dev *pdev)
        if (adapter->fe != NULL)
                dvb_unregister_frontend(adapter->fe);
 
-       dvb_unregister_adapter(adapter->dvb_adapter);
+       dvb_unregister_adapter(&adapter->dvb_adapter);
 
                        i2c_del_adapter(&adapter->i2c_adap);
 
index e7d11e0667a8b2a1bd8add1ece6868befb864b4a..b12545f093f8aacd54e4aac476a0b504aaddda38 100644 (file)
@@ -11,9 +11,8 @@ config DVB_BT8XX
          the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and
          pcHDTV HD2000 cards.
 
-          Since these cards have no MPEG decoder onboard, they transmit
+         Since these cards have no MPEG decoder onboard, they transmit
          only compressed MPEG data over the PCI bus, so you need
          an external software decoder to watch TV on your computer.
 
          Say Y if you own such a device and want to use it.
-
index 9da8604b9e18a01b370b8339ff25277be19405e1..d188e4c670b512f6667825a39117a14a6a843d08 100644 (file)
@@ -1,5 +1,3 @@
-
-obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o
+obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
 
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends
-
index 213ff7902024221c176e4d138ea2faa87aaf5e7f..3c5a8e273c4aa47488837a3110deab42f33099b2 100644 (file)
@@ -4,27 +4,27 @@
  * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
  *
  * large parts based on the bttv driver
- * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
- *                        & Marcus Metzler (mocm@thp.uni-koeln.de)
+ * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@metzlerbros.de)
+ *                        & Marcus Metzler (mocm@metzlerbros.de)
  * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- * 
+ *
 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
 
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- * 
+ *
  */
 
 #include <linux/module.h>
@@ -58,7 +58,7 @@ module_param_named(verbose, bt878_verbose, int, 0444);
 MODULE_PARM_DESC(verbose,
                 "verbose startup messages, default is 1 (yes)");
 module_param_named(debug, bt878_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off).");
 
 int bt878_num;
 struct bt878 bt878[BT878_MAX];
@@ -128,21 +128,21 @@ static int bt878_mem_alloc(struct bt878 *bt)
 }
 
 /* RISC instructions */
-#define RISC_WRITE             (0x01 << 28)
-#define RISC_JUMP              (0x07 << 28)
-#define RISC_SYNC              (0x08 << 28)
+#define RISC_WRITE             (0x01 << 28)
+#define RISC_JUMP              (0x07 << 28)
+#define RISC_SYNC              (0x08 << 28)
 
 /* RISC bits */
-#define RISC_WR_SOL            (1 << 27)
-#define RISC_WR_EOL            (1 << 26)
-#define RISC_IRQ               (1 << 24)
+#define RISC_WR_SOL            (1 << 27)
+#define RISC_WR_EOL            (1 << 26)
+#define RISC_IRQ               (1 << 24)
 #define RISC_STATUS(status)    ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16))
-#define RISC_SYNC_RESYNC       (1 << 15)
-#define RISC_SYNC_FM1          0x06
-#define RISC_SYNC_VRO          0x0C
+#define RISC_SYNC_RESYNC       (1 << 15)
+#define RISC_SYNC_FM1          0x06
+#define RISC_SYNC_VRO          0x0C
 
 #define RISC_FLUSH()           bt->risc_pos = 0
-#define RISC_INSTR(instr)      bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr)
+#define RISC_INSTR(instr)      bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr)
 
 static int bt878_make_risc(struct bt878 *bt)
 {
@@ -173,7 +173,7 @@ static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin)
        RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin);
        RISC_INSTR(0);
 
-       dprintk("bt878: risc len lines %u, bytes per line %u\n", 
+       dprintk("bt878: risc len lines %u, bytes per line %u\n",
                        bt->line_count, bt->line_bytes);
        for (line = 0; line < bt->line_count; line++) {
                // At the beginning of every block we issue an IRQ with previous (finished) block number set
@@ -228,14 +228,14 @@ void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
         * Hacked for DST to:
         * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI
         */
-       int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT | 
-               BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT | 
+       int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT |
+               BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT |
                BT878_AFBUS | BT878_ARISCI;
 
 
        /* ignore pesky bits */
        int_mask &= ~irq_err_ignore;
-       
+
        btwrite(int_mask, BT878_AINT_MASK);
        btwrite(controlreg, BT878_AGPIO_DMA_CTL);
 }
@@ -461,9 +461,9 @@ static int __devinit bt878_probe(struct pci_dev *dev,
        pci_set_drvdata(dev, bt);
 
 /*        if(init_bt878(btv) < 0) {
-                bt878_remove(dev);
-                return -EIO;
-        }
+               bt878_remove(dev);
+               return -EIO;
+       }
 */
 
        if ((result = bt878_mem_alloc(bt))) {
@@ -536,10 +536,10 @@ static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
 MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
 
 static struct pci_driver bt878_pci_driver = {
-      .name    = "bt878",
+      .name    = "bt878",
       .id_table = bt878_pci_tbl,
-      .probe   = bt878_probe,
-      .remove  = bt878_remove,
+      .probe   = bt878_probe,
+      .remove  = bt878_remove,
 };
 
 static int bt878_pci_driver_registered = 0;
@@ -558,7 +558,7 @@ static int bt878_init_module(void)
               (BT878_VERSION_CODE >> 8) & 0xff,
               BT878_VERSION_CODE & 0xff);
 /*
-        bt878_check_chipset();
+       bt878_check_chipset();
 */
        /* later we register inside of bt878_find_audio_dma()
         * because we may want to ignore certain cards */
index e1b9809d1b083b0f2d32be74884df713b1fc81df..837623f7fcdfce60e08bc97de33c09134c49462f 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
     bt878.h - Bt878 audio module (register offsets)
 
     Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
@@ -120,14 +120,14 @@ struct bt878 {
        u32 risc_pos;
 
        struct tasklet_struct tasklet;
-       int shutdown;   
+       int shutdown;
 };
 
 extern struct bt878 bt878[BT878_MAX];
 
 void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
                u32 irq_err_ignore);
-void bt878_stop(struct bt878 *bt);          
+void bt878_stop(struct bt878 *bt);
 
 #if defined(__powerpc__)       /* big-endian */
 extern __inline__ void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
index eac83768dfd0ef2d6d2ad90b3e6f1872f802c130..1339912c308b4a502e418ab0949b658d0583c26f 100644 (file)
@@ -1,25 +1,25 @@
 /*
-    Frontend-driver for TwinHan DST Frontend
 
-    Copyright (C) 2003 Jamie Honan
+       Frontend/Card driver for TwinHan DST Frontend
+       Copyright (C) 2003 Jamie Honan
+       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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 free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
 
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
 
+       You 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 "dvb_frontend.h"
 #include "dst_priv.h"
-#include "dst.h"
-
-struct dst_state {
-
-       struct i2c_adapter* i2c;
-
-       struct bt878* bt;
-
-       struct dvb_frontend_ops ops;
-
-       /* configuration settings */
-       const struct dst_config* config;
-
-       struct dvb_frontend frontend;
-
-       /* private demodulator data */
-       u8 tx_tuna[10];
-       u8 rx_tuna[10];
-       u8 rxbuffer[10];
-       u8 diseq_flags;
-       u8 dst_type;
-       u32 type_flags;
-       u32 frequency;          /* intermediate frequency in kHz for QPSK */
-       fe_spectral_inversion_t inversion;
-       u32 symbol_rate;        /* symbol rate in Symbols per second */
-       fe_code_rate_t fec;
-       fe_sec_voltage_t voltage;
-       fe_sec_tone_mode_t tone;
-       u32 decode_freq;
-       u8 decode_lock;
-       u16 decode_strength;
-       u16 decode_snr;
-       unsigned long cur_jiff;
-       u8 k22;
-       fe_bandwidth_t bandwidth;
-};
+#include "dst_common.h"
+
 
-static unsigned int dst_verbose = 0;
-module_param(dst_verbose, int, 0644);
-MODULE_PARM_DESC(dst_verbose, "verbose startup messages, default is 1 (yes)");
-static unsigned int dst_debug = 0;
-module_param(dst_debug, int, 0644);
-MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)");
+static unsigned int verbose = 1;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
 
-#define dprintk        if (dst_debug) printk
+static unsigned int debug = 1;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)");
 
-#define DST_TYPE_IS_SAT                0
-#define DST_TYPE_IS_TERR       1
-#define DST_TYPE_IS_CABLE      2
+static unsigned int dst_addons;
+module_param(dst_addons, int, 0644);
+MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
 
-#define DST_TYPE_HAS_NEWTUNE   1
-#define DST_TYPE_HAS_TS204     2
-#define DST_TYPE_HAS_SYMDIV    4
+#define dprintk        if (debug) printk
 
 #define HAS_LOCK       1
 #define ATTEMPT_TUNE   2
@@ -97,7 +60,7 @@ static void dst_packsize(struct dst_state* state, int psize)
        bt878_device_control(state->bt, DST_IG_TS, &bits);
 }
 
-static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh)
+int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay)
 {
        union dst_gpio_packet enb;
        union dst_gpio_packet bits;
@@ -105,26 +68,33 @@ static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhig
 
        enb.enb.mask = mask;
        enb.enb.enable = enbb;
+       if (verbose > 4)
+               dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh);
+
        if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
-               dprintk("%s: dst_gpio_enb error (err == %i, mask == 0x%02x, enb == 0x%02x)\n", __FUNCTION__, err, mask, enbb);
+               dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb);
                return -EREMOTEIO;
        }
-
+       udelay(1000);
        /* because complete disabling means no output, no need to do output packet */
        if (enbb == 0)
                return 0;
 
+       if (delay)
+               msleep(10);
+
        bits.outp.mask = enbb;
        bits.outp.highvals = outhigh;
 
        if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
-               dprintk("%s: dst_gpio_outb error (err == %i, enbb == 0x%02x, outhigh == 0x%02x)\n", __FUNCTION__, err, enbb, outhigh);
+               dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh);
                return -EREMOTEIO;
        }
        return 0;
 }
+EXPORT_SYMBOL(dst_gpio_outb);
 
-static int dst_gpio_inb(struct dst_state *state, u8 * result)
+int dst_gpio_inb(struct dst_state *state, u8 * result)
 {
        union dst_gpio_packet rd_packet;
        int err;
@@ -139,143 +109,225 @@ static int dst_gpio_inb(struct dst_state *state, u8 * result)
        *result = (u8) rd_packet.rd.value;
        return 0;
 }
+EXPORT_SYMBOL(dst_gpio_inb);
 
-#define DST_I2C_ENABLE 1
-#define DST_8820       2
-
-static int dst_reset8820(struct dst_state *state)
+int rdc_reset_state(struct dst_state *state)
 {
-       int retval;
-       /* pull 8820 gpio pin low, wait, high, wait, then low */
-       // dprintk ("%s: reset 8820\n", __FUNCTION__);
-       retval = dst_gpio_outb(state, DST_8820, DST_8820, 0);
-       if (retval < 0)
-               return retval;
+       if (verbose > 1)
+               dprintk("%s: Resetting state machine\n", __FUNCTION__);
+
+       if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
+               dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+               return -1;
+       }
+
        msleep(10);
-       retval = dst_gpio_outb(state, DST_8820, DST_8820, DST_8820);
-       if (retval < 0)
-               return retval;
-       /* wait for more feedback on what works here *
-          msleep(10);
-          retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0);
-          if (retval < 0)
-          return retval;
-        */
+
+       if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
+               dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+               msleep(10);
+               return -1;
+       }
+
        return 0;
 }
+EXPORT_SYMBOL(rdc_reset_state);
 
-static int dst_i2c_enable(struct dst_state *state)
+int rdc_8820_reset(struct dst_state *state)
 {
-       int retval;
-       /* pull I2C enable gpio pin low, wait */
-       // dprintk ("%s: i2c enable\n", __FUNCTION__);
-       retval = dst_gpio_outb(state, ~0, DST_I2C_ENABLE, 0);
-       if (retval < 0)
-               return retval;
-       // dprintk ("%s: i2c enable delay\n", __FUNCTION__);
-       msleep(33);
+       if (verbose > 1)
+               dprintk("%s: Resetting DST\n", __FUNCTION__);
+
+       if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
+               dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+               return -1;
+       }
+       udelay(1000);
+       if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
+               dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+               return -1;
+       }
+
        return 0;
 }
+EXPORT_SYMBOL(rdc_8820_reset);
 
-static int dst_i2c_disable(struct dst_state *state)
+int dst_pio_enable(struct dst_state *state)
 {
-       int retval;
-       /* release I2C enable gpio pin, wait */
-       // dprintk ("%s: i2c disable\n", __FUNCTION__);
-       retval = dst_gpio_outb(state, ~0, 0, 0);
-       if (retval < 0)
-               return retval;
-       // dprintk ("%s: i2c disable delay\n", __FUNCTION__);
-       msleep(33);
+       if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
+               dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+               return -1;
+       }
+       udelay(1000);
+       return 0;
+}
+EXPORT_SYMBOL(dst_pio_enable);
+
+int dst_pio_disable(struct dst_state *state)
+{
+       if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
+               dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+               return -1;
+       }
+       if (state->type_flags & DST_TYPE_HAS_FW_1)
+               udelay(1000);
+
        return 0;
 }
+EXPORT_SYMBOL(dst_pio_disable);
 
-static int dst_wait_dst_ready(struct dst_state *state)
+int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
 {
        u8 reply;
-       int retval;
        int i;
+
        for (i = 0; i < 200; i++) {
-               retval = dst_gpio_inb(state, &reply);
-               if (retval < 0)
-                       return retval;
-               if ((reply & DST_I2C_ENABLE) == 0) {
-                       dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
+               if (dst_gpio_inb(state, &reply) < 0) {
+                       dprintk("%s: dst_gpio_inb ERROR !\n", __FUNCTION__);
+                       return -1;
+               }
+
+               if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
+                       if (verbose > 4)
+                               dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
                        return 1;
                }
                msleep(10);
        }
-       dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
+       if (verbose > 1)
+               dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
+
+       return 0;
+}
+EXPORT_SYMBOL(dst_wait_dst_ready);
+
+int dst_error_recovery(struct dst_state *state)
+{
+       dprintk("%s: Trying to return from previous errors...\n", __FUNCTION__);
+       dst_pio_disable(state);
+       msleep(10);
+       dst_pio_enable(state);
+       msleep(10);
+
        return 0;
 }
+EXPORT_SYMBOL(dst_error_recovery);
+
+int dst_error_bailout(struct dst_state *state)
+{
+       dprintk("%s: Trying to bailout from previous error...\n", __FUNCTION__);
+       rdc_8820_reset(state);
+       dst_pio_disable(state);
+       msleep(10);
+
+       return 0;
+}
+EXPORT_SYMBOL(dst_error_bailout);
+
+
+int dst_comm_init(struct dst_state* state)
+{
+       if (verbose > 1)
+               dprintk ("%s: Initializing DST..\n", __FUNCTION__);
+       if ((dst_pio_enable(state)) < 0) {
+               dprintk("%s: PIO Enable Failed.\n", __FUNCTION__);
+               return -1;
+       }
+       if ((rdc_reset_state(state)) < 0) {
+               dprintk("%s: RDC 8820 State RESET Failed.\n", __FUNCTION__);
+               return -1;
+       }
+       if (state->type_flags & DST_TYPE_HAS_FW_1)
+               msleep(100);
+       else
+               msleep(5);
+
+       return 0;
+}
+EXPORT_SYMBOL(dst_comm_init);
+
 
-static int write_dst(struct dst_state *state, u8 * data, u8 len)
+int write_dst(struct dst_state *state, u8 *data, u8 len)
 {
        struct i2c_msg msg = {
                .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len
        };
+
        int err;
        int cnt;
-
-       if (dst_debug && dst_verbose) {
+       if (debug && (verbose > 4)) {
                u8 i;
-               dprintk("%s writing", __FUNCTION__);
-               for (i = 0; i < len; i++) {
-                       dprintk(" 0x%02x", data[i]);
+               if (verbose > 4) {
+                       dprintk("%s writing", __FUNCTION__);
+                       for (i = 0; i < len; i++)
+                               dprintk(" %02x", data[i]);
+                       dprintk("\n");
                }
-               dprintk("\n");
        }
-       msleep(30);
-       for (cnt = 0; cnt < 4; cnt++) {
+       for (cnt = 0; cnt < 2; cnt++) {
                if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
-                       dprintk("%s: write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
-                       dst_i2c_disable(state);
-                       msleep(500);
-                       dst_i2c_enable(state);
-                       msleep(500);
+                       dprintk("%s: _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
+                       dst_error_recovery(state);
                        continue;
                } else
                        break;
        }
-       if (cnt >= 4)
-               return -EREMOTEIO;
+
+       if (cnt >= 2) {
+               if (verbose > 1)
+                       printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
+               dst_error_bailout(state);
+
+               return -1;
+       }
+
        return 0;
 }
+EXPORT_SYMBOL(write_dst);
 
-static int read_dst(struct dst_state *state, u8 * ret, u8 len)
+int read_dst(struct dst_state *state, u8 * ret, u8 len)
 {
        struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len };
        int err;
        int cnt;
 
-       for (cnt = 0; cnt < 4; cnt++) {
+       for (cnt = 0; cnt < 2; cnt++) {
                if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
+
                        dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
-                       dst_i2c_disable(state);
-                       dst_i2c_enable(state);
+                       dst_error_recovery(state);
+
                        continue;
                } else
                        break;
        }
-       if (cnt >= 4)
-               return -EREMOTEIO;
-       dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
-       if (dst_debug && dst_verbose) {
+       if (cnt >= 2) {
+               if (verbose > 1)
+                       printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
+               dst_error_bailout(state);
+
+               return -1;
+       }
+       if (debug && (verbose > 4)) {
+               dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
                for (err = 1; err < len; err++)
                        dprintk(" 0x%x", ret[err]);
                if (err > 1)
                        dprintk("\n");
        }
+
        return 0;
 }
+EXPORT_SYMBOL(read_dst);
 
 static int dst_set_freq(struct dst_state *state, u32 freq)
 {
        u8 *val;
 
        state->frequency = freq;
+       if (debug > 4)
+               dprintk("%s: set Frequency %u\n", __FUNCTION__, freq);
 
-       // dprintk("%s: set frequency %u\n", __FUNCTION__, freq);
        if (state->dst_type == DST_TYPE_IS_SAT) {
                freq = freq / 1000;
                if (freq < 950 || freq > 2150)
@@ -398,7 +450,8 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate)
        if (state->dst_type == DST_TYPE_IS_TERR) {
                return 0;
        }
-       // dprintk("%s: set srate %u\n", __FUNCTION__, srate);
+       if (debug > 4)
+               dprintk("%s: set symrate %u\n", __FUNCTION__, srate);
        srate /= 1000;
        val = &state->tx_tuna[0];
 
@@ -407,7 +460,10 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate)
                sval <<= 20;
                do_div(sval, 88000);
                symcalc = (u32) sval;
-               // dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
+
+               if (debug > 4)
+                       dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
+
                val[5] = (u8) (symcalc >> 12);
                val[6] = (u8) (symcalc >> 4);
                val[7] = (u8) (symcalc << 4);
@@ -422,7 +478,7 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate)
        return 0;
 }
 
-static u8 dst_check_sum(u8 * buf, u32 len)
+u8 dst_check_sum(u8 * buf, u32 len)
 {
        u32 i;
        u8 val = 0;
@@ -433,28 +489,7 @@ static u8 dst_check_sum(u8 * buf, u32 len)
        }
        return ((~val) + 1);
 }
-
-struct dst_types {
-       char *mstr;
-       int offs;
-       u8 dst_type;
-       u32 type_flags;
-};
-
-static struct dst_types dst_tlist[] = {
-       {"DST-020", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV},
-       {"DST-030", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE},
-       {"DST-03T", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204},
-       {"DST-MOT", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV},
-       {"DST-CI",  1, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE},
-       {"DSTMCI",  1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE},
-       {"DSTFCI",  1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE},
-       {"DCTNEW",  1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE},
-       {"DCT-CI",  1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_TS204},
-       {"DTTDIG",  1, DST_TYPE_IS_TERR, 0}
-};
-
-/* DCTNEW and DCT-CI are guesses */
+EXPORT_SYMBOL(dst_check_sum);
 
 static void dst_type_flags_print(u32 type_flags)
 {
@@ -465,93 +500,270 @@ static void dst_type_flags_print(u32 type_flags)
                printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
        if (type_flags & DST_TYPE_HAS_SYMDIV)
                printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
+       if (type_flags & DST_TYPE_HAS_FW_1)
+               printk(" 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
+       if (type_flags & DST_TYPE_HAS_FW_2)
+               printk(" 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
+       if (type_flags & DST_TYPE_HAS_FW_3)
+               printk(" 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
+//     if ((type_flags & DST_TYPE_HAS_FW_BUILD) && new_fw)
+
        printk("\n");
 }
 
-static int dst_type_print(u8 type)
+
+static int dst_type_print (u8 type)
 {
        char *otype;
        switch (type) {
        case DST_TYPE_IS_SAT:
                otype = "satellite";
                break;
+
        case DST_TYPE_IS_TERR:
                otype = "terrestrial";
                break;
+
        case DST_TYPE_IS_CABLE:
                otype = "cable";
                break;
+
        default:
                printk("%s: invalid dst type %d\n", __FUNCTION__, type);
                return -EINVAL;
        }
        printk("DST type : %s\n", otype);
+
        return 0;
 }
 
-static int dst_check_ci(struct dst_state *state)
+/*
+       Known cards list
+       Satellite
+       -------------------
+                 200103A
+       VP-1020   DST-MOT       LG(old), TS=188
+
+       VP-1020   DST-03T       LG(new), TS=204
+       VP-1022   DST-03T       LG(new), TS=204
+       VP-1025   DST-03T       LG(new), TS=204
+
+       VP-1030   DSTMCI,       LG(new), TS=188
+       VP-1032   DSTMCI,       LG(new), TS=188
+
+       Cable
+       -------------------
+       VP-2030   DCT-CI,       Samsung, TS=204
+       VP-2021   DCT-CI,       Unknown, TS=204
+       VP-2031   DCT-CI,       Philips, TS=188
+       VP-2040   DCT-CI,       Philips, TS=188, with CA daughter board
+       VP-2040   DCT-CI,       Philips, TS=204, without CA daughter board
+
+       Terrestrial
+       -------------------
+       VP-3050  DTTNXT                  TS=188
+       VP-3040  DTT-CI,        Philips, TS=188
+       VP-3040  DTT-CI,        Philips, TS=204
+
+       ATSC
+       -------------------
+       VP-3220  ATSCDI,                 TS=188
+       VP-3250  ATSCAD,                 TS=188
+
+*/
+
+struct dst_types dst_tlist[] = {
+       {
+               .device_id = "200103A",
+               .offset = 0,
+               .dst_type =  DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
+               .dst_feature = 0
+       },      /*      obsolete        */
+
+       {
+               .device_id = "DST-020",
+               .offset = 0,
+               .dst_type =  DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
+               .dst_feature = 0
+       },      /*      obsolete        */
+
+       {
+               .device_id = "DST-030",
+               .offset =  0,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
+               .dst_feature = 0
+       },      /*      obsolete        */
+
+       {
+               .device_id = "DST-03T",
+               .offset = 0,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
+               .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
+                                                        | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO
+        },
+
+       {
+               .device_id = "DST-MOT",
+               .offset =  0,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
+               .dst_feature = 0
+       },      /*      obsolete        */
+
+       {
+               .device_id = "DST-CI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
+               .dst_feature = DST_TYPE_HAS_CA
+       },      /*      An OEM board    */
+
+       {
+               .device_id = "DSTMCI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+               .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
+                                                       | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC
+       },
+
+       {
+               .device_id = "DSTFCI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
+               .dst_feature = 0
+       },      /* unknown to vendor    */
+
+       {
+               .device_id = "DCT-CI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_CABLE,
+               .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1
+                                                       | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+               .dst_feature = DST_TYPE_HAS_CA
+       },
+
+       {
+               .device_id = "DCTNEW",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_CABLE,
+               .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3,
+               .dst_feature = 0
+       },
+
+       {
+               .device_id = "DTT-CI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_TERR,
+               .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+               .dst_feature = 0
+       },
+
+       {
+               .device_id = "DTTDIG",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_TERR,
+               .type_flags = DST_TYPE_HAS_FW_2,
+               .dst_feature = 0
+       },
+
+       {
+               .device_id = "DTTNXT",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_TERR,
+               .type_flags = DST_TYPE_HAS_FW_2,
+               .dst_feature = DST_TYPE_HAS_ANALOG
+       },
+
+       {
+               .device_id = "ATSCDI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_ATSC,
+               .type_flags = DST_TYPE_HAS_FW_2,
+               .dst_feature = 0
+       },
+
+       {
+               .device_id = "ATSCAD",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_ATSC,
+               .type_flags = DST_TYPE_HAS_FW_2,
+               .dst_feature = 0
+       },
+
+       { }
+
+};
+
+
+static int dst_get_device_id(struct dst_state *state)
 {
-       u8 txbuf[8];
-       u8 rxbuf[8];
-       int retval;
+       u8 reply;
+
        int i;
-       struct dst_types *dsp;
-       u8 use_dst_type;
-       u32 use_type_flags;
+       struct dst_types *p_dst_type;
+       u8 use_dst_type = 0;
+       u32 use_type_flags = 0;
 
-       memset(txbuf, 0, sizeof(txbuf));
-       txbuf[1] = 6;
-       txbuf[7] = dst_check_sum(txbuf, 7);
+       static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
 
-       dst_i2c_enable(state);
-       dst_reset8820(state);
-       retval = write_dst(state, txbuf, 8);
-       if (retval < 0) {
-               dst_i2c_disable(state);
-               dprintk("%s: write not successful, maybe no card?\n", __FUNCTION__);
-               return retval;
-       }
-       msleep(3);
-       retval = read_dst(state, rxbuf, 1);
-       dst_i2c_disable(state);
-       if (retval < 0) {
-               dprintk("%s: read not successful, maybe no card?\n", __FUNCTION__);
-               return retval;
-       }
-       if (rxbuf[0] != 0xff) {
-               dprintk("%s: write reply not 0xff, not ci (%02x)\n", __FUNCTION__, rxbuf[0]);
-               return retval;
-       }
-       if (!dst_wait_dst_ready(state))
-               return 0;
-       // dst_i2c_enable(i2c); Dimitri
-       retval = read_dst(state, rxbuf, 8);
-       dst_i2c_disable(state);
-       if (retval < 0) {
-               dprintk("%s: read not successful\n", __FUNCTION__);
-               return retval;
+       device_type[7] = dst_check_sum(device_type, 7);
+
+       if (write_dst(state, device_type, FIXED_COMM))
+               return -1;              /*      Write failed            */
+
+       if ((dst_pio_disable(state)) < 0)
+               return -1;
+
+       if (read_dst(state, &reply, GET_ACK))
+               return -1;              /*      Read failure            */
+
+       if (reply != ACK) {
+               dprintk("%s: Write not Acknowledged! [Reply=0x%02x]\n", __FUNCTION__, reply);
+               return -1;              /*      Unack'd write           */
        }
-       if (rxbuf[7] != dst_check_sum(rxbuf, 7)) {
-               dprintk("%s: checksum failure\n", __FUNCTION__);
-               return retval;
+
+       if (!dst_wait_dst_ready(state, DEVICE_INIT))
+               return -1;              /*      DST not ready yet       */
+
+       if (read_dst(state, state->rxbuffer, FIXED_COMM))
+               return -1;
+
+       dst_pio_disable(state);
+
+       if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
+               dprintk("%s: Checksum failure! \n", __FUNCTION__);
+               return -1;              /*      Checksum failure        */
        }
-       rxbuf[7] = '\0';
-       for (i = 0, dsp = &dst_tlist[0]; i < sizeof(dst_tlist) / sizeof(dst_tlist[0]); i++, dsp++) {
-               if (!strncmp(&rxbuf[dsp->offs], dsp->mstr, strlen(dsp->mstr))) {
-                       use_type_flags = dsp->type_flags;
-                       use_dst_type = dsp->dst_type;
-                       printk("%s: recognize %s\n", __FUNCTION__, dsp->mstr);
+
+       state->rxbuffer[7] = '\0';
+
+       for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE (dst_tlist); i++, p_dst_type++) {
+               if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
+                       use_type_flags = p_dst_type->type_flags;
+                       use_dst_type = p_dst_type->dst_type;
+
+                       /*      Card capabilities       */
+                       state->dst_hw_cap = p_dst_type->dst_feature;
+                       printk ("%s: Recognise [%s]\n", __FUNCTION__, p_dst_type->device_id);
+
                        break;
                }
        }
-       if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) {
-               printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]);
-               printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
+
+       if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) {
+               printk("%s: Unable to recognize %s or %s\n", __FUNCTION__, &state->rxbuffer[0], &state->rxbuffer[1]);
+               printk("%s: please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
                use_dst_type = DST_TYPE_IS_SAT;
                use_type_flags = DST_TYPE_HAS_SYMDIV;
        }
-       dst_type_print(use_dst_type);
 
+       dst_type_print(use_dst_type);
        state->type_flags = use_type_flags;
        state->dst_type = use_dst_type;
        dst_type_flags_print(state->type_flags);
@@ -559,50 +771,102 @@ static int dst_check_ci(struct dst_state *state)
        if (state->type_flags & DST_TYPE_HAS_TS204) {
                dst_packsize(state, 204);
        }
+
        return 0;
 }
 
-static int dst_command(struct dst_state* state, u8 * data, u8 len)
+static int dst_probe(struct dst_state *state)
+{
+       if ((rdc_8820_reset(state)) < 0) {
+               dprintk("%s: RDC 8820 RESET Failed.\n", __FUNCTION__);
+               return -1;
+       }
+       if (dst_addons & DST_TYPE_HAS_CA)
+               msleep(4000);
+       else
+               msleep(100);
+
+       if ((dst_comm_init(state)) < 0) {
+               dprintk("%s: DST Initialization Failed.\n", __FUNCTION__);
+               return -1;
+       }
+       msleep(100);
+       if (dst_get_device_id(state) < 0) {
+               dprintk("%s: unknown device.\n", __FUNCTION__);
+               return -1;
+       }
+
+       return 0;
+}
+
+int dst_command(struct dst_state* state, u8 * data, u8 len)
 {
-       int retval;
        u8 reply;
+       if ((dst_comm_init(state)) < 0) {
+               dprintk("%s: DST Communication Initialization Failed.\n", __FUNCTION__);
+               return -1;
+       }
 
-       dst_i2c_enable(state);
-       dst_reset8820(state);
-       retval = write_dst(state, data, len);
-       if (retval < 0) {
-               dst_i2c_disable(state);
-               dprintk("%s: write not successful\n", __FUNCTION__);
-               return retval;
+       if (write_dst(state, data, len)) {
+               if (verbose > 1)
+                       dprintk("%s: Tring to recover.. \n", __FUNCTION__);
+               if ((dst_error_recovery(state)) < 0) {
+                       dprintk("%s: Recovery Failed.\n", __FUNCTION__);
+                       return -1;
+               }
+               return -1;
        }
-       msleep(33);
-       retval = read_dst(state, &reply, 1);
-       dst_i2c_disable(state);
-       if (retval < 0) {
-               dprintk("%s: read verify  not successful\n", __FUNCTION__);
-               return retval;
+       if ((dst_pio_disable(state)) < 0) {
+               dprintk("%s: PIO Disable Failed.\n", __FUNCTION__);
+               return -1;
        }
-       if (reply != 0xff) {
-               dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
-               return 0;
+       if (state->type_flags & DST_TYPE_HAS_FW_1)
+               udelay(3000);
+
+       if (read_dst(state, &reply, GET_ACK)) {
+               if (verbose > 1)
+                       dprintk("%s: Trying to recover.. \n", __FUNCTION__);
+               if ((dst_error_recovery(state)) < 0) {
+                       dprintk("%s: Recovery Failed.\n", __FUNCTION__);
+                       return -1;
+               }
+               return -1;
+       }
+
+       if (reply != ACK) {
+               dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
+               return -1;
        }
        if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
                return 0;
-       if (!dst_wait_dst_ready(state))
-               return 0;
-       // dst_i2c_enable(i2c); Per dimitri
-       retval = read_dst(state, state->rxbuffer, 8);
-       dst_i2c_disable(state);
-       if (retval < 0) {
-               dprintk("%s: read not successful\n", __FUNCTION__);
-               return 0;
+
+//     udelay(3000);
+       if (state->type_flags & DST_TYPE_HAS_FW_1)
+               udelay(3000);
+       else
+               udelay(2000);
+
+       if (!dst_wait_dst_ready(state, NO_DELAY))
+               return -1;
+
+       if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
+               if (verbose > 1)
+                       dprintk("%s: Trying to recover.. \n", __FUNCTION__);
+               if ((dst_error_recovery(state)) < 0) {
+                       dprintk("%s: Recovery failed.\n", __FUNCTION__);
+                       return -1;
+               }
+               return -1;
        }
+
        if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
                dprintk("%s: checksum failure\n", __FUNCTION__);
-               return 0;
+               return -1;
        }
+
        return 0;
 }
+EXPORT_SYMBOL(dst_command);
 
 static int dst_get_signal(struct dst_state* state)
 {
@@ -642,37 +906,38 @@ static int dst_tone_power_cmd(struct dst_state* state)
        if (state->dst_type == DST_TYPE_IS_TERR)
                return 0;
 
-       if (state->voltage == SEC_VOLTAGE_OFF)
-               paket[4] = 0;
-       else
-               paket[4] = 1;
-       if (state->tone == SEC_TONE_ON)
-               paket[2] = state->k22;
-       else
-               paket[2] = 0;
-       paket[7] = dst_check_sum(&paket[0], 7);
+       paket[4] = state->tx_tuna[4];
+       paket[2] = state->tx_tuna[2];
+       paket[3] = state->tx_tuna[3];
+       paket[7] = dst_check_sum (paket, 7);
        dst_command(state, paket, 8);
+
        return 0;
 }
 
 static int dst_get_tuna(struct dst_state* state)
 {
        int retval;
+
        if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
                return 0;
+
        state->diseq_flags &= ~(HAS_LOCK);
-       if (!dst_wait_dst_ready(state))
+       if (!dst_wait_dst_ready(state, NO_DELAY))
                return 0;
+
        if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
                /* how to get variable length reply ???? */
                retval = read_dst(state, state->rx_tuna, 10);
        } else {
-               retval = read_dst(state, &state->rx_tuna[2], 8);
+               retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
        }
+
        if (retval < 0) {
                dprintk("%s: read not successful\n", __FUNCTION__);
                return 0;
        }
+
        if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
                if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
                        dprintk("%s: checksum failure?\n", __FUNCTION__);
@@ -705,11 +970,13 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
 
 static int dst_write_tuna(struct dvb_frontend* fe)
 {
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
        int retval;
        u8 reply;
 
-       dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags);
+       if (debug > 4)
+               dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags);
+
        state->decode_freq = 0;
        state->decode_lock = state->decode_strength = state->decode_snr = 0;
        if (state->dst_type == DST_TYPE_IS_SAT) {
@@ -717,32 +984,41 @@ static int dst_write_tuna(struct dvb_frontend* fe)
                        dst_set_voltage(fe, SEC_VOLTAGE_13);
        }
        state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
-       dst_i2c_enable(state);
+
+       if ((dst_comm_init(state)) < 0) {
+               dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__);
+               return -1;
+       }
+
        if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
-               dst_reset8820(state);
                state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
                retval = write_dst(state, &state->tx_tuna[0], 10);
+
        } else {
                state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
-               retval = write_dst(state, &state->tx_tuna[2], 8);
+               retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
        }
        if (retval < 0) {
-               dst_i2c_disable(state);
+               dst_pio_disable(state);
                dprintk("%s: write not successful\n", __FUNCTION__);
                return retval;
        }
-       msleep(3);
-       retval = read_dst(state, &reply, 1);
-       dst_i2c_disable(state);
-       if (retval < 0) {
-               dprintk("%s: read verify  not successful\n", __FUNCTION__);
-               return retval;
+
+       if ((dst_pio_disable(state)) < 0) {
+               dprintk("%s: DST PIO disable failed !\n", __FUNCTION__);
+               return -1;
        }
-       if (reply != 0xff) {
-               dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
+
+       if ((read_dst(state, &reply, GET_ACK) < 0)) {
+               dprintk("%s: read verify not successful.\n", __FUNCTION__);
+               return -1;
+       }
+       if (reply != ACK) {
+               dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
                return 0;
        }
        state->diseq_flags |= ATTEMPT_TUNE;
+
        return dst_get_tuna(state);
 }
 
@@ -762,10 +1038,10 @@ static int dst_write_tuna(struct dvb_frontend* fe)
 
 static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
 {
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
        u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
 
-       if (state->dst_type == DST_TYPE_IS_TERR)
+       if (state->dst_type != DST_TYPE_IS_SAT)
                return 0;
 
        if (cmd->msg_len == 0 || cmd->msg_len > 4)
@@ -778,73 +1054,91 @@ static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd*
 
 static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
-       u8 *val;
        int need_cmd;
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
 
        state->voltage = voltage;
 
-       if (state->dst_type == DST_TYPE_IS_TERR)
+       if (state->dst_type != DST_TYPE_IS_SAT)
                return 0;
 
        need_cmd = 0;
-       val = &state->tx_tuna[0];
-       val[8] &= ~0x40;
        switch (voltage) {
-       case SEC_VOLTAGE_13:
-               if ((state->diseq_flags & HAS_POWER) == 0)
-                       need_cmd = 1;
-               state->diseq_flags |= HAS_POWER;
-               break;
-       case SEC_VOLTAGE_18:
-               if ((state->diseq_flags & HAS_POWER) == 0)
+               case SEC_VOLTAGE_13:
+               case SEC_VOLTAGE_18:
+                       if ((state->diseq_flags & HAS_POWER) == 0)
+                               need_cmd = 1;
+                       state->diseq_flags |= HAS_POWER;
+                       state->tx_tuna[4] = 0x01;
+                       break;
+
+               case SEC_VOLTAGE_OFF:
                        need_cmd = 1;
-               state->diseq_flags |= HAS_POWER;
-               val[8] |= 0x40;
-               break;
-       case SEC_VOLTAGE_OFF:
-               need_cmd = 1;
-               state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
-               break;
-       default:
-               return -EINVAL;
+                       state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
+                       state->tx_tuna[4] = 0x00;
+                       break;
+
+               default:
+                       return -EINVAL;
        }
-       if (need_cmd) {
+       if (need_cmd)
                dst_tone_power_cmd(state);
-       }
+
        return 0;
 }
 
 static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
-       u8 *val;
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
 
        state->tone = tone;
 
-       if (state->dst_type == DST_TYPE_IS_TERR)
+       if (state->dst_type != DST_TYPE_IS_SAT)
                return 0;
 
-       val = &state->tx_tuna[0];
+       switch (tone) {
+               case SEC_TONE_OFF:
+                       state->tx_tuna[2] = 0xff;
+                       break;
 
-       val[8] &= ~0x1;
+               case SEC_TONE_ON:
+                       state->tx_tuna[2] = 0x02;
+                       break;
 
-       switch (tone) {
-       case SEC_TONE_OFF:
-               break;
-       case SEC_TONE_ON:
-               val[8] |= 1;
-               break;
-       default:
-               return -EINVAL;
+               default:
+                       return -EINVAL;
        }
        dst_tone_power_cmd(state);
+
+       return 0;
+}
+
+static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
+{
+       struct dst_state *state = fe->demodulator_priv;
+
+       if (state->dst_type != DST_TYPE_IS_SAT)
+               return 0;
+
+       state->minicmd = minicmd;
+
+       switch (minicmd) {
+               case SEC_MINI_A:
+                       state->tx_tuna[3] = 0x02;
+                       break;
+               case SEC_MINI_B:
+                       state->tx_tuna[3] = 0xff;
+                       break;
+       }
+       dst_tone_power_cmd(state);
+
        return 0;
 }
 
+
 static int dst_init(struct dvb_frontend* fe)
 {
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
        static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 };
        static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 };
        static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
@@ -876,7 +1170,7 @@ static int dst_init(struct dvb_frontend* fe)
 
 static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
 
        *status = 0;
        if (state->diseq_flags & HAS_LOCK) {
@@ -890,7 +1184,7 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
 
        dst_get_signal(state);
        *strength = state->decode_strength;
@@ -900,7 +1194,7 @@ static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
 
        dst_get_signal(state);
        *snr = state->decode_snr;
@@ -910,13 +1204,19 @@ static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
 
        dst_set_freq(state, p->frequency);
+       if (verbose > 4)
+               dprintk("Set Frequency = [%d]\n", p->frequency);
+
        dst_set_inversion(state, p->inversion);
        if (state->dst_type == DST_TYPE_IS_SAT) {
                dst_set_fec(state, p->u.qpsk.fec_inner);
                dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
+               if (verbose > 4)
+                       dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate);
+
        } else if (state->dst_type == DST_TYPE_IS_TERR) {
                dst_set_bandwidth(state, p->u.ofdm.bandwidth);
        } else if (state->dst_type == DST_TYPE_IS_CABLE) {
@@ -930,7 +1230,7 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
 
 static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
 
        p->frequency = state->decode_freq;
        p->inversion = state->inversion;
@@ -950,7 +1250,7 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
 
 static void dst_release(struct dvb_frontend* fe)
 {
-       struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
+       struct dst_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -958,50 +1258,47 @@ static struct dvb_frontend_ops dst_dvbt_ops;
 static struct dvb_frontend_ops dst_dvbs_ops;
 static struct dvb_frontend_ops dst_dvbc_ops;
 
-struct dvb_frontend* dst_attach(const struct dst_config* config,
-                               struct i2c_adapter* i2c,
-                               struct bt878 *bt)
+struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
 {
-       struct dst_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = (struct dst_state*) kmalloc(sizeof(struct dst_state), GFP_KERNEL);
-       if (state == NULL) goto error;
 
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->bt = bt;
-
-       /* check if the demod is there */
-       if (dst_check_ci(state) < 0) goto error;
+       /* check if the ASIC is there */
+       if (dst_probe(state) < 0) {
+               if (state)
+                       kfree(state);
 
+               return NULL;
+       }
        /* determine settings based on type */
        switch (state->dst_type) {
        case DST_TYPE_IS_TERR:
                memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
                break;
+
        case DST_TYPE_IS_CABLE:
                memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
                break;
+
        case DST_TYPE_IS_SAT:
                memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
                break;
+
        default:
-               printk("dst: unknown frontend type. please report to the LinuxTV.org DVB mailinglist.\n");
-               goto error;
+               printk("%s: unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n", __FUNCTION__);
+               if (state)
+                       kfree(state);
+
+               return NULL;
        }
 
        /* create dvb_frontend */
        state->frontend.ops = &state->ops;
        state->frontend.demodulator_priv = state;
-       return &state->frontend;
 
-error:
-       kfree(state);
-       return NULL;
+       return state;                           /*      Manu (DST is a card not a frontend)     */
 }
 
+EXPORT_SYMBOL(dst_attach);
+
 static struct dvb_frontend_ops dst_dvbt_ops = {
 
        .info = {
@@ -1051,6 +1348,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
        .read_signal_strength = dst_read_signal_strength,
        .read_snr = dst_read_snr,
 
+       .diseqc_send_burst = dst_send_burst,
        .diseqc_send_master_cmd = dst_set_diseqc,
        .set_voltage = dst_set_voltage,
        .set_tone = dst_set_tone,
@@ -1082,8 +1380,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
        .read_snr = dst_read_snr,
 };
 
+
 MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");
-MODULE_AUTHOR("Jamie Honan");
+MODULE_AUTHOR("Jamie Honan, Manu Abraham");
 MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(dst_attach);
diff --git a/drivers/media/dvb/bt8xx/dst.h b/drivers/media/dvb/bt8xx/dst.h
deleted file mode 100644 (file)
index bcb418c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-    Frontend-driver for TwinHan DST Frontend
-
-    Copyright (C) 2003 Jamie Honan
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You 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 DST_H
-#define DST_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/device.h>
-#include "bt878.h"
-
-struct dst_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-};
-
-extern struct dvb_frontend* dst_attach(const struct dst_config* config,
-                                      struct i2c_adapter* i2c,
-                                      struct bt878 *bt);
-
-#endif // DST_H
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
new file mode 100644 (file)
index 0000000..d781504
--- /dev/null
@@ -0,0 +1,861 @@
+/*
+       CA-driver for TwinHan DST Frontend/Card
+
+       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <linux/dvb/ca.h>
+#include "dvbdev.h"
+#include "dvb_frontend.h"
+
+#include "dst_ca.h"
+#include "dst_common.h"
+
+static unsigned int verbose = 1;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
+
+static unsigned int debug = 1;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug messages, default is 1 (yes)");
+
+#define dprintk if (debug) printk
+
+/*     Need some more work     */
+static int ca_set_slot_descr(void)
+{
+       /*      We could make this more graceful ?      */
+       return -EOPNOTSUPP;
+}
+
+/*     Need some more work     */
+static int ca_set_pid(void)
+{
+       /*      We could make this more graceful ?      */
+       return -EOPNOTSUPP;
+}
+
+
+static int put_checksum(u8 *check_string, int length)
+{
+       u8 i = 0, checksum = 0;
+
+       if (verbose > 3) {
+               dprintk("%s: ========================= Checksum calculation ===========================\n", __FUNCTION__);
+               dprintk("%s: String Length=[0x%02x]\n", __FUNCTION__, length);
+
+               dprintk("%s: String=[", __FUNCTION__);
+       }
+       while (i < length) {
+               if (verbose > 3)
+                       dprintk(" %02x", check_string[i]);
+               checksum += check_string[i];
+               i++;
+       }
+       if (verbose > 3) {
+               dprintk(" ]\n");
+               dprintk("%s: Sum=[%02x]\n", __FUNCTION__, checksum);
+       }
+       check_string[length] = ~checksum + 1;
+       if (verbose > 3) {
+               dprintk("%s: Checksum=[%02x]\n", __FUNCTION__, check_string[length]);
+               dprintk("%s: ==========================================================================\n", __FUNCTION__);
+       }
+
+       return 0;
+}
+
+static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
+{
+       u8 reply;
+
+       dst_comm_init(state);
+       msleep(65);
+
+       if (write_dst(state, data, len)) {
+               dprintk("%s: Write not successful, trying to recover\n", __FUNCTION__);
+               dst_error_recovery(state);
+               return -1;
+       }
+
+       if ((dst_pio_disable(state)) < 0) {
+               dprintk("%s: DST PIO disable failed.\n", __FUNCTION__);
+               return -1;
+       }
+
+       if (read_dst(state, &reply, GET_ACK) < 0) {
+               dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
+               dst_error_recovery(state);
+               return -1;
+       }
+
+       if (read) {
+               if (! dst_wait_dst_ready(state, LONG_DELAY)) {
+                       dprintk("%s: 8820 not ready\n", __FUNCTION__);
+                       return -1;
+               }
+
+               if (read_dst(state, ca_string, 128) < 0) {      /*      Try to make this dynamic        */
+                       dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
+                       dst_error_recovery(state);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+
+static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read)
+{
+       u8 dst_ca_comm_err = 0;
+
+       while (dst_ca_comm_err < RETRIES) {
+               dst_comm_init(state);
+               if (verbose > 2)
+                       dprintk("%s: Put Command\n", __FUNCTION__);
+               if (dst_ci_command(state, data, ca_string, len, read)) {        // If error
+                       dst_error_recovery(state);
+                       dst_ca_comm_err++; // work required here.
+               }
+               break;
+       }
+
+       return 0;
+}
+
+
+
+static int ca_get_app_info(struct dst_state *state)
+{
+       static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff};
+
+       put_checksum(&command[0], command[0]);
+       if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) {
+               dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
+               return -1;
+       }
+       if (verbose > 1) {
+               dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
+
+               dprintk("%s: ================================ CI Module Application Info ======================================\n", __FUNCTION__);
+               dprintk("%s: Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]\n",
+                       __FUNCTION__, state->messages[7], (state->messages[8] << 8) | state->messages[9],
+                       (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
+               dprintk("%s: ==================================================================================================\n", __FUNCTION__);
+       }
+
+       return 0;
+}
+
+static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg)
+{
+       int i;
+       u8 slot_cap[256];
+       static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff};
+
+       put_checksum(&slot_command[0], slot_command[0]);
+       if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) {
+               dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
+               return -1;
+       }
+       if (verbose > 1)
+               dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
+
+       /*      Will implement the rest soon            */
+
+       if (verbose > 1) {
+               dprintk("%s: Slot cap = [%d]\n", __FUNCTION__, slot_cap[7]);
+               dprintk("===================================\n");
+               for (i = 0; i < 8; i++)
+                       dprintk(" %d", slot_cap[i]);
+               dprintk("\n");
+       }
+
+       p_ca_caps->slot_num = 1;
+       p_ca_caps->slot_type = 1;
+       p_ca_caps->descr_num = slot_cap[7];
+       p_ca_caps->descr_type = 1;
+
+
+       if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) {
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+/*     Need some more work     */
+static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
+{
+       return -EOPNOTSUPP;
+}
+
+
+static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg)
+{
+       int i;
+       static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
+
+       u8 *slot_info = state->rxbuffer;
+
+       put_checksum(&slot_command[0], 7);
+       if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
+               dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
+               return -1;
+       }
+       if (verbose > 1)
+               dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
+
+       /*      Will implement the rest soon            */
+
+       if (verbose > 1) {
+               dprintk("%s: Slot info = [%d]\n", __FUNCTION__, slot_info[3]);
+               dprintk("===================================\n");
+               for (i = 0; i < 8; i++)
+                       dprintk(" %d", slot_info[i]);
+               dprintk("\n");
+       }
+
+       if (slot_info[4] & 0x80) {
+               p_ca_slot_info->flags = CA_CI_MODULE_PRESENT;
+               p_ca_slot_info->num = 1;
+               p_ca_slot_info->type = CA_CI;
+       }
+       else if (slot_info[4] & 0x40) {
+               p_ca_slot_info->flags = CA_CI_MODULE_READY;
+               p_ca_slot_info->num = 1;
+               p_ca_slot_info->type = CA_CI;
+       }
+       else {
+               p_ca_slot_info->flags = 0;
+       }
+
+       if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) {
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+
+
+
+static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
+{
+       u8 i = 0;
+       u32 command = 0;
+
+       if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
+               return -EFAULT;
+
+
+       if (p_ca_message->msg) {
+               if (verbose > 3)
+                       dprintk("Message = [%02x %02x %02x]\n", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
+
+               for (i = 0; i < 3; i++) {
+                       command = command | p_ca_message->msg[i];
+                       if (i < 2)
+                               command = command << 8;
+               }
+               if (verbose > 3)
+                       dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
+
+               switch (command) {
+                       case CA_APP_INFO:
+                               memcpy(p_ca_message->msg, state->messages, 128);
+                               if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) )
+                                       return -EFAULT;
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int handle_en50221_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
+{
+       if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
+               hw_buffer->msg[2] = p_ca_message->msg[1];               /*              MSB                     */
+               hw_buffer->msg[3] = p_ca_message->msg[2];               /*              LSB                     */
+       }
+       else {
+               hw_buffer->msg[2] = 0x03;
+               hw_buffer->msg[3] = 0x00;
+       }
+       return 0;
+}
+
+static int debug_8820_buffer(struct ca_msg *hw_buffer)
+{
+       unsigned int i;
+
+       dprintk("%s:Debug=[", __FUNCTION__);
+       for (i = 0; i < (hw_buffer->msg[0] + 1); i++)
+               dprintk(" %02x", hw_buffer->msg[i]);
+       dprintk("]\n");
+
+       return 0;
+}
+
+static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 reply)
+{
+       if ((dst_put_ci(state, hw_buffer->msg, (hw_buffer->length + 1), hw_buffer->msg, reply)) < 0) {
+               dprintk("%s: DST-CI Command failed.\n", __FUNCTION__);
+               dprintk("%s: Resetting DST.\n", __FUNCTION__);
+               rdc_reset_state(state);
+               return -1;
+       }
+       if (verbose > 2)
+               dprintk("%s: DST-CI Command succes.\n", __FUNCTION__);
+
+       return 0;
+}
+
+
+static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
+{
+       u32 hw_offset, buf_offset, i, k;
+       u32 program_info_length = 0, es_info_length = 0, length = 0, words = 0;
+       u8 found_prog_ca_desc = 0, found_stream_ca_desc = 0, error_condition = 0, hw_buffer_length = 0;
+
+       if (verbose > 3)
+               dprintk("%s, p_ca_message length %d (0x%x)\n", __FUNCTION__,p_ca_message->length,p_ca_message->length );
+
+       handle_en50221_tag(state, p_ca_message, hw_buffer);                     /*      EN50221 tag             */
+
+       /*      Handle the length field (variable)      */
+       if (!(p_ca_message->msg[3] & 0x80)) {                           /*      Length = 1              */
+               length = p_ca_message->msg[3] & 0x7f;
+               words = 0;                                              /*      domi's suggestion       */
+       }
+       else {                                                          /*      Length = words          */
+               words = p_ca_message->msg[3] & 0x7f;
+               for (i = 0; i < words; i++) {
+                       length = length << 8;
+                       length = length | p_ca_message->msg[4 + i];
+               }
+       }
+       if (verbose > 4) {
+               dprintk("%s:Length=[%d (0x%x)], Words=[%d]\n", __FUNCTION__, length,length, words);
+
+               /*      Debug Input string              */
+               for (i = 0; i < length; i++)
+                       dprintk(" %02x", p_ca_message->msg[i]);
+               dprintk("]\n");
+       }
+
+       hw_offset = 7;
+       buf_offset = words + 4;
+
+       /*              Program Header                  */
+       if (verbose > 4)
+               dprintk("\n%s:Program Header=[", __FUNCTION__);
+       for (i = 0; i < 6; i++) {
+               hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
+               if (verbose > 4)
+                       dprintk(" %02x", p_ca_message->msg[buf_offset]);
+               hw_offset++, buf_offset++, hw_buffer_length++;
+       }
+       if (verbose > 4)
+               dprintk("]\n");
+
+       program_info_length = 0;
+       program_info_length = (((program_info_length | p_ca_message->msg[words + 8]) & 0x0f) << 8) | p_ca_message->msg[words + 9];
+       if (verbose > 4)
+               dprintk("%s:Program info Length=[%d][%02x], hw_offset=[%d], buf_offset=[%d] \n",
+                       __FUNCTION__, program_info_length, program_info_length, hw_offset, buf_offset);
+
+       if (program_info_length && (program_info_length < 256)) {       /*      If program_info_length          */
+               hw_buffer->msg[11] = hw_buffer->msg[11] & 0x0f;         /*      req only 4 bits                 */
+               hw_buffer->msg[12] = hw_buffer->msg[12] + 1;            /*      increment! ASIC bug!            */
+
+               if (p_ca_message->msg[buf_offset + 1] == 0x09) {        /*      Check CA descriptor             */
+                       found_prog_ca_desc = 1;
+                       if (verbose > 4)
+                               dprintk("%s: Found CA descriptor @ Program level\n", __FUNCTION__);
+               }
+
+               if (found_prog_ca_desc) {                               /*      Command only if CA descriptor   */
+                       hw_buffer->msg[13] = p_ca_message->msg[buf_offset];     /*      CA PMT command ID       */
+                       hw_offset++, buf_offset++, hw_buffer_length++;
+               }
+
+               /*                      Program descriptors                             */
+               if (verbose > 4) {
+                       dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
+                       dprintk("%s:Program descriptors=[", __FUNCTION__);
+               }
+               while (program_info_length && !error_condition) {               /*      Copy prog descriptors   */
+                       if (program_info_length > p_ca_message->length) {       /*      Error situation         */
+                               dprintk ("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d]\n",
+                                                               __FUNCTION__, __LINE__, program_info_length);
+                               dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
+                               error_condition = 1;
+                               break;
+                       }
+
+                       hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
+                       dprintk(" %02x", p_ca_message->msg[buf_offset]);
+                       hw_offset++, buf_offset++, hw_buffer_length++, program_info_length--;
+               }
+               if (verbose > 4) {
+                       dprintk("]\n");
+                       dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
+               }
+               if (found_prog_ca_desc) {
+                       if (!reply) {
+                               hw_buffer->msg[13] = 0x01;              /*      OK descrambling                 */
+                               if (verbose > 1)
+                                       dprintk("CA PMT Command = OK Descrambling\n");
+                       }
+                       else {
+                               hw_buffer->msg[13] = 0x02;              /*      Ok MMI                          */
+                               if (verbose > 1)
+                                       dprintk("CA PMT Command = Ok MMI\n");
+                       }
+                       if (query) {
+                               hw_buffer->msg[13] = 0x03;              /*      Query                           */
+                               if (verbose > 1)
+                                       dprintk("CA PMT Command = CA PMT query\n");
+                       }
+               }
+       }
+       else {
+               hw_buffer->msg[11] = hw_buffer->msg[11] & 0xf0;         /*      Don't write to ASIC             */
+               hw_buffer->msg[12] = hw_buffer->msg[12] = 0x00;
+       }
+       if (verbose > 4)
+               dprintk("%s:**********>p_ca_message->length=[%d], buf_offset=[%d], hw_offset=[%d]\n",
+                                       __FUNCTION__, p_ca_message->length, buf_offset, hw_offset);
+
+       while ((buf_offset  < p_ca_message->length)  && !error_condition) {
+               /*      Bail out in case of an indefinite loop          */
+               if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
+                       dprintk("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d], buf_offset=[%d]\n",
+                                                       __FUNCTION__, __LINE__, program_info_length, buf_offset);
+
+                       dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
+                       error_condition = 1;
+                       break;
+               }
+
+               /*              Stream Header                           */
+
+               for (k = 0; k < 5; k++) {
+                       hw_buffer->msg[hw_offset + k] = p_ca_message->msg[buf_offset + k];
+               }
+
+               es_info_length = 0;
+               es_info_length = (es_info_length | (p_ca_message->msg[buf_offset + 3] & 0x0f)) << 8 | p_ca_message->msg[buf_offset + 4];
+
+               if (verbose > 4) {
+                       dprintk("\n%s:----->Stream header=[%02x %02x %02x %02x %02x]\n", __FUNCTION__,
+                               p_ca_message->msg[buf_offset + 0], p_ca_message->msg[buf_offset + 1],
+                               p_ca_message->msg[buf_offset + 2], p_ca_message->msg[buf_offset + 3],
+                               p_ca_message->msg[buf_offset + 4]);
+
+                       dprintk("%s:----->Stream type=[%02x], es length=[%d (0x%x)], Chars=[%02x] [%02x], buf_offset=[%d]\n", __FUNCTION__,
+                               p_ca_message->msg[buf_offset + 0], es_info_length, es_info_length,
+                               p_ca_message->msg[buf_offset + 3], p_ca_message->msg[buf_offset + 4], buf_offset);
+               }
+
+               hw_buffer->msg[hw_offset + 3] &= 0x0f;                  /*      req only 4 bits                 */
+
+               if (found_prog_ca_desc) {
+                       hw_buffer->msg[hw_offset + 3] = 0x00;
+                       hw_buffer->msg[hw_offset + 4] = 0x00;
+               }
+
+               hw_offset += 5, buf_offset += 5, hw_buffer_length += 5;
+
+               /*              Check for CA descriptor                 */
+               if (p_ca_message->msg[buf_offset + 1] == 0x09) {
+                       if (verbose > 4)
+                               dprintk("%s:Found CA descriptor @ Stream level\n", __FUNCTION__);
+                       found_stream_ca_desc = 1;
+               }
+
+               /*              ES descriptors                          */
+
+               if (es_info_length && !error_condition && !found_prog_ca_desc && found_stream_ca_desc) {
+//                     if (!ca_pmt_done) {
+                               hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];      /*      CA PMT cmd(es)  */
+                               if (verbose > 4)
+                                       printk("%s:----->CA PMT Command ID=[%02x]\n", __FUNCTION__, p_ca_message->msg[buf_offset]);
+//                             hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--, ca_pmt_done = 1;
+                               hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
+//                     }
+                       if (verbose > 4)
+                               dprintk("%s:----->ES descriptors=[", __FUNCTION__);
+
+                       while (es_info_length && !error_condition) {    /*      ES descriptors                  */
+                               if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
+                                       if (verbose > 4) {
+                                               dprintk("%s:\"WARNING\" ES Length error, line=[%d], es_info_length=[%d], buf_offset=[%d]\n",
+                                                                               __FUNCTION__, __LINE__, es_info_length, buf_offset);
+
+                                               dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
+                                       }
+                                       error_condition = 1;
+                                       break;
+                               }
+
+                               hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
+                               if (verbose > 3)
+                                       dprintk("%02x ", hw_buffer->msg[hw_offset]);
+                               hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
+                       }
+                       found_stream_ca_desc = 0;                       /*      unset for new streams           */
+                       dprintk("]\n");
+               }
+       }
+
+       /*              MCU Magic words                                 */
+
+       hw_buffer_length += 7;
+       hw_buffer->msg[0] = hw_buffer_length;
+       hw_buffer->msg[1] = 64;
+       hw_buffer->msg[4] = 3;
+       hw_buffer->msg[5] = hw_buffer->msg[0] - 7;
+       hw_buffer->msg[6] = 0;
+
+
+       /*      Fix length      */
+       hw_buffer->length = hw_buffer->msg[0];
+
+       put_checksum(&hw_buffer->msg[0], hw_buffer->msg[0]);
+       /*      Do the actual write     */
+       if (verbose > 4) {
+               dprintk("%s:======================DEBUGGING================================\n", __FUNCTION__);
+               dprintk("%s: Actual Length=[%d]\n", __FUNCTION__, hw_buffer_length);
+       }
+       /*      Only for debugging!     */
+       if (verbose > 2)
+               debug_8820_buffer(hw_buffer);
+       if (verbose > 3)
+               dprintk("%s: Reply = [%d]\n", __FUNCTION__, reply);
+       write_to_8820(state, hw_buffer, reply);
+
+       return 0;
+}
+
+/*     Board supports CA PMT reply ?           */
+static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
+{
+       int ca_pmt_reply_test = 0;
+
+       /*      Do test board                   */
+       /*      Not there yet but soon          */
+
+
+       /*      CA PMT Reply capable            */
+       if (ca_pmt_reply_test) {
+               if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
+                       dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
+                       return -1;
+               }
+
+       /*      Process CA PMT Reply            */
+       /*      will implement soon             */
+               dprintk("%s: Not there yet\n", __FUNCTION__);
+       }
+       /*      CA PMT Reply not capable        */
+       if (!ca_pmt_reply_test) {
+               if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
+                       dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
+                       return -1;
+               }
+               if (verbose > 3)
+                       dprintk("%s: ca_set_pmt.. success !\n", __FUNCTION__);
+       /*      put a dummy message             */
+
+       }
+       return 0;
+}
+
+static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
+{
+       int i = 0;
+       unsigned int ca_message_header_len;
+
+       u32 command = 0;
+       struct ca_msg *hw_buffer;
+
+       if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
+               printk("%s: Memory allocation failure\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+       if (verbose > 3)
+               dprintk("%s\n", __FUNCTION__);
+
+       if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
+               return -EFAULT;
+
+       if (p_ca_message->msg) {
+               ca_message_header_len = p_ca_message->length;   /*      Restore it back when you are done       */
+               /*      EN50221 tag     */
+               command = 0;
+
+               for (i = 0; i < 3; i++) {
+                       command = command | p_ca_message->msg[i];
+                       if (i < 2)
+                               command = command << 8;
+               }
+               if (verbose > 3)
+                       dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
+
+               switch (command) {
+                       case CA_PMT:
+                               if (verbose > 3)
+                                       dprintk("Command = SEND_CA_PMT\n");
+                               if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
+                                       dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__);
+                                       return -1;
+                               }
+                               if (verbose > 3)
+                                       dprintk("%s: -->CA_PMT Success !\n", __FUNCTION__);
+//                             retval = dummy_set_pmt(state, p_ca_message, hw_buffer, 0, 0);
+
+                               break;
+
+                       case CA_PMT_REPLY:
+                               if (verbose > 3)
+                                       dprintk("Command = CA_PMT_REPLY\n");
+                               /*      Have to handle the 2 basic types of cards here  */
+                               if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
+                                       dprintk("%s: -->CA_PMT_REPLY Failed !\n", __FUNCTION__);
+                                       return -1;
+                               }
+                               if (verbose > 3)
+                                       dprintk("%s: -->CA_PMT_REPLY Success !\n", __FUNCTION__);
+
+                               /*      Certain boards do behave different ?            */
+//                             retval = ca_set_pmt(state, p_ca_message, hw_buffer, 1, 1);
+
+                       case CA_APP_INFO_ENQUIRY:               // only for debugging
+                               if (verbose > 3)
+                                       dprintk("%s: Getting Cam Application information\n", __FUNCTION__);
+
+                               if ((ca_get_app_info(state)) < 0) {
+                                       dprintk("%s: -->CA_APP_INFO_ENQUIRY Failed !\n", __FUNCTION__);
+                                       return -1;
+                               }
+                               if (verbose > 3)
+                                       printk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
+
+                               break;
+               }
+       }
+       return 0;
+}
+
+static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
+{
+       struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
+       struct dst_state* state = (struct dst_state*) dvbdev->priv;
+       struct ca_slot_info *p_ca_slot_info;
+       struct ca_caps *p_ca_caps;
+       struct ca_msg *p_ca_message;
+
+       if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
+               printk("%s: Memory allocation failure\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
+               printk("%s: Memory allocation failure\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
+               printk("%s: Memory allocation failure\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       /*      We have now only the standard ioctl's, the driver is upposed to handle internals.       */
+       switch (cmd) {
+               case CA_SEND_MSG:
+                       if (verbose > 1)
+                               dprintk("%s: Sending message\n", __FUNCTION__);
+                       if ((ca_send_message(state, p_ca_message, arg)) < 0) {
+                               dprintk("%s: -->CA_SEND_MSG Failed !\n", __FUNCTION__);
+                               return -1;
+                       }
+
+                       break;
+
+               case CA_GET_MSG:
+                       if (verbose > 1)
+                               dprintk("%s: Getting message\n", __FUNCTION__);
+                       if ((ca_get_message(state, p_ca_message, arg)) < 0) {
+                               dprintk("%s: -->CA_GET_MSG Failed !\n", __FUNCTION__);
+                               return -1;
+                       }
+                       if (verbose > 1)
+                               dprintk("%s: -->CA_GET_MSG Success !\n", __FUNCTION__);
+
+                       break;
+
+               case CA_RESET:
+                       if (verbose > 1)
+                               dprintk("%s: Resetting DST\n", __FUNCTION__);
+                       dst_error_bailout(state);
+                       msleep(4000);
+
+                       break;
+
+               case CA_GET_SLOT_INFO:
+                       if (verbose > 1)
+                               dprintk("%s: Getting Slot info\n", __FUNCTION__);
+                       if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
+                               dprintk("%s: -->CA_GET_SLOT_INFO Failed !\n", __FUNCTION__);
+                               return -1;
+                       }
+                       if (verbose > 1)
+                               dprintk("%s: -->CA_GET_SLOT_INFO Success !\n", __FUNCTION__);
+
+                       break;
+
+               case CA_GET_CAP:
+                       if (verbose > 1)
+                               dprintk("%s: Getting Slot capabilities\n", __FUNCTION__);
+                       if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
+                               dprintk("%s: -->CA_GET_CAP Failed !\n", __FUNCTION__);
+                               return -1;
+                       }
+                       if (verbose > 1)
+                               dprintk("%s: -->CA_GET_CAP Success !\n", __FUNCTION__);
+
+                       break;
+
+               case CA_GET_DESCR_INFO:
+                       if (verbose > 1)
+                               dprintk("%s: Getting descrambler description\n", __FUNCTION__);
+                       if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
+                               dprintk("%s: -->CA_GET_DESCR_INFO Failed !\n", __FUNCTION__);
+                               return -1;
+                       }
+                       if (verbose > 1)
+                               dprintk("%s: -->CA_GET_DESCR_INFO Success !\n", __FUNCTION__);
+
+                       break;
+
+               case CA_SET_DESCR:
+                       if (verbose > 1)
+                               dprintk("%s: Setting descrambler\n", __FUNCTION__);
+                       if ((ca_set_slot_descr()) < 0) {
+                               dprintk("%s: -->CA_SET_DESCR Failed !\n", __FUNCTION__);
+                               return -1;
+                       }
+                       if (verbose > 1)
+                               dprintk("%s: -->CA_SET_DESCR Success !\n", __FUNCTION__);
+
+                       break;
+
+               case CA_SET_PID:
+                       if (verbose > 1)
+                               dprintk("%s: Setting PID\n", __FUNCTION__);
+                       if ((ca_set_pid()) < 0) {
+                               dprintk("%s: -->CA_SET_PID Failed !\n", __FUNCTION__);
+                               return -1;
+                       }
+                       if (verbose > 1)
+                               dprintk("%s: -->CA_SET_PID Success !\n", __FUNCTION__);
+
+               default:
+                       return -EOPNOTSUPP;
+               };
+
+       return 0;
+}
+
+static int dst_ca_open(struct inode *inode, struct file *file)
+{
+       if (verbose > 4)
+               dprintk("%s:Device opened [%p]\n", __FUNCTION__, file);
+       try_module_get(THIS_MODULE);
+
+       return 0;
+}
+
+static int dst_ca_release(struct inode *inode, struct file *file)
+{
+       if (verbose > 4)
+               dprintk("%s:Device closed.\n", __FUNCTION__);
+       module_put(THIS_MODULE);
+
+       return 0;
+}
+
+static int dst_ca_read(struct file *file, char __user * buffer, size_t length, loff_t * offset)
+{
+       int bytes_read = 0;
+
+       if (verbose > 4)
+               dprintk("%s:Device read.\n", __FUNCTION__);
+
+       return bytes_read;
+}
+
+static int dst_ca_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset)
+{
+       if (verbose > 4)
+               dprintk("%s:Device write.\n", __FUNCTION__);
+
+       return 0;
+}
+
+static struct file_operations dst_ca_fops = {
+       .owner = THIS_MODULE,
+       .ioctl = (void *)dst_ca_ioctl,
+       .open = dst_ca_open,
+       .release = dst_ca_release,
+       .read = dst_ca_read,
+       .write = dst_ca_write
+};
+
+static struct dvb_device dvbdev_ca = {
+       .priv = NULL,
+       .users = 1,
+       .readers = 1,
+       .writers = 1,
+       .fops = &dst_ca_fops
+};
+
+int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
+{
+       struct dvb_device *dvbdev;
+       if (verbose > 4)
+               dprintk("%s:registering DST-CA device\n", __FUNCTION__);
+       dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA);
+       return 0;
+}
+
+EXPORT_SYMBOL(dst_ca_attach);
+
+MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst_ca.h b/drivers/media/dvb/bt8xx/dst_ca.h
new file mode 100644 (file)
index 0000000..59cd0dd
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+       CA-driver for TwinHan DST Frontend/Card
+
+       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _DST_CA_H_
+#define _DST_CA_H_
+
+#define RETRIES                        5
+
+
+#define        CA_APP_INFO_ENQUIRY     0x9f8020
+#define        CA_APP_INFO             0x9f8021
+#define        CA_ENTER_MENU           0x9f8022
+#define CA_INFO_ENQUIRY                0x9f8030
+#define        CA_INFO                 0x9f8031
+#define CA_PMT                 0x9f8032
+#define CA_PMT_REPLY           0x9f8033
+
+#define CA_CLOSE_MMI           0x9f8800
+#define CA_DISPLAY_CONTROL     0x9f8801
+#define CA_DISPLAY_REPLY       0x9f8802
+#define CA_TEXT_LAST           0x9f8803
+#define CA_TEXT_MORE           0x9f8804
+#define CA_KEYPAD_CONTROL      0x9f8805
+#define CA_KEYPRESS            0x9f8806
+
+#define CA_ENQUIRY             0x9f8807
+#define CA_ANSWER              0x9f8808
+#define CA_MENU_LAST           0x9f8809
+#define CA_MENU_MORE           0x9f880a
+#define CA_MENU_ANSWER         0x9f880b
+#define CA_LIST_LAST           0x9f880c
+#define CA_LIST_MORE           0x9f880d
+
+
+struct dst_ca_private {
+       struct dst_state *dst;
+       struct dvb_device *dvbdev;
+};
+
+
+#endif
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
new file mode 100644 (file)
index 0000000..0b3da29
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+       Frontend-driver for TwinHan DST Frontend
+
+       Copyright (C) 2003 Jamie Honan
+       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef DST_COMMON_H
+#define DST_COMMON_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/device.h>
+#include "bt878.h"
+
+#include "dst_ca.h"
+
+
+#define NO_DELAY               0
+#define LONG_DELAY             1
+#define DEVICE_INIT            2
+
+#define DELAY                  1
+
+#define DST_TYPE_IS_SAT                0
+#define DST_TYPE_IS_TERR       1
+#define DST_TYPE_IS_CABLE      2
+#define DST_TYPE_IS_ATSC       3
+
+#define DST_TYPE_HAS_NEWTUNE   1
+#define DST_TYPE_HAS_TS204     2
+#define DST_TYPE_HAS_SYMDIV    4
+#define DST_TYPE_HAS_FW_1      8
+#define DST_TYPE_HAS_FW_2      16
+#define DST_TYPE_HAS_FW_3      32
+#define DST_TYPE_HAS_FW_BUILD  64
+
+/*     Card capability list    */
+
+#define DST_TYPE_HAS_MAC       1
+#define DST_TYPE_HAS_DISEQC3   2
+#define DST_TYPE_HAS_DISEQC4   4
+#define DST_TYPE_HAS_DISEQC5   8
+#define DST_TYPE_HAS_MOTO      16
+#define DST_TYPE_HAS_CA                32
+#define        DST_TYPE_HAS_ANALOG     64      /*      Analog inputs   */
+#define DST_TYPE_HAS_SESSION   128
+
+
+#define RDC_8820_PIO_0_DISABLE 0
+#define RDC_8820_PIO_0_ENABLE  1
+#define RDC_8820_INT           2
+#define RDC_8820_RESET         4
+
+/*     DST Communication       */
+#define GET_REPLY              1
+#define NO_REPLY               0
+
+#define GET_ACK                        1
+#define FIXED_COMM             8
+
+#define ACK                    0xff
+
+struct dst_state {
+
+       struct i2c_adapter* i2c;
+
+       struct bt878* bt;
+
+       struct dvb_frontend_ops ops;
+
+       /* configuration settings */
+       const struct dst_config* config;
+
+       struct dvb_frontend frontend;
+
+       /* private ASIC data */
+       u8 tx_tuna[10];
+       u8 rx_tuna[10];
+       u8 rxbuffer[10];
+       u8 diseq_flags;
+       u8 dst_type;
+       u32 type_flags;
+       u32 frequency;          /* intermediate frequency in kHz for QPSK */
+       fe_spectral_inversion_t inversion;
+       u32 symbol_rate;        /* symbol rate in Symbols per second */
+       fe_code_rate_t fec;
+       fe_sec_voltage_t voltage;
+       fe_sec_tone_mode_t tone;
+       u32 decode_freq;
+       u8 decode_lock;
+       u16 decode_strength;
+       u16 decode_snr;
+       unsigned long cur_jiff;
+       u8 k22;
+       fe_bandwidth_t bandwidth;
+       u32 dst_hw_cap;
+       u8 dst_fw_version;
+       fe_sec_mini_cmd_t minicmd;
+       u8 messages[256];
+};
+
+struct dst_types {
+       char *device_id;
+       int offset;
+       u8 dst_type;
+       u32 type_flags;
+       u32 dst_feature;
+};
+
+
+
+struct dst_config
+{
+       /* the ASIC i2c address */
+       u8 demod_address;
+};
+
+
+int rdc_reset_state(struct dst_state *state);
+int rdc_8820_reset(struct dst_state *state);
+
+int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode);
+int dst_pio_enable(struct dst_state *state);
+int dst_pio_disable(struct dst_state *state);
+int dst_error_recovery(struct dst_state* state);
+int dst_error_bailout(struct dst_state *state);
+int dst_comm_init(struct dst_state* state);
+
+int write_dst(struct dst_state *state, u8 * data, u8 len);
+int read_dst(struct dst_state *state, u8 * ret, u8 len);
+u8 dst_check_sum(u8 * buf, u32 len);
+struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter);
+int dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
+int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay);
+
+int dst_command(struct dst_state* state, u8 * data, u8 len);
+
+
+#endif // DST_COMMON_H
index 80488aa628b40fb785581d76b967079081202242..3974a4c6ebe75c704dc8d4ed5bb87788d5788362 100644 (file)
@@ -33,4 +33,3 @@ union dst_gpio_packet {
 struct bt878;
 
 int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp);
-
index b735397f59aad475beae62dc744badf5633c0799..6f857c6091f34ecbb9c6e5874e0049a3d5406f1e 100644 (file)
@@ -142,7 +142,7 @@ static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
        mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
 
        mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
-        mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
+       mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
        mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
 
        return 0;
@@ -161,7 +161,7 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
        else if (params->frequency < 771000000) cp = 0xbc;
        else cp = 0xf4;
 
-        if (params->frequency == 0) bs = 0x03;
+       if (params->frequency == 0) bs = 0x03;
        else if (params->frequency < 443250000) bs = 0x02;
        else bs = 0x08;
 
@@ -190,44 +190,44 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
 
 
    u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
-               1576000,1718000,1856000,2036000,2150000};
+              1576000,1718000,1856000,2036000,2150000};
    u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
-               0x00102000,0x00104000,0x00108000,0x00110000,
-               0x00120000,0x00140000};
+              0x00102000,0x00104000,0x00108000,0x00110000,
+              0x00120000,0x00140000};
 
 #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
-        printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
-
-        /* This is really the bit driving the tuner chip cx24108 */
-
-        if(freq<950000) freq=950000; /* kHz */
-        if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */
-
-        /* decide which VCO to use for the input frequency */
-        for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++);
-        printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
-        band=bandsel[i];
-        /* the gain values must be set by SetSymbolrate */
-        /* compute the pll divider needed, from Conexant data sheet,
-           resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
-           depending on the divider bit. It is set to /4 on the 2 lowest
-           bands  */
-        n=((i<=2?2:1)*freq*10L)/(XTAL/100);
-        a=n%32; n/=32; if(a==0) n--;
-        pump=(freq<(osci[i-1]+osci[i])/2);
-        pll=0xf8000000|
-            ((pump?1:2)<<(14+11))|
-            ((n&0x1ff)<<(5+11))|
-            ((a&0x1f)<<11);
-        /* everything is shifted left 11 bits to left-align the bits in the
-           32bit word. Output to the tuner goes MSB-aligned, after all */
-        printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a);
-        cx24110_pll_write(fe,band);
-        /* set vga and vca to their widest-band settings, as a precaution.
-           SetSymbolrate might not be called to set this up */
-        cx24110_pll_write(fe,0x500c0000);
-        cx24110_pll_write(fe,0x83f1f800);
-        cx24110_pll_write(fe,pll);
+       printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
+
+       /* This is really the bit driving the tuner chip cx24108 */
+
+       if(freq<950000) freq=950000; /* kHz */
+       if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */
+
+       /* decide which VCO to use for the input frequency */
+       for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++);
+       printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
+       band=bandsel[i];
+       /* the gain values must be set by SetSymbolrate */
+       /* compute the pll divider needed, from Conexant data sheet,
+          resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
+          depending on the divider bit. It is set to /4 on the 2 lowest
+          bands  */
+       n=((i<=2?2:1)*freq*10L)/(XTAL/100);
+       a=n%32; n/=32; if(a==0) n--;
+       pump=(freq<(osci[i-1]+osci[i])/2);
+       pll=0xf8000000|
+           ((pump?1:2)<<(14+11))|
+           ((n&0x1ff)<<(5+11))|
+           ((a&0x1f)<<11);
+       /* everything is shifted left 11 bits to left-align the bits in the
+          32bit word. Output to the tuner goes MSB-aligned, after all */
+       printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a);
+       cx24110_pll_write(fe,band);
+       /* set vga and vca to their widest-band settings, as a precaution.
+          SetSymbolrate might not be called to set this up */
+       cx24110_pll_write(fe,0x500c0000);
+       cx24110_pll_write(fe,0x83f1f800);
+       cx24110_pll_write(fe,pll);
 /*        writereg(client,0x56,0x7f);*/
 
        return 0;
@@ -299,7 +299,7 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
        static u8 mt352_reset [] = { 0x50, 0x80 };
        static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
        static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
-                                      0x00, 0xFF, 0x00, 0x40, 0x40 };
+                                      0x00, 0xFF, 0x00, 0x40, 0x40 };
        static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
        static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
 
@@ -463,6 +463,9 @@ static struct nxt6000_config vp3021_alps_tded4_config = {
 
 static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
 {
+       int ret;
+       struct dst_state* state = NULL;
+
        switch(type) {
 #ifdef BTTV_DVICO_DVBT_LITE
        case BTTV_DVICO_DVBT_LITE:
@@ -503,7 +506,25 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
                break;
 
        case BTTV_TWINHAN_DST:
-               card->fe = dst_attach(&dst_config, card->i2c_adapter, card->bt);
+               /*      DST is not a frontend driver !!!                */
+               state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
+               /*      Setup the Card                                  */
+               state->config = &dst_config;
+               state->i2c = card->i2c_adapter;
+               state->bt = card->bt;
+
+               /*      DST is not a frontend, attaching the ASIC       */
+               if ((dst_attach(state, &card->dvb_adapter)) == NULL) {
+                       printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__);
+                       break;
+               }
+               card->fe = &state->frontend;
+
+               /*      Attach other DST peripherals if any             */
+               /*      Conditional Access device                       */
+               if (state->dst_hw_cap & DST_TYPE_HAS_CA) {
+                       ret = dst_ca_attach(state, &card->dvb_adapter);
+               }
                if (card->fe != NULL) {
                        break;
                }
@@ -531,7 +552,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
                       card->bt->dev->subsystem_vendor,
                       card->bt->dev->subsystem_device);
        } else {
-               if (dvb_register_frontend(card->dvb_adapter, card->fe)) {
+               if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
                        printk("dvb-bt8xx: Frontend registration failed!\n");
                        if (card->fe->ops->release)
                                card->fe->ops->release(card->fe);
@@ -550,7 +571,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
                return result;
 
        }
-       card->dvb_adapter->priv = card;
+       card->dvb_adapter.priv = card;
 
        card->bt->adapter = card->i2c_adapter;
 
@@ -568,7 +589,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
        if ((result = dvb_dmx_init(&card->demux)) < 0) {
                printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
 
-               dvb_unregister_adapter(card->dvb_adapter);
+               dvb_unregister_adapter(&card->dvb_adapter);
                return result;
        }
 
@@ -576,11 +597,11 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
        card->dmxdev.demux = &card->demux.dmx;
        card->dmxdev.capabilities = 0;
 
-       if ((result = dvb_dmxdev_init(&card->dmxdev, card->dvb_adapter)) < 0) {
+       if ((result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter)) < 0) {
                printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result);
 
                dvb_dmx_release(&card->demux);
-               dvb_unregister_adapter(card->dvb_adapter);
+               dvb_unregister_adapter(&card->dvb_adapter);
                return result;
        }
 
@@ -591,7 +612,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
 
                dvb_dmxdev_release(&card->dmxdev);
                dvb_dmx_release(&card->demux);
-               dvb_unregister_adapter(card->dvb_adapter);
+               dvb_unregister_adapter(&card->dvb_adapter);
                return result;
        }
 
@@ -603,7 +624,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
                card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
                dvb_dmxdev_release(&card->dmxdev);
                dvb_dmx_release(&card->demux);
-               dvb_unregister_adapter(card->dvb_adapter);
+               dvb_unregister_adapter(&card->dvb_adapter);
                return result;
        }
 
@@ -614,11 +635,11 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
                card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
                dvb_dmxdev_release(&card->dmxdev);
                dvb_dmx_release(&card->demux);
-               dvb_unregister_adapter(card->dvb_adapter);
+               dvb_unregister_adapter(&card->dvb_adapter);
                return result;
        }
 
-       dvb_net_init(card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
+       dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
 
        tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
 
@@ -648,7 +669,7 @@ static int dvb_bt8xx_probe(struct device *dev)
        case BTTV_PINNACLESAT:
                card->gpio_mode = 0x0400c060;
                /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
-                             BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
+                             BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
                card->op_sync_orin = 0;
                card->irq_err_ignore = 0;
                break;
@@ -759,7 +780,7 @@ static int dvb_bt8xx_remove(struct device *dev)
        dvb_dmxdev_release(&card->dmxdev);
        dvb_dmx_release(&card->demux);
        if (card->fe) dvb_unregister_frontend(card->fe);
-       dvb_unregister_adapter(card->dvb_adapter);
+       dvb_unregister_adapter(&card->dvb_adapter);
 
        kfree(card);
 
index 80ef189f930f34cac24662c68b7d7284aaab2466..2923b3b0dd3ce3168d27964d7d78229a80d191fb 100644 (file)
@@ -31,7 +31,7 @@
 #include "bttv.h"
 #include "mt352.h"
 #include "sp887x.h"
-#include "dst.h"
+#include "dst_common.h"
 #include "nxt6000.h"
 #include "cx24110.h"
 #include "or51211.h"
@@ -40,7 +40,7 @@ struct dvb_bt8xx_card {
        struct semaphore lock;
        int nfeeds;
        char card_name[32];
-       struct dvb_adapter *dvb_adapter;
+       struct dvb_adapter dvb_adapter;
        struct bt878 *bt;
        unsigned int bttv_nr;
        struct dvb_demux demux;
index 28d4d926de3e1540ca448eb0b5532ca0838d4ee3..96c57fde95a0da96efd4e16f47c8417837ee7a2c 100644 (file)
@@ -119,7 +119,7 @@ struct cinergyt2 {
        struct dvb_demux demux;
        struct usb_device *udev;
        struct semaphore sem;
-       struct dvb_adapter *adapter;
+       struct dvb_adapter adapter;
        struct dvb_device *fedev;
        struct dmxdev dmxdev;
        struct dvb_net dvbnet;
@@ -813,15 +813,15 @@ static int cinergyt2_probe (struct usb_interface *intf,
        cinergyt2->dmxdev.demux = &cinergyt2->demux.dmx;
        cinergyt2->dmxdev.capabilities = 0;
 
-       if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, cinergyt2->adapter)) < 0) {
+       if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, &cinergyt2->adapter)) < 0) {
                dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err);
                goto bailout;
        }
 
-       if (dvb_net_init(cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx))
+       if (dvb_net_init(&cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx))
                dprintk(1, "dvb_net_init() failed!\n");
 
-       dvb_register_device(cinergyt2->adapter, &cinergyt2->fedev,
+       dvb_register_device(&cinergyt2->adapter, &cinergyt2->fedev,
                            &cinergyt2_fe_template, cinergyt2,
                            DVB_DEVICE_FRONTEND);
 
@@ -848,7 +848,7 @@ static int cinergyt2_probe (struct usb_interface *intf,
 bailout:
        dvb_dmxdev_release(&cinergyt2->dmxdev);
        dvb_dmx_release(&cinergyt2->demux);
-       dvb_unregister_adapter (cinergyt2->adapter);
+       dvb_unregister_adapter (&cinergyt2->adapter);
        cinergyt2_free_stream_urbs (cinergyt2);
        kfree(cinergyt2);
        return -ENOMEM;
@@ -872,7 +872,7 @@ static void cinergyt2_disconnect (struct usb_interface *intf)
        dvb_dmxdev_release(&cinergyt2->dmxdev);
        dvb_dmx_release(&cinergyt2->demux);
        dvb_unregister_device(cinergyt2->fedev);
-       dvb_unregister_adapter(cinergyt2->adapter);
+       dvb_unregister_adapter(&cinergyt2->adapter);
 
        cinergyt2_free_stream_urbs(cinergyt2);
        up(&cinergyt2->sem);
index 04e54ec093f0b6ea3983b6dfcd2c1ebcefb623bf..400b439e804e991962accef1f01972eb8ca202be 100644 (file)
@@ -131,7 +131,7 @@ int dibusb_dvb_init(struct usb_dibusb *dib)
                deb_info("dvb_register_adapter failed: error %d", ret);
                goto err;
        }
-       dib->adapter->priv = dib;
+       dib->adapter.priv = dib;
        
 /* i2c is done in dibusb_i2c_init */
        
@@ -151,18 +151,18 @@ int dibusb_dvb_init(struct usb_dibusb *dib)
        dib->dmxdev.filternum = dib->demux.filternum;
        dib->dmxdev.demux = &dib->demux.dmx;
        dib->dmxdev.capabilities = 0;
-       if ((ret = dvb_dmxdev_init(&dib->dmxdev, dib->adapter)) < 0) {
+       if ((ret = dvb_dmxdev_init(&dib->dmxdev, &dib->adapter)) < 0) {
                err("dvb_dmxdev_init failed: error %d",ret);
                goto err_dmx_dev;
        }
 
-       dvb_net_init(dib->adapter, &dib->dvb_net, &dib->demux.dmx);
+       dvb_net_init(&dib->adapter, &dib->dvb_net, &dib->demux.dmx);
 
        goto success;
 err_dmx_dev:
        dvb_dmx_release(&dib->demux);
 err_dmx:
-       dvb_unregister_adapter(dib->adapter);
+       dvb_unregister_adapter(&dib->adapter);
 err:
        return ret;
 success:
@@ -179,7 +179,7 @@ int dibusb_dvb_exit(struct usb_dibusb *dib)
                dib->demux.dmx.close(&dib->demux.dmx);
                dvb_dmxdev_release(&dib->dmxdev);
                dvb_dmx_release(&dib->demux);
-               dvb_unregister_adapter(dib->adapter);
+               dvb_unregister_adapter(&dib->adapter);
        }
        return 0;
 }
index 2ed89488c7c49db9a3a0566d38d59344a35a24dd..5a71b88797d9ca0018e505f643e5474f25603110 100644 (file)
@@ -183,7 +183,7 @@ int dibusb_fe_init(struct usb_dibusb* dib)
                       dib->dibdev->name);
                return -ENODEV;
        } else {
-               if (dvb_register_frontend(dib->adapter, dib->fe)) {
+               if (dvb_register_frontend(&dib->adapter, dib->fe)) {
                        err("Frontend registration failed.");
                        if (dib->fe->ops->release)
                                dib->fe->ops->release(dib->fe);
@@ -206,7 +206,7 @@ int dibusb_i2c_init(struct usb_dibusb *dib)
 {
        int ret = 0;
 
-       dib->adapter->priv = dib;
+       dib->adapter.priv = dib;
 
        strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE);
 #ifdef I2C_ADAP_CLASS_TV_DIGITAL
index 52cd35dd9d838e3fe3634f333996de58bc926918..c965b64fb1ab61c37f39f0f8955cbb8d497444cb 100644 (file)
@@ -181,7 +181,7 @@ struct usb_dibusb {
        struct semaphore i2c_sem;
 
        /* dvb */
-       struct dvb_adapter *adapter;
+       struct dvb_adapter adapter;
        struct dmxdev dmxdev;
        struct dvb_demux demux;
        struct dvb_net dvb_net;
index 1863f1dfb00c54f2d7772161b537573c057cefe6..c225de7ffd82429f61103839a4657df49a440a3c 100644 (file)
@@ -175,8 +175,8 @@ static inline void dvb_dmxdev_dvr_state_set(struct dmxdev_dvr *dmxdevdvr, int st
 
 static int dvb_dvr_open(struct inode *inode, struct file *file)
 {
-       struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
-       struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dmxdev *dmxdev = dvbdev->priv;
        struct dmx_frontend *front;
 
        dprintk ("function : %s\n", __FUNCTION__);
@@ -224,8 +224,8 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
 
 static int dvb_dvr_release(struct inode *inode, struct file *file)
 {
-       struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
-       struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dmxdev *dmxdev = dvbdev->priv;
 
        if (down_interruptible (&dmxdev->mutex))
                return -ERESTARTSYS;
@@ -252,8 +252,8 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
 static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
                size_t count, loff_t *ppos)
 {
-       struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
-       struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dmxdev *dmxdev = dvbdev->priv;
        int ret;
 
        if (!dmxdev->demux->write)
@@ -270,8 +270,8 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
 static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
                loff_t *ppos)
 {
-       struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
-       struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dmxdev *dmxdev = dvbdev->priv;
        int ret;
 
        //down(&dmxdev->mutex);
@@ -345,7 +345,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
                            const u8 *buffer2, size_t buffer2_len,
                            struct dmx_section_filter *filter, enum dmx_success success)
 {
-       struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) filter->priv;
+       struct dmxdev_filter *dmxdevfilter = filter->priv;
        int ret;
 
        if (dmxdevfilter->buffer.error) {
@@ -381,7 +381,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
                       const u8 *buffer2, size_t buffer2_len,
                       struct dmx_ts_feed *feed, enum dmx_success success)
 {
-       struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) feed->priv;
+       struct dmxdev_filter *dmxdevfilter = feed->priv;
        struct dmxdev_buffer *buffer;
        int ret;
 
@@ -684,8 +684,8 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
 
 static int dvb_demux_open(struct inode *inode, struct file *file)
 {
-       struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
-       struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dmxdev *dmxdev = dvbdev->priv;
        int i;
        struct dmxdev_filter *dmxdevfilter;
 
@@ -1013,8 +1013,8 @@ static struct dvb_device dvbdev_demux = {
 static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
                     unsigned int cmd, void *parg)
 {
-       struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
-       struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dmxdev *dmxdev = dvbdev->priv;
 
        int ret=0;
 
@@ -1044,8 +1044,8 @@ static int dvb_dvr_ioctl(struct inode *inode, struct file *file,
 
 static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait)
 {
-       struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-       struct dmxdev *dmxdev = (struct dmxdev *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dmxdev *dmxdev = dvbdev->priv;
        unsigned int mask = 0;
 
        dprintk ("function : %s\n", __FUNCTION__);
index c1ea89f2880ceddf85ea853acaff4b4b5e04c380..0eb9aa711fb0335f44cce5d96faca15de40eb75d 100644 (file)
@@ -829,7 +829,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
  */
 void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type)
 {
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
+       struct dvb_ca_private *ca = pubca->private;
 
        dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type);
 
@@ -857,7 +857,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
  */
 void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
 {
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
+       struct dvb_ca_private *ca = pubca->private;
 
        dprintk("CAMREADY IRQ slot:%i\n", slot);
 
@@ -876,7 +876,7 @@ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
  */
 void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
 {
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
+       struct dvb_ca_private *ca = pubca->private;
        int flags;
 
        dprintk("FR/DA IRQ slot:%i\n", slot);
@@ -993,7 +993,7 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
  */
 static int dvb_ca_en50221_thread(void *data)
 {
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) data;
+       struct dvb_ca_private *ca = data;
        char name[15];
        int slot;
        int flags;
@@ -1202,8 +1202,8 @@ static int dvb_ca_en50221_thread(void *data)
 static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
                                      unsigned int cmd, void *parg)
 {
-       struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dvb_ca_private *ca = dvbdev->priv;
        int err = 0;
        int slot;
 
@@ -1225,7 +1225,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
                break;
 
        case CA_GET_CAP: {
-               struct ca_caps *caps = (struct ca_caps *) parg;
+               struct ca_caps *caps = parg;
 
                caps->slot_num = ca->slot_count;
                caps->slot_type = CA_CI_LINK;
@@ -1235,7 +1235,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
        }
 
        case CA_GET_SLOT_INFO: {
-               struct ca_slot_info *info = (struct ca_slot_info *) parg;
+               struct ca_slot_info *info = parg;
 
                if ((info->num > ca->slot_count) || (info->num < 0))
                        return -EINVAL;
@@ -1291,8 +1291,8 @@ static int dvb_ca_en50221_io_ioctl(struct inode *inode, struct file *file,
 static ssize_t dvb_ca_en50221_io_write(struct file *file,
                                       const char __user * buf, size_t count, loff_t * ppos)
 {
-       struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dvb_ca_private *ca = dvbdev->priv;
        u8 slot, connection_id;
        int status;
        char fragbuf[HOST_LINK_BUF_SIZE];
@@ -1428,8 +1428,8 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, int *resu
 static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
                                      size_t count, loff_t * ppos)
 {
-       struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dvb_ca_private *ca = dvbdev->priv;
        int status;
        int result = 0;
        u8 hdr[2];
@@ -1526,8 +1526,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
  */
 static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
 {
-       struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dvb_ca_private *ca = dvbdev->priv;
        int err;
        int i;
 
@@ -1569,8 +1569,8 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
  */
 static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
 {
-       struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dvb_ca_private *ca = dvbdev->priv;
        int err = 0;
 
        dprintk("%s\n", __FUNCTION__);
@@ -1597,8 +1597,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
  */
 static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
 {
-       struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dvb_ca_private *ca = dvbdev->priv;
        unsigned int mask = 0;
        int slot;
        int result = 0;
@@ -1750,7 +1750,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_release);
  */
 void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
 {
-       struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
+       struct dvb_ca_private *ca = pubca->private;
        int i;
 
        dprintk("%s\n", __FUNCTION__);
index 59a9adfae1ebc909120ea148f3f5593671f7862f..d19301d90a09937a481ef21666096aa121ebf575 100644 (file)
@@ -48,7 +48,7 @@ static int dvb_override_tune_delay;
 static int dvb_powerdown_on_sleep = 1;
 
 module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
-MODULE_PARM_DESC(dvb_frontend_debug, "Turn on/off frontend core debugging (default:off).");
+MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
 module_param(dvb_shutdown_timeout, int, 0444);
 MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");
 module_param(dvb_force_auto_inversion, int, 0444);
@@ -117,7 +117,7 @@ struct dvb_frontend_private {
 
 static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
 {
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
        struct dvb_fe_events *events = &fepriv->events;
        struct dvb_frontend_event *e;
        int wp;
@@ -155,7 +155,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
 static int dvb_frontend_get_event(struct dvb_frontend *fe,
                            struct dvb_frontend_event *event, int flags)
 {
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
        struct dvb_fe_events *events = &fepriv->events;
 
        dprintk ("%s\n", __FUNCTION__);
@@ -234,7 +234,7 @@ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped)
 {
        int autoinversion;
        int ready = 0;
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
        int original_inversion = fepriv->parameters.inversion;
        u32 original_frequency = fepriv->parameters.frequency;
 
@@ -321,7 +321,7 @@ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped)
 
 static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
 {
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
        if (fepriv->exit)
                return 1;
@@ -335,7 +335,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
 
 static int dvb_frontend_should_wakeup(struct dvb_frontend *fe)
 {
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
        if (fepriv->wakeup) {
                fepriv->wakeup = 0;
@@ -346,7 +346,7 @@ static int dvb_frontend_should_wakeup(struct dvb_frontend *fe)
 
 static void dvb_frontend_wakeup(struct dvb_frontend *fe)
 {
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
        fepriv->wakeup = 1;
        wake_up_interruptible(&fepriv->wait_queue);
@@ -357,8 +357,8 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe)
  */
 static int dvb_frontend_thread(void *data)
 {
-       struct dvb_frontend *fe = (struct dvb_frontend *) data;
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend *fe = data;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
        unsigned long timeout;
        char name [15];
        int quality = 0, delay = 3*HZ;
@@ -520,7 +520,7 @@ static int dvb_frontend_thread(void *data)
 static void dvb_frontend_stop(struct dvb_frontend *fe)
 {
        unsigned long ret;
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
        dprintk ("%s\n", __FUNCTION__);
 
@@ -559,7 +559,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
 static int dvb_frontend_start(struct dvb_frontend *fe)
 {
        int ret;
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
        dprintk ("%s\n", __FUNCTION__);
 
@@ -597,7 +597,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dvb_frontend *fe = dvbdev->priv;
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
        int err = -EOPNOTSUPP;
 
        dprintk ("%s\n", __FUNCTION__);
@@ -615,7 +615,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
        case FE_GET_INFO: {
-               struct dvb_frontend_info* info = (struct dvb_frontend_info*) parg;
+               struct dvb_frontend_info* info = parg;
                memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info));
 
                /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
@@ -793,7 +793,7 @@ static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struc
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dvb_frontend *fe = dvbdev->priv;
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
        dprintk ("%s\n", __FUNCTION__);
 
@@ -809,7 +809,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dvb_frontend *fe = dvbdev->priv;
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
        int ret;
 
        dprintk ("%s\n", __FUNCTION__);
@@ -833,7 +833,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dvb_frontend *fe = dvbdev->priv;
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
        dprintk ("%s\n", __FUNCTION__);
 
@@ -873,7 +873,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
                up(&frontend_mutex);
                return -ENOMEM;
        }
-       fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       fepriv = fe->frontend_priv;
        memset(fe->frontend_priv, 0, sizeof(struct dvb_frontend_private));
 
        init_MUTEX (&fepriv->sem);
@@ -897,7 +897,7 @@ EXPORT_SYMBOL(dvb_register_frontend);
 
 int dvb_unregister_frontend(struct dvb_frontend* fe)
 {
-       struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+       struct dvb_frontend_private *fepriv = fe->frontend_priv;
        dprintk ("%s\n", __FUNCTION__);
 
        down (&frontend_mutex);
index 44892e7abd3d1cfdb165b578e564e2f91744fff3..6a968c346a367d9595bfbfc979b8203aebc3051e 100644 (file)
@@ -315,7 +315,7 @@ static inline void reset_ule( struct dvb_net_priv *p )
  */
 static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
 {
-       struct dvb_net_priv *priv = (struct dvb_net_priv *)dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
        unsigned long skipped = 0L;
        u8 *ts, *ts_end, *from_where = NULL, ts_remain = 0, how_much = 0, new_ts = 1;
        struct ethhdr *ethh = NULL;
@@ -709,7 +709,7 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
                               const u8 *buffer2, size_t buffer2_len,
                               struct dmx_ts_feed *feed, enum dmx_success success)
 {
-       struct net_device *dev = (struct net_device *)feed->priv;
+       struct net_device *dev = feed->priv;
 
        if (buffer2 != 0)
                printk(KERN_WARNING "buffer2 not 0: %p.\n", buffer2);
@@ -727,6 +727,7 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
         u8 *eth;
         struct sk_buff *skb;
        struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats);
+       int snap = 0;
 
        /* note: pkt_len includes a 32bit checksum */
        if (pkt_len < 16) {
@@ -750,9 +751,12 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
                return;
        }
        if (pkt[5] & 0x02) {
-               //FIXME: handle LLC/SNAP
-                stats->rx_dropped++;
-                return;
+               /* handle LLC/SNAP, see rfc-1042 */
+               if (pkt_len < 24 || memcmp(&pkt[12], "\xaa\xaa\x03\0\0\0", 6)) {
+                       stats->rx_dropped++;
+                       return;
+               }
+               snap = 8;
         }
        if (pkt[7]) {
                /* FIXME: assemble datagram from multiple sections */
@@ -762,9 +766,9 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
        }
 
        /* we have 14 byte ethernet header (ip header follows);
-        * 12 byte MPE header; 4 byte checksum; + 2 byte alignment
+        * 12 byte MPE header; 4 byte checksum; + 2 byte alignment, 8 byte LLC/SNAP
         */
-       if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2))) {
+       if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2 - snap))) {
                //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
                stats->rx_dropped++;
                return;
@@ -773,8 +777,8 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
        skb->dev = dev;
 
        /* copy L3 payload */
-       eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14);
-       memcpy(eth + 14, pkt + 12, pkt_len - 12 - 4);
+       eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14 - snap);
+       memcpy(eth + 14, pkt + 12 + snap, pkt_len - 12 - 4 - snap);
 
        /* create ethernet header: */
         eth[0]=pkt[0x0b];
@@ -786,8 +790,21 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
 
         eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;
 
-       eth[12] = 0x08; /* ETH_P_IP */
-       eth[13] = 0x00;
+       if (snap) {
+               eth[12] = pkt[18];
+               eth[13] = pkt[19];
+       } else {
+               /* protocol numbers are from rfc-1700 or
+                * http://www.iana.org/assignments/ethernet-numbers
+                */
+               if (pkt[12] >> 4 == 6) { /* version field from IP header */
+                       eth[12] = 0x86; /* IPv6 */
+                       eth[13] = 0xdd;
+               } else {
+                       eth[12] = 0x08; /* IPv4 */
+                       eth[13] = 0x00;
+               }
+       }
 
        skb->protocol = dvb_net_eth_type_trans(skb, dev);
 
@@ -801,7 +818,7 @@ static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
                 struct dmx_section_filter *filter,
                 enum dmx_success success)
 {
-        struct net_device *dev=(struct net_device *) filter->priv;
+        struct net_device *dev = filter->priv;
 
        /**
         * we rely on the DVB API definition where exactly one complete
@@ -826,7 +843,7 @@ static int dvb_net_filter_sec_set(struct net_device *dev,
                   struct dmx_section_filter **secfilter,
                   u8 *mac, u8 *mac_mask)
 {
-       struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
        int ret;
 
        *secfilter=NULL;
@@ -870,7 +887,7 @@ static int dvb_net_filter_sec_set(struct net_device *dev,
 static int dvb_net_feed_start(struct net_device *dev)
 {
        int ret, i;
-       struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
         struct dmx_demux *demux = priv->demux;
         unsigned char *mac = (unsigned char *) dev->dev_addr;
 
@@ -965,7 +982,7 @@ static int dvb_net_feed_start(struct net_device *dev)
 
 static int dvb_net_feed_stop(struct net_device *dev)
 {
-       struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
        int i;
 
        dprintk("%s\n", __FUNCTION__);
@@ -1016,7 +1033,7 @@ static int dvb_net_feed_stop(struct net_device *dev)
 
 static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
 {
-       struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
 
        if (priv->multi_num == DVB_NET_MULTICAST_MAX)
                return -ENOMEM;
@@ -1031,7 +1048,7 @@ static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
 static void wq_set_multicast_list (void *data)
 {
        struct net_device *dev = data;
-       struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
 
        dvb_net_feed_stop(dev);
 
@@ -1066,7 +1083,7 @@ static void wq_set_multicast_list (void *data)
 
 static void dvb_net_set_multicast_list (struct net_device *dev)
 {
-       struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
        schedule_work(&priv->set_multicast_list_wq);
 }
 
@@ -1084,7 +1101,7 @@ static void wq_restart_net_feed (void *data)
 
 static int dvb_net_set_mac (struct net_device *dev, void *p)
 {
-       struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
        struct sockaddr *addr=p;
 
        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
@@ -1098,7 +1115,7 @@ static int dvb_net_set_mac (struct net_device *dev, void *p)
 
 static int dvb_net_open(struct net_device *dev)
 {
-       struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
 
        priv->in_use++;
        dvb_net_feed_start(dev);
@@ -1108,7 +1125,7 @@ static int dvb_net_open(struct net_device *dev)
 
 static int dvb_net_stop(struct net_device *dev)
 {
-       struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+       struct dvb_net_priv *priv = dev->priv;
 
        priv->in_use--;
         return dvb_net_feed_stop(dev);
@@ -1228,8 +1245,8 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num)
 static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
                  unsigned int cmd, void *parg)
 {
-       struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-       struct dvb_net *dvbnet = (struct dvb_net *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct dvb_net *dvbnet = dvbdev->priv;
 
        if (((file->f_flags&O_ACCMODE)==O_RDONLY))
                return -EPERM;
@@ -1237,7 +1254,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
        switch (cmd) {
        case NET_ADD_IF:
        {
-               struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
+               struct dvb_net_if *dvbnetif = parg;
                int result;
 
                if (!capable(CAP_SYS_ADMIN))
@@ -1258,7 +1275,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
        {
                struct net_device *netdev;
                struct dvb_net_priv *priv_data;
-               struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
+               struct dvb_net_if *dvbnetif = parg;
 
                if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
                    !dvbnet->state[dvbnetif->if_num])
@@ -1266,7 +1283,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
 
                netdev = dvbnet->device[dvbnetif->if_num];
 
-               priv_data=(struct dvb_net_priv*)netdev->priv;
+               priv_data = netdev->priv;
                dvbnetif->pid=priv_data->pid;
                dvbnetif->feedtype=priv_data->feedtype;
                break;
@@ -1288,7 +1305,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
        /* binary compatiblity cruft */
        case __NET_ADD_IF_OLD:
        {
-               struct __dvb_net_if_old *dvbnetif=(struct __dvb_net_if_old *)parg;
+               struct __dvb_net_if_old *dvbnetif = parg;
                int result;
 
                if (!capable(CAP_SYS_ADMIN))
@@ -1309,7 +1326,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
        {
                struct net_device *netdev;
                struct dvb_net_priv *priv_data;
-               struct __dvb_net_if_old *dvbnetif=(struct __dvb_net_if_old *)parg;
+               struct __dvb_net_if_old *dvbnetif = parg;
 
                if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
                    !dvbnet->state[dvbnetif->if_num])
@@ -1317,7 +1334,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
 
                netdev = dvbnet->device[dvbnetif->if_num];
 
-               priv_data=(struct dvb_net_priv*)netdev->priv;
+               priv_data = netdev->priv;
                dvbnetif->pid=priv_data->pid;
                break;
        }
index cf4ffe38fda375cf3ba3b2998cb2a42798fc7f81..9d9662f4b8e660d5814d61a493e6ed321c50e98c 100644 (file)
@@ -286,9 +286,8 @@ skip:
 }
 
 
-int dvb_register_adapter(struct dvb_adapter **padap, const char *name, struct module *module)
+int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module)
 {
-       struct dvb_adapter *adap;
        int num;
 
        if (down_interruptible (&dvbdev_register_lock))
@@ -299,11 +298,6 @@ int dvb_register_adapter(struct dvb_adapter **padap, const char *name, struct mo
                return -ENFILE;
        }
 
-       if (!(*padap = adap = kmalloc(sizeof(struct dvb_adapter), GFP_KERNEL))) {
-               up(&dvbdev_register_lock);
-               return -ENOMEM;
-       }
-
        memset (adap, 0, sizeof(struct dvb_adapter));
        INIT_LIST_HEAD (&adap->device_list);
 
@@ -331,7 +325,6 @@ int dvb_unregister_adapter(struct dvb_adapter *adap)
                return -ERESTARTSYS;
        list_del (&adap->list_head);
        up (&dvbdev_register_lock);
-       kfree (adap);
        return 0;
 }
 EXPORT_SYMBOL(dvb_unregister_adapter);
index 184edba3caa7121b64763f93102bd1515f3d31a4..a251867f30f1cfde7cb3523a1eb2a2f9ba36fa7d 100644 (file)
@@ -76,7 +76,7 @@ struct dvb_device {
 };
 
 
-extern int dvb_register_adapter (struct dvb_adapter **padap, const char *name, struct module *module);
+extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module);
 extern int dvb_unregister_adapter (struct dvb_adapter *adap);
 
 extern int dvb_register_device (struct dvb_adapter *adap,
index 0bfd4df17d08d4775a58539e74a22c52892e35a6..75fb556ec01fe32b99d4f7c06d4ea50de758646d 100644 (file)
@@ -12,10 +12,10 @@ config DVB_STV0299
 
 config DVB_CX24110
        tristate "Conexant CX24110 based"
-       depends on DVB_CORE
-       help
+       depends on DVB_CORE
+       help
          A DVB-S tuner module. Say Y when you want to support this frontend.
+
 config DVB_TDA8083
        tristate "Philips TDA8083 based"
        depends on DVB_CORE
@@ -127,8 +127,8 @@ comment "DVB-C (cable) frontends"
 config DVB_ATMEL_AT76C651
        tristate "Atmel AT76C651 based"
        depends on DVB_CORE
-        help
-         A DVB-C tuner module. Say Y when you want to support this frontend.
+       help
+         A DVB-C tuner module. Say Y when you want to support this frontend.
 
 config DVB_VES1820
        tristate "VLSI VES1820 based"
@@ -158,10 +158,6 @@ config DVB_NXT2002
        help
          An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
 
-config DVB_OR51132
-       tristate "OR51132 based (pcHDTV)"
-       depends on DVB_CORE
-
 config DVB_OR51211
        tristate "or51211 based (pcHDTV HD2000 card)"
        depends on DVB_CORE
@@ -169,4 +165,12 @@ config DVB_OR51211
        help
          An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
 
+config DVB_OR51132
+       tristate "OR51132 based (pcHDTV HD3000 card)"
+       depends on DVB_CORE
+       select FW_LOADER
+       help
+         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+         to support this frontend.
+
 endmenu
index ce2eaa1640e87b5cabd8254f0f4126e7f01bba82..72a2b5455b0bfd46873e84eb4ec942547f4f28fa 100644 (file)
@@ -259,7 +259,7 @@ static int at76c651_set_parameters(struct dvb_frontend* fe,
                                   struct dvb_frontend_parameters *p)
 {
        int ret;
-       struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
+       struct at76c651_state* state = fe->demodulator_priv;
 
        at76c651_writereg(state, 0x0c, 0xc3);
        state->config->pll_set(fe, p);
@@ -276,7 +276,7 @@ static int at76c651_set_parameters(struct dvb_frontend* fe,
 
 static int at76c651_set_defaults(struct dvb_frontend* fe)
 {
-       struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
+       struct at76c651_state* state = fe->demodulator_priv;
 
        at76c651_set_symbol_rate(state, 6900000);
        at76c651_set_qam(state, QAM_64);
@@ -294,7 +294,7 @@ static int at76c651_set_defaults(struct dvb_frontend* fe)
 
 static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
+       struct at76c651_state* state = fe->demodulator_priv;
        u8 sync;
 
        /*
@@ -319,7 +319,7 @@ static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
+       struct at76c651_state* state = fe->demodulator_priv;
 
        *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16;
        *ber |= at76c651_readreg(state, 0x82) << 8;
@@ -331,7 +331,7 @@ static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
+       struct at76c651_state* state = fe->demodulator_priv;
 
        u8 gain = ~at76c651_readreg(state, 0x91);
        *strength = (gain << 8) | gain;
@@ -341,7 +341,7 @@ static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
+       struct at76c651_state* state = fe->demodulator_priv;
 
        *snr = 0xFFFF -
            ((at76c651_readreg(state, 0x8F) << 8) |
@@ -352,7 +352,7 @@ static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
+       struct at76c651_state* state = fe->demodulator_priv;
 
        *ucblocks = at76c651_readreg(state, 0x82);
 
@@ -369,7 +369,7 @@ static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronte
 
 static void at76c651_release(struct dvb_frontend* fe)
 {
-       struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
+       struct at76c651_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -381,7 +381,7 @@ struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
        struct at76c651_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct at76c651_state*) kmalloc(sizeof(struct at76c651_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct at76c651_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index a212279042b8f225454191ad8e0e637002932fb5..0c2ed44386189224518863fb8a28a3e0de5ba8de 100644 (file)
@@ -232,7 +232,7 @@ static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_paramet
 
 static int cx22700_init (struct dvb_frontend* fe)
 
-{      struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
+{      struct cx22700_state* state = fe->demodulator_priv;
        int i;
 
        dprintk("cx22700_init: init chip\n");
@@ -258,7 +258,7 @@ static int cx22700_init (struct dvb_frontend* fe)
 
 static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
+       struct cx22700_state* state = fe->demodulator_priv;
 
        u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
                   | (cx22700_readreg (state, 0x0e) << 1);
@@ -286,7 +286,7 @@ static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
+       struct cx22700_state* state = fe->demodulator_priv;
 
        *ber = cx22700_readreg (state, 0x0c) & 0x7f;
        cx22700_writereg (state, 0x0c, 0x00);
@@ -296,7 +296,7 @@ static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
 {
-       struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
+       struct cx22700_state* state = fe->demodulator_priv;
 
        u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
                   | (cx22700_readreg (state, 0x0e) << 1);
@@ -307,7 +307,7 @@ static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
 
 static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
+       struct cx22700_state* state = fe->demodulator_priv;
 
        u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
                   | (cx22700_readreg (state, 0x0e) << 1);
@@ -318,7 +318,7 @@ static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
+       struct cx22700_state* state = fe->demodulator_priv;
 
        *ucblocks = cx22700_readreg (state, 0x0f);
        cx22700_writereg (state, 0x0f, 0x00);
@@ -328,7 +328,7 @@ static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
+       struct cx22700_state* state = fe->demodulator_priv;
 
        cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/
        cx22700_writereg (state, 0x00, 0x00);
@@ -346,7 +346,7 @@ static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
+       struct cx22700_state* state = fe->demodulator_priv;
        u8 reg09 = cx22700_readreg (state, 0x09);
 
        p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF;
@@ -363,7 +363,7 @@ static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten
 
 static void cx22700_release(struct dvb_frontend* fe)
 {
-       struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
+       struct cx22700_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -375,7 +375,7 @@ struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
        struct cx22700_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct cx22700_state*) kmalloc(sizeof(struct cx22700_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct cx22700_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 011860ce36cc8b93894e2876f87c49ef2e12fa87..f4aa44136c7ced10a677e46dbde06cf39a1f9fe2 100644 (file)
@@ -200,7 +200,7 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet
 static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
        u8 val;
-       struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
+       struct cx22702_state* state = fe->demodulator_priv;
 
        /* set PLL */
         cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
@@ -338,7 +338,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
 static int cx22702_init (struct dvb_frontend* fe)
 {
        int i;
-       struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
+       struct cx22702_state* state = fe->demodulator_priv;
 
        cx22702_writereg (state, 0x00, 0x02);
 
@@ -360,7 +360,7 @@ static int cx22702_init (struct dvb_frontend* fe)
 
 static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
+       struct cx22702_state* state = fe->demodulator_priv;
        u8 reg0A;
        u8 reg23;
 
@@ -389,7 +389,7 @@ static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
+       struct cx22702_state* state = fe->demodulator_priv;
 
        if(cx22702_readreg (state, 0xE4) & 0x02) {
                /* Realtime statistics */
@@ -406,7 +406,7 @@ static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
 {
-       struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
+       struct cx22702_state* state = fe->demodulator_priv;
 
        *signal_strength = cx22702_readreg (state, 0x23);
 
@@ -415,7 +415,7 @@ static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
 
 static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
+       struct cx22702_state* state = fe->demodulator_priv;
 
        u16 rs_ber=0;
        if(cx22702_readreg (state, 0xE4) & 0x02) {
@@ -434,7 +434,7 @@ static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
+       struct cx22702_state* state = fe->demodulator_priv;
 
        u8 _ucblocks;
 
@@ -449,7 +449,7 @@ static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
+       struct cx22702_state* state = fe->demodulator_priv;
 
        u8 reg0C = cx22702_readreg (state, 0x0C);
 
@@ -459,7 +459,7 @@ static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static void cx22702_release(struct dvb_frontend* fe)
 {
-       struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
+       struct cx22702_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -471,7 +471,7 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
        struct cx22702_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct cx22702_state*) kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index ae16112a06535b0f7a52b1792f022f47fdc5bfbd..8222b88cb4868fdc8f5dd1ad2abb325c9b4e5a9b 100644 (file)
@@ -315,7 +315,7 @@ dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate);
 
 int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 
 /* tuner data is 21 bits long, must be left-aligned in data */
 /* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
@@ -356,7 +356,7 @@ int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
 
 static int cx24110_initfe(struct dvb_frontend* fe)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 /* fixme (low): error handling */
         int i;
 
@@ -373,7 +373,7 @@ static int cx24110_initfe(struct dvb_frontend* fe)
 
 static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 
        switch (voltage) {
        case SEC_VOLTAGE_13:
@@ -385,8 +385,7 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
        };
 }
 
-static int cx24110_diseqc_send_burst(struct dvb_frontend* fe,
-                       fe_sec_mini_cmd_t burst)
+static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
 {
        int rv, bit, i;
        struct cx24110_state *state = fe->demodulator_priv;
@@ -413,7 +412,7 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
                                   struct dvb_diseqc_master_cmd *cmd)
 {
        int i, rv;
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 
        for (i = 0; i < cmd->msg_len; i++)
                cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
@@ -432,7 +431,7 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
 
 static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 
        int sync = cx24110_readreg (state, 0x55);
 
@@ -460,7 +459,7 @@ static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 
        /* fixme (maybe): value range is 16 bit. Scale? */
        if(cx24110_readreg(state,0x24)&0x10) {
@@ -478,7 +477,7 @@ static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 
 /* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */
        u8 signal = cx24110_readreg (state, 0x27)+128;
@@ -489,7 +488,7 @@ static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
 
 static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 
        /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */
        if(cx24110_readreg(state,0x6a)&0x80) {
@@ -505,7 +504,7 @@ static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
        u32 lastbyer;
 
        if(cx24110_readreg(state,0x10)&0x40) {
@@ -527,7 +526,7 @@ static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 
        state->config->pll_set(fe, p);
        cx24110_set_inversion (state, p->inversion);
@@ -540,7 +539,7 @@ static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
        s32 afc; unsigned sclk;
 
 /* cannot read back tuner settings (freq). Need to have some private storage */
@@ -567,14 +566,14 @@ static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
-       struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state *state = fe->demodulator_priv;
 
        return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0));
 }
 
 static void cx24110_release(struct dvb_frontend* fe)
 {
-       struct cx24110_state* state = (struct cx24110_state*) fe->demodulator_priv;
+       struct cx24110_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -587,7 +586,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
        int ret;
 
        /* allocate memory for the internal state */
-       state = (struct cx24110_state*) kmalloc(sizeof(struct cx24110_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct cx24110_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index a853d12a26f1efb82092cd187c5df91b6a292917..6f52d649e97e083b8fcd18a837526aeb5abacfec 100644 (file)
@@ -56,12 +56,12 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe,
 static int dib3000mb_set_frontend(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters *fep, int tuner)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
        fe_code_rate_t fe_cr = FEC_NONE;
        int search_state, seq;
 
-       if (tuner) {
+       if (tuner && state->config.pll_addr && state->config.pll_set) {
                dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
                state->config.pll_set(fe, fep, NULL);
                dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
@@ -317,7 +317,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
 
 static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
        deb_info("dib3000mb is getting up.\n");
        wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP);
@@ -401,7 +401,7 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
 static int dib3000mb_get_frontend(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters *fep)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
        fe_code_rate_t *cr;
        u16 tps_val;
@@ -562,7 +562,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe,
 
 static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
        *stat = 0;
 
@@ -594,7 +594,7 @@ static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
 
 static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
        *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB));
        return 0;
@@ -603,7 +603,7 @@ static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
 /* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */
 static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
        *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
        return 0;
@@ -611,7 +611,7 @@ static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength
 
 static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
        int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
                rd(DIB3000MB_REG_NOISE_POWER_LSB);
@@ -621,7 +621,7 @@ static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
 
 static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
        *unc = rd(DIB3000MB_REG_UNC);
        return 0;
@@ -629,7 +629,7 @@ static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
 
 static int dib3000mb_sleep(struct dvb_frontend* fe)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        deb_info("dib3000mb is going to bed.\n");
        wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN);
        return 0;
@@ -656,7 +656,7 @@ static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_
 
 static void dib3000mb_release(struct dvb_frontend* fe)
 {
-       struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state *state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -671,7 +671,7 @@ static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int
 
 static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
 {
-       struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state *state = fe->demodulator_priv;
 
        deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
        if (onoff) {
@@ -692,7 +692,7 @@ static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
 
 static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
 {
-       struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state *state = fe->demodulator_priv;
        if (onoff) {
                wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
        } else {
@@ -709,7 +709,7 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
        struct dib3000_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
        memset(state,0,sizeof(struct dib3000_state));
index 4a31c05eaecd1ae8c3753f599b8feffeabeafbfe..888f10a5e96b28bc469c9d14c4b265b89a527dc0 100644 (file)
@@ -297,7 +297,7 @@ static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_fro
 static int dib3000mc_get_frontend(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters *fep)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
        fe_code_rate_t *cr;
        u16 tps_val,cr_val;
@@ -458,12 +458,12 @@ static int dib3000mc_get_frontend(struct dvb_frontend* fe,
 static int dib3000mc_set_frontend(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters *fep, int tuner)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
        int search_state,auto_val;
        u16 val;
 
-       if (tuner) { /* initial call from dvb */
+       if (tuner && state->config.pll_addr && state->config.pll_set) { /* initial call from dvb */
                dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
                state->config.pll_set(fe,fep,NULL);
                dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
@@ -659,7 +659,7 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
 }
 static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        u16 lock = rd(DIB3000MC_REG_LOCKING);
 
        *stat = 0;
@@ -679,14 +679,14 @@ static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat)
 
 static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB));
        return 0;
 }
 
 static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
        *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT);
        return 0;
@@ -695,7 +695,7 @@ static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
 /* see dib3000mb.c for calculation comments */
 static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB);
        *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
 
@@ -706,7 +706,7 @@ static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength
 /* see dib3000mb.c for calculation comments */
 static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
        u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB),
                val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB);
        u16 sig,noise;
@@ -726,7 +726,7 @@ static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
 
 static int dib3000mc_sleep(struct dvb_frontend* fe)
 {
-       struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state* state = fe->demodulator_priv;
 
        set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN);
        wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN);
@@ -756,7 +756,7 @@ static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_
 
 static void dib3000mc_release(struct dvb_frontend* fe)
 {
-       struct dib3000_state *state = (struct dib3000_state *) fe->demodulator_priv;
+       struct dib3000_state *state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -771,7 +771,7 @@ static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int
 
 static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff)
 {
-       struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state *state = fe->demodulator_priv;
        u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
 
        deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
@@ -803,7 +803,7 @@ static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
 
 static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
 {
-       struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
+       struct dib3000_state *state = fe->demodulator_priv;
        if (onoff) {
                wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
        } else {
@@ -844,7 +844,7 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
        u16 devid;
 
        /* allocate memory for the internal state */
-       state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
        memset(state,0,sizeof(struct dib3000_state));
index 016c794a5677f7209885ebe2cea9e4481d60d708..c4c3c56c4a819769e650ad62199abe431bc7a27f 100644 (file)
@@ -2,6 +2,9 @@
  * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $
  */
 
+#ifndef __DVB_PLL_H__
+#define __DVB_PLL_H__
+
 struct dvb_pll_desc {
        char *name;
        u32  min;
@@ -26,9 +29,4 @@ extern struct dvb_pll_desc dvb_pll_unknown_1;
 int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
                      u32 freq, int bandwidth);
 
-/*
- * Local variables:
- * c-basic-offset: 8
- * compile-command: "make DVB=1"
- * End:
- */
+#endif
index c05a9b05600c29d9b3033353864171ea5349cf3a..cff93b9d8ab2653e141fdd2ab466ac7b4f5c8bc2 100644 (file)
@@ -100,7 +100,7 @@ static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t vo
 
 static void dvb_dummy_fe_release(struct dvb_frontend* fe)
 {
-       struct dvb_dummy_fe_state* state = (struct dvb_dummy_fe_state*) fe->demodulator_priv;
+       struct dvb_dummy_fe_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -111,7 +111,7 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
        struct dvb_dummy_fe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
@@ -134,7 +134,7 @@ struct dvb_frontend* dvb_dummy_fe_qpsk_attach()
        struct dvb_dummy_fe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
@@ -157,7 +157,7 @@ struct dvb_frontend* dvb_dummy_fe_qam_attach()
        struct dvb_dummy_fe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 9ac95de9834d5604afd6de10316c149d3eb6cf07..031a1ddc7d11f16662e3446dd6fe561650959ad0 100644 (file)
@@ -121,7 +121,7 @@ static int reset_and_configure (struct l64781_state* state)
 
 static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
        /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */
        static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 };
        /* QPSK, QAM_16, QAM_64 */
@@ -234,7 +234,7 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa
 
 static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
        int tmp;
 
 
@@ -352,7 +352,7 @@ static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters*
 
 static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
        int sync = l64781_readreg (state, 0x32);
        int gain = l64781_readreg (state, 0x0e);
 
@@ -381,7 +381,7 @@ static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int l64781_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
 
        /*   XXX FIXME: set up counting period (reg 0x26...0x28)
         */
@@ -393,7 +393,7 @@ static int l64781_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
 
        u8 gain = l64781_readreg (state, 0x0e);
        *signal_strength = (gain << 8) | gain;
@@ -403,7 +403,7 @@ static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_stre
 
 static int l64781_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
 
        u8 avg_quality = 0xff - l64781_readreg (state, 0x33);
        *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/
@@ -413,7 +413,7 @@ static int l64781_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
 
        *ucblocks = l64781_readreg (state, 0x37)
           | (l64781_readreg (state, 0x38) << 8);
@@ -423,7 +423,7 @@ static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int l64781_sleep(struct dvb_frontend* fe)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
 
        /* Power down */
        return l64781_writereg (state, 0x3e, 0x5a);
@@ -431,7 +431,7 @@ static int l64781_sleep(struct dvb_frontend* fe)
 
 static int l64781_init(struct dvb_frontend* fe)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
 
         reset_and_configure (state);
 
@@ -484,7 +484,7 @@ static int l64781_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend
 
 static void l64781_release(struct dvb_frontend* fe)
 {
-       struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
+       struct l64781_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -501,7 +501,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config,
                           { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 
        /* allocate memory for the internal state */
-       state = (struct l64781_state*) kmalloc(sizeof(struct l64781_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct l64781_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 176a22e3441bfeb5bd6bbf040214c5be1b6fb8b4..e455aecd76b2f9c6732ff03e07c65fffbbf6dffe 100644 (file)
@@ -226,7 +226,7 @@ static int mt312_get_code_rate(struct mt312_state* state, fe_code_rate_t *cr)
 
 static int mt312_initfe(struct dvb_frontend* fe)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
        u8 buf[2];
 
@@ -287,7 +287,7 @@ static int mt312_initfe(struct dvb_frontend* fe)
 static int mt312_send_master_cmd(struct dvb_frontend* fe,
                                 struct dvb_diseqc_master_cmd *c)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
        u8 diseqc_mode;
 
@@ -318,7 +318,7 @@ static int mt312_send_master_cmd(struct dvb_frontend* fe,
 
 static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        const u8 mini_tab[2] = { 0x02, 0x03 };
 
        int ret;
@@ -340,7 +340,7 @@ static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c)
 
 static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        const u8 tone_tab[2] = { 0x01, 0x00 };
 
        int ret;
@@ -362,7 +362,7 @@ static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t)
 
 static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
 
        if (v > SEC_VOLTAGE_OFF)
@@ -373,7 +373,7 @@ static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v)
 
 static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
        u8 status[3];
 
@@ -400,7 +400,7 @@ static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
 
 static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
        u8 buf[3];
 
@@ -414,7 +414,7 @@ static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber)
 
 static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_strength)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
        u8 buf[3];
        u16 agc;
@@ -435,7 +435,7 @@ static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_stren
 
 static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
        u8 buf[2];
 
@@ -449,7 +449,7 @@ static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr)
 
 static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
        u8 buf[2];
 
@@ -464,7 +464,7 @@ static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc)
 static int mt312_set_frontend(struct dvb_frontend* fe,
                              struct dvb_frontend_parameters *p)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
        u8 buf[5], config_val;
        u16 sr;
@@ -560,7 +560,7 @@ static int mt312_set_frontend(struct dvb_frontend* fe,
 static int mt312_get_frontend(struct dvb_frontend* fe,
                              struct dvb_frontend_parameters *p)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
 
        if ((ret = mt312_get_inversion(state, &p->inversion)) < 0)
@@ -577,7 +577,7 @@ static int mt312_get_frontend(struct dvb_frontend* fe,
 
 static int mt312_sleep(struct dvb_frontend* fe)
 {
-       struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state *state = fe->demodulator_priv;
        int ret;
        u8 config;
 
@@ -605,7 +605,7 @@ static int mt312_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_
 
 static void mt312_release(struct dvb_frontend* fe)
 {
-       struct mt312_state* state = (struct mt312_state*) fe->demodulator_priv;
+       struct mt312_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -617,7 +617,7 @@ struct dvb_frontend* vp310_attach(const struct mt312_config* config,
        struct mt312_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
@@ -651,7 +651,7 @@ struct dvb_frontend* mt312_attach(const struct mt312_config* config,
        struct mt312_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 50326c7248fa3cc1ffa79824cfedde5d6fa90264..d32dc4de9e7f1fafd539e7e9de758705760b3613 100644 (file)
@@ -46,7 +46,7 @@ struct mt352_state {
        struct dvb_frontend_ops ops;
 
        /* configuration settings */
-       const struct mt352_config* config;
+       struct mt352_config config;
 };
 
 static int debug;
@@ -59,7 +59,7 @@ static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
 {
        struct mt352_state* state = fe->demodulator_priv;
        u8 buf[2] = { reg, val };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0,
+       struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
                               .buf = buf, .len = 2 };
        int err = i2c_transfer(state->i2c, &msg, 1);
        if (err != 1) {
@@ -84,10 +84,10 @@ static int mt352_read_register(struct mt352_state* state, u8 reg)
        int ret;
        u8 b0 [] = { reg };
        u8 b1 [] = { 0 };
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address,
+       struct i2c_msg msg [] = { { .addr = state->config.demod_address,
                                    .flags = 0,
                                    .buf = b0, .len = 1 },
-                                 { .addr = state->config->demod_address,
+                                 { .addr = state->config.demod_address,
                                    .flags = I2C_M_RD,
                                    .buf = b1, .len = 1 } };
 
@@ -102,11 +102,6 @@ static int mt352_read_register(struct mt352_state* state, u8 reg)
        return b1[0];
 }
 
-int mt352_read(struct dvb_frontend *fe, u8 reg)
-{
-       return mt352_read_register(fe->demodulator_priv,reg);
-}
-
 static int mt352_sleep(struct dvb_frontend* fe)
 {
        static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
@@ -134,8 +129,8 @@ static void mt352_calc_nominal_rate(struct mt352_state* state,
                bw = 8;
                break;
        }
-       if (state->config->adc_clock)
-               adc_clock = state->config->adc_clock;
+       if (state->config.adc_clock)
+               adc_clock = state->config.adc_clock;
 
        value = 64 * bw * (1<<16) / (7 * 8);
        value = value * 1000 / adc_clock;
@@ -152,10 +147,10 @@ static void mt352_calc_input_freq(struct mt352_state* state,
        int if2       = 36167; /* 36.166667 MHz */
        int ife,value;
 
-       if (state->config->adc_clock)
-               adc_clock = state->config->adc_clock;
-       if (state->config->if2)
-               if2 = state->config->if2;
+       if (state->config.adc_clock)
+               adc_clock = state->config.adc_clock;
+       if (state->config.if2)
+               if2 = state->config.if2;
 
        ife = (2*adc_clock - if2);
        value = -16374 * ife / adc_clock;
@@ -289,10 +284,10 @@ static int mt352_set_parameters(struct dvb_frontend* fe,
 
        mt352_calc_nominal_rate(state, op->bandwidth, buf+4);
        mt352_calc_input_freq(state, buf+6);
-       state->config->pll_set(fe, param, buf+8);
+       state->config.pll_set(fe, param, buf+8);
 
        mt352_write(fe, buf, sizeof(buf));
-       if (state->config->no_tuner) {
+       if (state->config.no_tuner) {
                /* start decoding */
                mt352_write(fe, fsm_go, 2);
        } else {
@@ -516,7 +511,7 @@ static int mt352_init(struct dvb_frontend* fe)
 
                /* Do a "hard" reset */
                mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
-               return state->config->demod_init(fe);
+               return state->config.demod_init(fe);
        }
 
        return 0;
@@ -541,8 +536,8 @@ struct dvb_frontend* mt352_attach(const struct mt352_config* config,
        memset(state,0,sizeof(*state));
 
        /* setup the state */
-       state->config = config;
        state->i2c = i2c;
+       memcpy(&state->config,config,sizeof(struct mt352_config));
        memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
 
        /* check if the demod is there */
@@ -601,10 +596,3 @@ MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(mt352_attach);
 EXPORT_SYMBOL(mt352_write);
-EXPORT_SYMBOL(mt352_read);
-/*
- * Local variables:
- * c-basic-offset: 8
- * compile-command: "make DVB=1"
- * End:
- */
index f5d8a5aed8a93101c52646a91cefd24246a85d2f..03040cd595bb4b50a0a9cb4d1f4835d663705b02 100644 (file)
@@ -61,12 +61,5 @@ extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
                                         struct i2c_adapter* i2c);
 
 extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen);
-extern int mt352_read(struct dvb_frontend *fe, u8 reg);
 
 #endif // MT352_H
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
index 4743aa17406e0b1fa4ffcb36e0e334e936182900..35a1d60f19273023ee5cfab5ce276a7aff74d0ce 100644 (file)
@@ -241,7 +241,7 @@ static void nxt2002_agc_reset(struct nxt2002_state* state)
 static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
 {
 
-       struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+       struct nxt2002_state* state = fe->demodulator_priv;
        u8 buf[256],written = 0,chunkpos = 0;
        u16 rambase,position,crc = 0;
 
@@ -309,7 +309,7 @@ static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware
 static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
                                             struct dvb_frontend_parameters *p)
 {
-       struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+       struct nxt2002_state* state = fe->demodulator_priv;
        u32 freq = 0;
        u16 tunerfreq = 0;
        u8 buf[4];
@@ -343,8 +343,6 @@ static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
        /* reset the agc now that tuning has been completed */
        nxt2002_agc_reset(state);
 
-
-
        /* set target power level */
        switch (p->u.vsb.modulation) {
                case QAM_64:
@@ -453,7 +451,7 @@ static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
 
 static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+       struct nxt2002_state* state = fe->demodulator_priv;
        u8 lock;
        i2c_readbytes(state,0x31,&lock,1);
 
@@ -470,7 +468,7 @@ static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+       struct nxt2002_state* state = fe->demodulator_priv;
        u8 b[3];
 
        nxt2002_readreg_multibyte(state,0xE6,b,3);
@@ -482,7 +480,7 @@ static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+       struct nxt2002_state* state = fe->demodulator_priv;
        u8 b[2];
        u16 temp = 0;
 
@@ -502,7 +500,7 @@ static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr)
 {
 
-       struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+       struct nxt2002_state* state = fe->demodulator_priv;
        u8 b[2];
        u16 temp = 0, temp2;
        u32 snrdb = 0;
@@ -536,7 +534,7 @@ static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+       struct nxt2002_state* state = fe->demodulator_priv;
        u8 b[3];
 
        nxt2002_readreg_multibyte(state,0xE6,b,3);
@@ -552,7 +550,7 @@ static int nxt2002_sleep(struct dvb_frontend* fe)
 
 static int nxt2002_init(struct dvb_frontend* fe)
 {
-       struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+       struct nxt2002_state* state = fe->demodulator_priv;
        const struct firmware *fw;
        int ret;
        u8 buf[2];
@@ -624,7 +622,7 @@ static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten
 
 static void nxt2002_release(struct dvb_frontend* fe)
 {
-       struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+       struct nxt2002_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -637,7 +635,7 @@ struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
        u8 buf [] = {0,0,0,0,0};
 
        /* allocate memory for the internal state */
-       state = (struct nxt2002_state*) kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index a41f7da8b842286b0a9b55636e8d3cf1b241171d..966de9853d18b7e6d9a8eadd768804603218595f 100644 (file)
@@ -176,11 +176,16 @@ static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmi
 
 static void nxt6000_setup(struct dvb_frontend* fe)
 {
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
+       struct nxt6000_state* state = fe->demodulator_priv;
 
        nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM);
        nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01);
-       nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC);
+       nxt6000_writereg(state, VIT_BERTIME_2, 0x00);  // BER Timer = 0x000200 * 256 = 131072 bits
+       nxt6000_writereg(state, VIT_BERTIME_1, 0x02);  //
+       nxt6000_writereg(state, VIT_BERTIME_0, 0x00);  //
+       nxt6000_writereg(state, VIT_COR_INTEN, 0x98); // Enable BER interrupts
+       nxt6000_writereg(state, VIT_COR_CTL, 0x82);   // Enable BER measurement
+       nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC | 0x02 );
        nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F));
        nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02);
        nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW);
@@ -422,7 +427,7 @@ static void nxt6000_dump_status(struct nxt6000_state *state)
 static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
        u8 core_status;
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
+       struct nxt6000_state* state = fe->demodulator_priv;
 
        *status = 0;
 
@@ -451,7 +456,7 @@ static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int nxt6000_init(struct dvb_frontend* fe)
 {
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
+       struct nxt6000_state* state = fe->demodulator_priv;
 
        nxt6000_reset(state);
        nxt6000_setup(fe);
@@ -461,7 +466,7 @@ static int nxt6000_init(struct dvb_frontend* fe)
 
 static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
 {
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
+       struct nxt6000_state* state = fe->demodulator_priv;
        int result;
 
        nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01);        /* open i2c bus switch */
@@ -482,10 +487,44 @@ static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static void nxt6000_release(struct dvb_frontend* fe)
 {
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
+       struct nxt6000_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
+static int nxt6000_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       *snr = nxt6000_readreg( state, OFDM_CHC_SNR) / 8;
+
+       return 0;
+}
+
+static int nxt6000_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18 );
+
+       *ber = (nxt6000_readreg( state, VIT_BER_1 ) << 8 ) |
+               nxt6000_readreg( state, VIT_BER_0 );
+
+       nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18); // Clear BER Done interrupts
+
+       return 0;
+}
+
+static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       *signal_strength = (short) (511 -
+               (nxt6000_readreg(state, AGC_GAIN_1) +
+               ((nxt6000_readreg(state, AGC_GAIN_2) & 0x03) << 8)));
+
+       return 0;
+}
+
 static struct dvb_frontend_ops nxt6000_ops;
 
 struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
@@ -494,7 +533,7 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
        struct nxt6000_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct nxt6000_state*) kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
@@ -542,6 +581,9 @@ static struct dvb_frontend_ops nxt6000_ops = {
        .set_frontend = nxt6000_set_frontend,
 
        .read_status = nxt6000_read_status,
+       .read_ber = nxt6000_read_ber,
+       .read_signal_strength = nxt6000_read_signal_strength,
+       .read_snr = nxt6000_read_snr,
 };
 
 module_param(debug, int, 0644);
index 64b1a89b2a22a2026a9bd7a81a7c44788458938f..0422e580038ac14719741c7c53e5b243f919b374 100644 (file)
 #define BER_DONE               (0x08)
 #define BER_OVERFLOW           (0x10)
 
+/* 0x38 VIT_BERTIME_2 */
+#define VIT_BERTIME_2      (0x38)
+
+/* 0x39 VIT_BERTIME_1 */
+#define VIT_BERTIME_1      (0x39)
+
+/* 0x3A VIT_BERTIME_0 */
+#define VIT_BERTIME_0      (0x3a)
+
                             /* 0x38 OFDM_BERTimer *//* Use the alias registers */
 #define A_VIT_BER_TIMER_0      (0x1D)
 
                             /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */
 #define A_VIT_BER_0            (0x1B)
 
+/* 0x3B VIT_BER_1 */
+#define VIT_BER_1              (0x3b)
+
+/* 0x3C VIT_BER_0 */
+#define VIT_BER_0              (0x3c)
+
 /* 0x40 OFDM_COR_CTL */
 #define OFDM_COR_CTL           (0x40)
 #define COREACT                (0x20)
 #define OFDM_ITB_CTL           (0x4B)
 #define ITBINV                 (0x01)
 
+/* 0x49 AGC_GAIN_1 */
+#define AGC_GAIN_1             (0x49)
+
+/* 0x4A AGC_GAIN_2 */
+#define AGC_GAIN_2             (0x4A)
+
 /* 0x4C OFDM_ITB_FREQ_1 */
 #define OFDM_ITB_FREQ_1        (0x4C)
 
index df5dee7760a34268f24f313c3923205dcbdc88f1..cc0a77c790f1add3a312e95b1ac442f3340e8955 100644 (file)
@@ -102,7 +102,7 @@ static u8 i2c_readbytes (struct or51132_state* state, u8 reg, u8* buf, int len)
 
 static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
 {
-       struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
+       struct or51132_state* state = fe->demodulator_priv;
        static u8 run_buf[] = {0x7F,0x01};
        static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
        u8 rec_buf[14];
@@ -240,7 +240,7 @@ static int or51132_sleep(struct dvb_frontend* fe)
 
 static int or51132_setmode(struct dvb_frontend* fe)
 {
-       struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
+       struct or51132_state* state = fe->demodulator_priv;
        unsigned char cmd_buf[4];
 
        dprintk("setmode %d\n",(int)state->current_modulation);
@@ -316,7 +316,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
 {
        int ret;
        u8 buf[4];
-       struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
+       struct or51132_state* state = fe->demodulator_priv;
        const struct firmware *fw;
 
        /* Change only if we are actually changing the modulation */
@@ -391,7 +391,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
 
 static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
+       struct or51132_state* state = fe->demodulator_priv;
        unsigned char rec_buf[2];
        unsigned char snd_buf[2];
        *status = 0;
@@ -464,7 +464,7 @@ static unsigned int i20Log10(unsigned short val)
 
 static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
+       struct or51132_state* state = fe->demodulator_priv;
        unsigned char rec_buf[2];
        unsigned char snd_buf[2];
        u8 rcvr_stat;
@@ -512,7 +512,7 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
+       struct or51132_state* state = fe->demodulator_priv;
        unsigned char rec_buf[2];
        unsigned char snd_buf[2];
        u16 snr_equ;
@@ -549,7 +549,7 @@ static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten
 
 static void or51132_release(struct dvb_frontend* fe)
 {
-       struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
+       struct or51132_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
index 58ad34ef0a00753fd36cd00c3874a9c920a4f76f..764a95a2e212b2972434c743184d1f06002fb1f9 100644 (file)
@@ -248,7 +248,7 @@ static int sp8870_wake_up(struct sp8870_state* state)
 static int sp8870_set_frontend_parameters (struct dvb_frontend* fe,
                                           struct dvb_frontend_parameters *p)
 {
-       struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
+       struct sp8870_state* state = fe->demodulator_priv;
        int  err;
        u16 reg0xc05;
 
@@ -302,7 +302,7 @@ static int sp8870_set_frontend_parameters (struct dvb_frontend* fe,
 
 static int sp8870_init (struct dvb_frontend* fe)
 {
-       struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
+       struct sp8870_state* state = fe->demodulator_priv;
         const struct firmware *fw = NULL;
 
        sp8870_wake_up(state);
@@ -358,7 +358,7 @@ static int sp8870_init (struct dvb_frontend* fe)
 
 static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
 {
-       struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
+       struct sp8870_state* state = fe->demodulator_priv;
        int status;
        int signal;
 
@@ -384,7 +384,7 @@ static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
 
 static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
 {
-       struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
+       struct sp8870_state* state = fe->demodulator_priv;
        int ret;
        u32 tmp;
 
@@ -412,7 +412,7 @@ static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
 
 static int sp8870_read_signal_strength(struct dvb_frontend* fe,  u16 * signal)
 {
-       struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
+       struct sp8870_state* state = fe->demodulator_priv;
        int ret;
        u16 tmp;
 
@@ -438,7 +438,7 @@ static int sp8870_read_signal_strength(struct dvb_frontend* fe,  u16 * signal)
 
 static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
 {
-       struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
+       struct sp8870_state* state = fe->demodulator_priv;
        int ret;
 
        *ublocks = 0;
@@ -467,7 +467,7 @@ static int switches = 0;
 
 static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
+       struct sp8870_state* state = fe->demodulator_priv;
 
        /*
            The firmware of the sp8870 sometimes locks up after setting frontend parameters.
@@ -524,7 +524,7 @@ static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int sp8870_sleep(struct dvb_frontend* fe)
 {
-       struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
+       struct sp8870_state* state = fe->demodulator_priv;
 
        // tristate TS output and disable interface pins
        return sp8870_writereg(state, 0xC18, 0x000);
@@ -540,7 +540,7 @@ static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend
 
 static void sp8870_release(struct dvb_frontend* fe)
 {
-       struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
+       struct sp8870_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -552,7 +552,7 @@ struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
        struct sp8870_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct sp8870_state*) kmalloc(sizeof(struct sp8870_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct sp8870_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 7eae833ece4909259cde871114881d4e619fe054..d868a6927a16d022d7643f7a4e2b2fc52ec680b2 100644 (file)
@@ -135,7 +135,7 @@ static void sp887x_setup_agc (struct sp887x_state* state)
  */
 static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
        u8 buf [BLOCKSIZE+2];
        int i;
        int fw_size = fw->size;
@@ -344,7 +344,7 @@ static void sp887x_correct_offsets (struct sp887x_state* state,
 static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
                                             struct dvb_frontend_parameters *p)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
        int actual_freq, err;
        u16 val, reg0xc05;
 
@@ -405,7 +405,7 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
 
 static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
        u16 snr12 = sp887x_readreg(state, 0xf16);
        u16 sync0x200 = sp887x_readreg(state, 0x200);
        u16 sync0xf17 = sp887x_readreg(state, 0xf17);
@@ -439,7 +439,7 @@ static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
 
        *ber = (sp887x_readreg(state, 0xc08) & 0x3f) |
               (sp887x_readreg(state, 0xc07) << 6);
@@ -453,7 +453,7 @@ static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
 
        u16 snr12 = sp887x_readreg(state, 0xf16);
        u32 signal = 3 * (snr12 << 4);
@@ -464,7 +464,7 @@ static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
 
        u16 snr12 = sp887x_readreg(state, 0xf16);
        *snr = (snr12 << 4) | (snr12 >> 8);
@@ -474,7 +474,7 @@ static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
 
        *ucblocks = sp887x_readreg(state, 0xc0c);
        if (*ucblocks == 0xfff)
@@ -485,7 +485,7 @@ static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int sp887x_sleep(struct dvb_frontend* fe)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
 
        /* tristate TS output and disable interface pins */
        sp887x_writereg(state, 0xc18, 0x000);
@@ -495,7 +495,7 @@ static int sp887x_sleep(struct dvb_frontend* fe)
 
 static int sp887x_init(struct dvb_frontend* fe)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
         const struct firmware *fw = NULL;
        int ret;
 
@@ -534,7 +534,7 @@ static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend
 
 static void sp887x_release(struct dvb_frontend* fe)
 {
-       struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
+       struct sp887x_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -546,7 +546,7 @@ struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
        struct sp887x_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct sp887x_state*) kmalloc(sizeof(struct sp887x_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct sp887x_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 502c6403dfc64b87a84183427ebe1b6a6607886d..e681263bf07986bb4252402c185069bf4960aaa3 100644 (file)
@@ -365,7 +365,7 @@ static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_invers
 
 int stv0297_enable_plli2c(struct dvb_frontend *fe)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
 
        stv0297_writereg(state, 0x87, 0x78);
        stv0297_writereg(state, 0x86, 0xc8);
@@ -375,7 +375,7 @@ int stv0297_enable_plli2c(struct dvb_frontend *fe)
 
 static int stv0297_init(struct dvb_frontend *fe)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
        int i;
 
        /* soft reset */
@@ -416,7 +416,7 @@ static int stv0297_init(struct dvb_frontend *fe)
 
 static int stv0297_sleep(struct dvb_frontend *fe)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
 
        stv0297_writereg_mask(state, 0x80, 1, 1);
 
@@ -425,7 +425,7 @@ static int stv0297_sleep(struct dvb_frontend *fe)
 
 static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
 
        u8 sync = stv0297_readreg(state, 0xDF);
 
@@ -438,7 +438,7 @@ static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status)
 
 static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
        u8 BER[3];
 
        stv0297_writereg(state, 0xA0, 0x80);    // Start Counting bit errors for 4096 Bytes
@@ -453,7 +453,7 @@ static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
 
 static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
        u8 STRENGTH[2];
 
        stv0297_readregs(state, 0x41, STRENGTH, 2);
@@ -464,7 +464,7 @@ static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
 
 static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
        u8 SNR[2];
 
        stv0297_readregs(state, 0x07, SNR, 2);
@@ -475,7 +475,7 @@ static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr)
 
 static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
 
        *ucblocks = (stv0297_readreg(state, 0xD5) << 8)
                | stv0297_readreg(state, 0xD4);
@@ -485,7 +485,7 @@ static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
 
 static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
        int u_threshold;
        int initial_u;
        int blind_u;
@@ -689,7 +689,7 @@ timeout:
 
 static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
        int reg_00, reg_83;
 
        reg_00 = stv0297_readreg(state, 0x00);
@@ -725,7 +725,7 @@ static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
 
 static void stv0297_release(struct dvb_frontend *fe)
 {
-       struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+       struct stv0297_state *state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -737,7 +737,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
        struct stv0297_state *state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct stv0297_state *) kmalloc(sizeof(struct stv0297_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct stv0297_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 15b40541b62d1c8bb0065f051a382a4e07c198bb..cfa3928bb487bab6d61cb0991833dadf7326819a 100644 (file)
@@ -70,6 +70,7 @@ struct stv0299_state {
 #define STATUS_UCBLOCKS 1
 
 static int debug;
+static int debug_legacy_dish_switch;
 #define dprintk(args...) \
        do { \
                if (debug) printk(KERN_DEBUG "stv0299: " args); \
@@ -93,7 +94,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
 
 int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
 
        return stv0299_writeregI(state, reg, data);
 }
@@ -218,7 +219,7 @@ static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
 
 static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
        u64 big = srate;
        u32 ratio;
 
@@ -269,7 +270,7 @@ static int stv0299_get_symbolrate (struct stv0299_state* state)
 static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
                                    struct dvb_diseqc_master_cmd *m)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
        u8 val;
        int i;
 
@@ -299,7 +300,7 @@ static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
 
 static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
        u8 val;
 
        dprintk ("%s\n", __FUNCTION__);
@@ -326,7 +327,7 @@ static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t
 
 static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
        u8 val;
 
        if (stv0299_wait_diseqc_idle (state, 100) < 0)
@@ -348,7 +349,7 @@ static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 
 static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
        u8 reg0x08;
        u8 reg0x0c;
 
@@ -385,34 +386,84 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
        };
 }
 
-static int stv0299_send_legacy_dish_cmd(struct dvb_frontend* fe, u32 cmd)
+static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime)
 {
+       return ((curtime.tv_usec < lasttime.tv_usec) ?
+               1000000 - lasttime.tv_usec + curtime.tv_usec :
+               curtime.tv_usec - lasttime.tv_usec);
+}
+
+static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec)
+{
+       struct timeval lasttime;
+       s32 delta, newdelta;
+
+       waketime->tv_usec += add_usec;
+       if (waketime->tv_usec >= 1000000) {
+               waketime->tv_usec -= 1000000;
+               waketime->tv_sec++;
+       }
+
+       do_gettimeofday (&lasttime);
+       delta = stv0299_calc_usec_delay (lasttime, *waketime);
+       if (delta > 2500) {
+               msleep ((delta - 1500) / 1000);
+               do_gettimeofday (&lasttime);
+               newdelta = stv0299_calc_usec_delay (lasttime, *waketime);
+               delta = (newdelta > delta) ? 0 : newdelta;
+       }
+       if (delta > 0)
+               udelay (delta);
+}
+
+static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       u8 reg0x08;
+       u8 reg0x0c;
+       u8 lv_mask = 0x40;
        u8 last = 1;
        int i;
+       struct timeval nexttime;
+       struct timeval tv[10];
 
-       /* reset voltage at the end
-       if((0x50 & stv0299_readreg (i2c, 0x0c)) == 0x50)
-               cmd |= 0x80;
-       else
-               cmd &= 0x7F;
-       */
+       reg0x08 = stv0299_readreg (state, 0x08);
+       reg0x0c = stv0299_readreg (state, 0x0c);
+       reg0x0c &= 0x0f;
+       stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
+       if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
+               lv_mask = 0x10;
 
        cmd = cmd << 1;
-       dprintk("%s switch command: 0x%04x\n",__FUNCTION__, cmd);
+       if (debug_legacy_dish_switch)
+               printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd);
+
+       do_gettimeofday (&nexttime);
+       if (debug_legacy_dish_switch)
+               memcpy (&tv[0], &nexttime, sizeof (struct timeval));
+       stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
 
-       stv0299_set_voltage(fe,SEC_VOLTAGE_18);
-       msleep(32);
+       stv0299_sleep_until (&nexttime, 32000);
 
        for (i=0; i<9; i++) {
+               if (debug_legacy_dish_switch)
+                       do_gettimeofday (&tv[i+1]);
                if((cmd & 0x01) != last) {
-                       stv0299_set_voltage(fe, last ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
+                       /* set voltage to (last ? 13V : 18V) */
+                       stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
                        last = (last) ? 0 : 1;
                }
 
                cmd = cmd >> 1;
 
                if (i != 8)
-                       msleep(8);
+                       stv0299_sleep_until (&nexttime, 8000);
+       }
+       if (debug_legacy_dish_switch) {
+               printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
+                       __FUNCTION__, fe->dvb->num);
+               for (i=1; i < 10; i++)
+                       printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i]));
        }
 
        return 0;
@@ -420,7 +471,7 @@ static int stv0299_send_legacy_dish_cmd(struct dvb_frontend* fe, u32 cmd)
 
 static int stv0299_init (struct dvb_frontend* fe)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
        int i;
 
        dprintk("stv0299: init chip\n");
@@ -439,7 +490,7 @@ static int stv0299_init (struct dvb_frontend* fe)
 
 static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
 
        u8 signal = 0xff - stv0299_readreg (state, 0x18);
        u8 sync = stv0299_readreg (state, 0x1b);
@@ -467,7 +518,7 @@ static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
 
        if (state->errmode != STATUS_BER) return 0;
        *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
@@ -477,7 +528,7 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
 
        s32 signal =  0xffff - ((stv0299_readreg (state, 0x18) << 8)
                               | stv0299_readreg (state, 0x19));
@@ -494,7 +545,7 @@ static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
 
        s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
                           | stv0299_readreg (state, 0x25));
@@ -506,7 +557,7 @@ static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
 
        if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
        else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
@@ -516,7 +567,7 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
        int invval = 0;
 
        dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__);
@@ -584,7 +635,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
        s32 derot_freq;
        int invval;
 
@@ -609,7 +660,7 @@ static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int stv0299_sleep(struct dvb_frontend* fe)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
 
        stv0299_writeregI(state, 0x02, 0x80);
        state->initialised = 0;
@@ -619,7 +670,7 @@ static int stv0299_sleep(struct dvb_frontend* fe)
 
 static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
 {
-        struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+        struct stv0299_state* state = fe->demodulator_priv;
 
        fesettings->min_delay_ms = state->config->min_delay_ms;
        if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
@@ -634,7 +685,7 @@ static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten
 
 static void stv0299_release(struct dvb_frontend* fe)
 {
-       struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
+       struct stv0299_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -647,7 +698,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
        int id;
 
        /* allocate memory for the internal state */
-       state = (struct stv0299_state*) kmalloc(sizeof(struct stv0299_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct stv0299_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
@@ -719,6 +770,9 @@ static struct dvb_frontend_ops stv0299_ops = {
        .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
 };
 
+module_param(debug_legacy_dish_switch, int, 0444);
+MODULE_PARM_DESC(debug_legacy_dish_switch, "Enable timing analysis for Dish Network legacy switches");
+
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 
index 4e40d95ee95da02a1d9fcad8c4be55acbf433796..87d5f4d8790ffdfb47d6d78704e48fd699508005 100644 (file)
@@ -205,7 +205,7 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
 
 static int tda10021_init (struct dvb_frontend *fe)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
        int i;
 
        dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
@@ -238,7 +238,7 @@ static int tda10021_init (struct dvb_frontend *fe)
 static int tda10021_set_parameters (struct dvb_frontend *fe,
                            struct dvb_frontend_parameters *p)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
 
        //table for QAM4-QAM256 ready  QAM4  QAM16 QAM32 QAM64 QAM128 QAM256
        //CONF
@@ -278,7 +278,7 @@ static int tda10021_set_parameters (struct dvb_frontend *fe,
 
 static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
        int sync;
 
        *status = 0;
@@ -303,7 +303,7 @@ static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
 
        u32 _ber = tda10021_readreg(state, 0x14) |
                (tda10021_readreg(state, 0x15) << 8) |
@@ -315,7 +315,7 @@ static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
 
        u8 gain = tda10021_readreg(state, 0x17);
        *strength = (gain << 8) | gain;
@@ -325,7 +325,7 @@ static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
 
        u8 quality = ~tda10021_readreg(state, 0x18);
        *snr = (quality << 8) | quality;
@@ -335,7 +335,7 @@ static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
 
        *ucblocks = tda10021_readreg (state, 0x13) & 0x7f;
        if (*ucblocks == 0x7f)
@@ -350,7 +350,7 @@ static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
        int sync;
        s8 afc = 0;
 
@@ -378,7 +378,7 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
 
 static int tda10021_sleep(struct dvb_frontend* fe)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
 
        tda10021_writereg (state, 0x1b, 0x02);  /* pdown ADC */
        tda10021_writereg (state, 0x00, 0x80);  /* standby */
@@ -388,7 +388,7 @@ static int tda10021_sleep(struct dvb_frontend* fe)
 
 static void tda10021_release(struct dvb_frontend* fe)
 {
-       struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
+       struct tda10021_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -401,7 +401,7 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
        struct tda10021_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct tda10021_state*) kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 687ad9cf3384b3d8630e762d990c61379ccc3d9c..0beb370792ae30584d42398ccdb98273ecb86f91 100644 (file)
 #include "dvb_frontend.h"
 #include "tda1004x.h"
 
-#define TDA1004X_DEMOD_TDA10045 0
-#define TDA1004X_DEMOD_TDA10046 1
-
+enum tda1004x_demod {
+       TDA1004X_DEMOD_TDA10045,
+       TDA1004X_DEMOD_TDA10046,
+};
 
 struct tda1004x_state {
        struct i2c_adapter* i2c;
@@ -46,8 +47,9 @@ struct tda1004x_state {
        struct dvb_frontend frontend;
 
        /* private demod data */
-       u8 initialised:1;
-       u8 demod_type;
+       u8 initialised;
+       enum tda1004x_demod demod_type;
+       u8 fw_version;
 };
 
 
@@ -139,7 +141,7 @@ static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data)
 {
        int ret;
        u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 };
+       struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
 
        dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data);
 
@@ -160,8 +162,8 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
        int ret;
        u8 b0[] = { reg };
        u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1},
-                               { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}};
+       struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
+                               { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
 
        dprintk("%s: reg=0x%x\n", __FUNCTION__, reg);
 
@@ -294,7 +296,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
                              u8 dspCodeCounterReg, u8 dspCodeInReg)
 {
        u8 buf[65];
-       struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = buf,.len = 0 };
+       struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 };
        int tx_size;
        int pos = 0;
 
@@ -304,12 +306,10 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
 
        buf[0] = dspCodeInReg;
        while (pos != len) {
-
                // work out how much to send this time
                tx_size = len - pos;
-               if (tx_size > 0x10) {
+               if (tx_size > 0x10)
                        tx_size = 0x10;
-               }
 
                // send the chunk
                memcpy(buf + 1, mem + pos, tx_size);
@@ -322,6 +322,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
 
                dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
        }
+
        return 0;
 }
 
@@ -335,9 +336,8 @@ static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion)
 
        data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
        data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
-       if (data1 != 0x67 || data2 != dspVersion) {
+       if ((data1 != 0x67) || (data2 != dspVersion))
                return -EIO;
-       }
 
        return 0;
 }
@@ -348,9 +348,9 @@ static int tda10045_fwupload(struct dvb_frontend* fe)
        int ret;
        const struct firmware *fw;
 
-
        /* don't re-upload unless necessary */
-       if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0;
+       if (tda1004x_check_upload_ok(state, 0x2c) == 0)
+               return 0;
 
        /* request the firmware, this will block until someone uploads it */
        printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
@@ -381,6 +381,25 @@ static int tda10045_fwupload(struct dvb_frontend* fe)
        return tda1004x_check_upload_ok(state, 0x2c);
 }
 
+static int tda10046_get_fw_version(struct tda1004x_state *state,
+                                  const struct firmware *fw)
+{
+       const unsigned char pattern[] = { 0x67, 0x00, 0x50, 0x62, 0x5e, 0x18, 0x67 };
+       unsigned int i;
+
+       /* area guessed from firmware v20, v21 and v25 */
+       for (i = 0x660; i < 0x700; i++) {
+               if (!memcmp(&fw->data[i], pattern, sizeof(pattern))) {
+                       state->fw_version = fw->data[i + sizeof(pattern)];
+                       printk(KERN_INFO "tda1004x: using firmware v%02x\n",
+                                       state->fw_version);
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
 static int tda10046_fwupload(struct dvb_frontend* fe)
 {
        struct tda1004x_state* state = fe->demodulator_priv;
@@ -394,7 +413,8 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
        msleep(100);
 
        /* don't re-upload unless necessary */
-       if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0;
+       if (tda1004x_check_upload_ok(state, state->fw_version) == 0)
+               return 0;
 
        /* request the firmware, this will block until someone uploads it */
        printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE);
@@ -404,9 +424,20 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
                return ret;
        }
 
+       if (fw->size < 24478) { /* size of firmware v20, which is the smallest of v20, v21 and v25 */
+               printk("tda1004x: firmware file seems to be too small (%d bytes)\n", fw->size);
+               return -EINVAL;
+       }
+
+       ret = tda10046_get_fw_version(state, fw);
+       if (ret < 0) {
+               printk("tda1004x: unable to find firmware version\n");
+               return ret;
+       }
+
        /* set parameters */
        tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10);
-       tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0);
+       tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c);
        tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
        tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
        tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
@@ -419,7 +450,7 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
 
        /* wait for DSP to initialise */
        timeout = jiffies + HZ;
-       while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
+       while (!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
                if (time_after(jiffies, timeout)) {
                        printk("tda1004x: DSP failed to initialised.\n");
                        return -EIO;
@@ -427,7 +458,7 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
                msleep(1);
        }
 
-       return tda1004x_check_upload_ok(state, 0x20);
+       return tda1004x_check_upload_ok(state, state->fw_version);
 }
 
 static int tda1004x_encode_fec(int fec)
@@ -483,7 +514,8 @@ static int tda10045_init(struct dvb_frontend* fe)
 
        dprintk("%s\n", __FUNCTION__);
 
-       if (state->initialised) return 0;
+       if (state->initialised)
+               return 0;
 
        if (tda10045_fwupload(fe)) {
                printk("tda1004x: firmware upload failed\n");
@@ -523,7 +555,8 @@ static int tda10046_init(struct dvb_frontend* fe)
        struct tda1004x_state* state = fe->demodulator_priv;
        dprintk("%s\n", __FUNCTION__);
 
-       if (state->initialised) return 0;
+       if (state->initialised)
+               return 0;
 
        if (tda10046_fwupload(fe)) {
                printk("tda1004x: firmware upload failed\n");
@@ -545,7 +578,7 @@ static int tda10046_init(struct dvb_frontend* fe)
        tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
        tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer
        tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
-       tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
+       tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); // PLL P = N = 0
        tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99
        tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221
        tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // }
@@ -621,12 +654,14 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
 
                // set HP FEC
                tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP);
-               if (tmp < 0) return tmp;
+               if (tmp < 0)
+                       return tmp;
                tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp);
 
                // set LP FEC
                tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP);
-               if (tmp < 0) return tmp;
+               if (tmp < 0)
+                       return tmp;
                tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3);
 
                // set constellation
@@ -671,7 +706,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
        }
 
        // set bandwidth
-       switch(state->demod_type) {
+       switch (state->demod_type) {
        case TDA1004X_DEMOD_TDA10045:
                tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
                break;
@@ -683,7 +718,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
 
        // set inversion
        inversion = fe_params->inversion;
-       if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON;
+       if (state->config->invert)
+               inversion = inversion ? INVERSION_OFF : INVERSION_ON;
        switch (inversion) {
        case INVERSION_OFF:
                tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0);
@@ -750,19 +786,19 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
        }
 
        // start the lock
-       switch(state->demod_type) {
+       switch (state->demod_type) {
        case TDA1004X_DEMOD_TDA10045:
                tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
                tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
-               msleep(10);
                break;
 
        case TDA1004X_DEMOD_TDA10046:
                tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
-               msleep(10);
                break;
        }
 
+       msleep(10);
+
        return 0;
 }
 
@@ -773,13 +809,13 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete
 
        // inversion status
        fe_params->inversion = INVERSION_OFF;
-       if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) {
+       if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20)
                fe_params->inversion = INVERSION_ON;
-       }
-       if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
+       if (state->config->invert)
+               fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
 
        // bandwidth
-       switch(state->demod_type) {
+       switch (state->demod_type) {
        case TDA1004X_DEMOD_TDA10045:
                switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) {
                case 0x14:
@@ -830,9 +866,8 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete
 
        // transmission mode
        fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
-       if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) {
+       if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10)
                fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
-       }
 
        // guard interval
        switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {
@@ -880,30 +915,33 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
 
        // read status
        status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
-       if (status == -1) {
+       if (status == -1)
                return -EIO;
-       }
 
        // decode
        *fe_status = 0;
-       if (status & 4) *fe_status |= FE_HAS_SIGNAL;
-       if (status & 2) *fe_status |= FE_HAS_CARRIER;
-       if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+       if (status & 4)
+               *fe_status |= FE_HAS_SIGNAL;
+       if (status & 2)
+               *fe_status |= FE_HAS_CARRIER;
+       if (status & 8)
+               *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
 
        // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi
        // is getting anything valid
        if (!(*fe_status & FE_HAS_VITERBI)) {
                // read the CBER
                cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
-               if (cber == -1) return -EIO;
+               if (cber == -1)
+                       return -EIO;
                status = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
-               if (status == -1) return -EIO;
+               if (status == -1)
+                       return -EIO;
                cber |= (status << 8);
                tda1004x_read_byte(state, TDA1004X_CBER_RESET);
 
-               if (cber != 65535) {
+               if (cber != 65535)
                        *fe_status |= FE_HAS_VITERBI;
-               }
        }
 
        // if we DO have some valid VITERBI output, but don't already have SYNC
@@ -911,20 +949,22 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
        if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {
                // read the VBER
                vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB);
-               if (vber == -1) return -EIO;
+               if (vber == -1)
+                       return -EIO;
                status = tda1004x_read_byte(state, TDA1004X_VBER_MID);
-               if (status == -1) return -EIO;
+               if (status == -1)
+                       return -EIO;
                vber |= (status << 8);
                status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
-               if (status == -1) return -EIO;
+               if (status == -1)
+                       return -EIO;
                vber |= ((status << 16) & 0x0f);
                tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
 
                // if RS has passed some valid TS packets, then we must be
                // getting some SYNC bytes
-               if (vber < 16632) {
+               if (vber < 16632)
                        *fe_status |= FE_HAS_SYNC;
-               }
        }
 
        // success
@@ -941,7 +981,7 @@ static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
        dprintk("%s\n", __FUNCTION__);
 
        // determine the register to use
-       switch(state->demod_type) {
+       switch (state->demod_type) {
        case TDA1004X_DEMOD_TDA10045:
                reg = TDA10045H_S_AGC;
                break;
@@ -972,9 +1012,8 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
        tmp = tda1004x_read_byte(state, TDA1004X_SNR);
        if (tmp < 0)
                return -EIO;
-       if (tmp) {
+       if (tmp)
                tmp = 255 - tmp;
-       }
 
        *snr = ((tmp << 8) | tmp);
        dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);
@@ -1009,11 +1048,11 @@ static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
                        break;
        }
 
-       if (tmp != 0x7f) {
+       if (tmp != 0x7f)
                *ucblocks = tmp;
-       } else {
+       else
                *ucblocks = 0xffffffff;
-       }
+
        dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks);
        return 0;
 }
@@ -1027,10 +1066,12 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
 
        // read it in
        tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
-       if (tmp < 0) return -EIO;
+       if (tmp < 0)
+               return -EIO;
        *ber = tmp << 1;
        tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
-       if (tmp < 0) return -EIO;
+       if (tmp < 0)
+               return -EIO;
        *ber |= (tmp << 9);
        tda1004x_read_byte(state, TDA1004X_CBER_RESET);
 
@@ -1042,7 +1083,7 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
 {
        struct tda1004x_state* state = fe->demodulator_priv;
 
-       switch(state->demod_type) {
+       switch (state->demod_type) {
        case TDA1004X_DEMOD_TDA10045:
                tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10);
                break;
@@ -1066,74 +1107,11 @@ static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronte
 
 static void tda1004x_release(struct dvb_frontend* fe)
 {
-       struct tda1004x_state* state = (struct tda1004x_state*) fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops tda10045_ops;
-
-struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
-                                    struct i2c_adapter* i2c)
-{
-       struct tda1004x_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
-       state->initialised = 0;
-       state->demod_type = TDA1004X_DEMOD_TDA10045;
-
-       /* check if the demod is there */
-       if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) goto error;
-
-       /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
+       struct tda1004x_state *state = fe->demodulator_priv;
        kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops tda10046_ops;
-
-struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
-                                    struct i2c_adapter* i2c)
-{
-       struct tda1004x_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
-       state->initialised = 0;
-       state->demod_type = TDA1004X_DEMOD_TDA10046;
-
-       /* check if the demod is there */
-       if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) goto error;
-
-       /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       if (state) kfree(state);
-       return NULL;
 }
 
 static struct dvb_frontend_ops tda10045_ops = {
-
        .info = {
                .name = "Philips TDA10045H DVB-T",
                .type = FE_OFDM,
@@ -1163,8 +1141,36 @@ static struct dvb_frontend_ops tda10045_ops = {
        .read_ucblocks = tda1004x_read_ucblocks,
 };
 
-static struct dvb_frontend_ops tda10046_ops = {
+struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
+                                    struct i2c_adapter* i2c)
+{
+       struct tda1004x_state *state;
+
+       /* allocate memory for the internal state */
+       state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
+       if (!state)
+               return NULL;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
+       state->initialised = 0;
+       state->demod_type = TDA1004X_DEMOD_TDA10045;
+
+       /* check if the demod is there */
+       if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) {
+               kfree(state);
+               return NULL;
+       }
 
+       /* create dvb_frontend */
+       state->frontend.ops = &state->ops;
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+}
+
+static struct dvb_frontend_ops tda10046_ops = {
        .info = {
                .name = "Philips TDA10046H DVB-T",
                .type = FE_OFDM,
@@ -1194,6 +1200,36 @@ static struct dvb_frontend_ops tda10046_ops = {
        .read_ucblocks = tda1004x_read_ucblocks,
 };
 
+struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
+                                    struct i2c_adapter* i2c)
+{
+       struct tda1004x_state *state;
+
+       /* allocate memory for the internal state */
+       state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
+       if (!state)
+               return NULL;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
+       state->initialised = 0;
+       state->demod_type = TDA1004X_DEMOD_TDA10046;
+       state->fw_version = 0x20;       /* dummy default value */
+
+       /* check if the demod is there */
+       if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {
+               kfree(state);
+               return NULL;
+       }
+
+       /* create dvb_frontend */
+       state->frontend.ops = &state->ops;
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+}
+
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 
index e452fc0bad1153734edf65ac75061a3919c75b7c..c8e1d54ff26283b0b9a475f1fa2a5006d34922a4 100644 (file)
@@ -32,10 +32,13 @@ struct tda1004x_config
        u8 demod_address;
 
        /* does the "inversion" need inverted? */
-       u8 invert:1;
+       u8 invert;
 
        /* Does the OCLK signal need inverted? */
-       u8 invert_oclk:1;
+       u8 invert_oclk;
+
+       /* value of N_I2C of the CONF_PLL3 register */
+       u8 n_i2c;
 
        /* PLL maintenance */
        int (*pll_init)(struct dvb_frontend* fe);
index da82e90d6d136181f2bd5878850da4307c59fc14..168e013d23bd5478f06b048e3185c06e73b72c31 100644 (file)
@@ -226,7 +226,7 @@ static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_c
 static int tda8083_send_diseqc_msg (struct dvb_frontend* fe,
                                    struct dvb_diseqc_master_cmd *m)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
        int i;
 
        tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */
@@ -243,7 +243,7 @@ static int tda8083_send_diseqc_msg (struct dvb_frontend* fe,
 
 static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
 
        u8 signal = ~tda8083_readreg (state, 0x01);
        u8 sync = tda8083_readreg (state, 0x02);
@@ -270,7 +270,7 @@ static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
 
        u8 signal = ~tda8083_readreg (state, 0x01);
        *strength = (signal << 8) | signal;
@@ -280,7 +280,7 @@ static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
 
        u8 _snr = tda8083_readreg (state, 0x08);
        *snr = (_snr << 8) | _snr;
@@ -290,7 +290,7 @@ static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
 
        state->config->pll_set(fe, p);
        tda8083_set_inversion (state, p->inversion);
@@ -305,7 +305,7 @@ static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
 
        /*  FIXME: get symbolrate & frequency offset...*/
        /*p->frequency = ???;*/
@@ -319,7 +319,7 @@ static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int tda8083_sleep(struct dvb_frontend* fe)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
 
        tda8083_writereg (state, 0x00, 0x02);
        return 0;
@@ -327,7 +327,7 @@ static int tda8083_sleep(struct dvb_frontend* fe)
 
 static int tda8083_init(struct dvb_frontend* fe)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
        int i;
 
        for (i=0; i<44; i++)
@@ -343,7 +343,7 @@ static int tda8083_init(struct dvb_frontend* fe)
 
 static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
 
        tda8083_send_diseqc_burst (state, burst);
        tda8083_writereg (state, 0x00, 0x3c);
@@ -354,7 +354,7 @@ static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
 
 static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
 
        tda8083_set_tone (state, tone);
        tda8083_writereg (state, 0x00, 0x3c);
@@ -365,7 +365,7 @@ static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t t
 
 static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
 
        tda8083_set_voltage (state, voltage);
        tda8083_writereg (state, 0x00, 0x3c);
@@ -376,7 +376,7 @@ static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t
 
 static void tda8083_release(struct dvb_frontend* fe)
 {
-       struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
+       struct tda8083_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -388,7 +388,7 @@ struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
        struct tda8083_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct tda8083_state*) kmalloc(sizeof(struct tda8083_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct tda8083_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index c99632114283d9e242615249c17fcdaa2a73122d..032d348dafb749acfb9144453e8400d8666c42a8 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/spinlock.h>
 #include <linux/threads.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -400,7 +400,7 @@ static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state)
 
 static int tda8044_init(struct dvb_frontend* fe)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
        int ret;
 
        /*
@@ -432,7 +432,7 @@ static int tda8044_init(struct dvb_frontend* fe)
 
 static int tda8083_init(struct dvb_frontend* fe)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab));
 
@@ -447,7 +447,7 @@ static int tda8083_init(struct dvb_frontend* fe)
 
 static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        switch (voltage) {
        case SEC_VOLTAGE_13:
@@ -463,7 +463,7 @@ static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
 
 static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        switch (tone) {
        case SEC_TONE_OFF:
@@ -477,7 +477,7 @@ static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 
 static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        if (cmd->msg_len > 6)
                return -EINVAL;
@@ -492,7 +492,7 @@ static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
 
 static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        switch (cmd) {
        case SEC_MINI_A:
@@ -512,7 +512,7 @@ static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
 
 static int tda80xx_sleep(struct dvb_frontend* fe)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        tda80xx_writereg(state, 0x00, 0x02);    /* enter standby */
 
@@ -521,7 +521,7 @@ static int tda80xx_sleep(struct dvb_frontend* fe)
 
 static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        tda80xx_writereg(state, 0x1c, 0x80);
        state->config->pll_set(fe, p);
@@ -537,7 +537,7 @@ static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        if (!state->config->irq)
                tda80xx_read_status_int(state);
@@ -550,7 +550,7 @@ static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        if (!state->config->irq)
                tda80xx_read_status_int(state);
@@ -561,7 +561,7 @@ static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
        int ret;
        u8 buf[3];
 
@@ -575,7 +575,7 @@ static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        u8 gain = ~tda80xx_readreg(state, 0x01);
        *strength = (gain << 8) | gain;
@@ -585,7 +585,7 @@ static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        u8 quality = tda80xx_readreg(state, 0x08);
        *snr = (quality << 8) | quality;
@@ -595,7 +595,7 @@ static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        *ucblocks = tda80xx_readreg(state, 0x0f);
        if (*ucblocks == 0xff)
@@ -606,7 +606,7 @@ static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int tda80xx_init(struct dvb_frontend* fe)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        switch(state->id) {
        case ID_TDA8044:
@@ -620,7 +620,7 @@ static int tda80xx_init(struct dvb_frontend* fe)
 
 static void tda80xx_release(struct dvb_frontend* fe)
 {
-       struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
+       struct tda80xx_state* state = fe->demodulator_priv;
 
        if (state->config->irq)
                free_irq(state->config->irq, &state->worklet);
@@ -637,7 +637,7 @@ struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
        int ret;
 
        /* allocate memory for the internal state */
-       state = (struct tda80xx_state*) kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 9c0d23e1d9e5a89993f47ecaad6d926729944fb6..70fb44b391a75e5877b0622acc30f2ee6e5f1fc4 100644 (file)
@@ -70,7 +70,6 @@ static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data)
                printk("ves1820: %s(): writereg error (reg == 0x%02x,"
                        "val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret);
 
-       msleep(10);
        return (ret != 1) ? -EREMOTEIO : 0;
 }
 
@@ -193,7 +192,7 @@ static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate)
 
 static int ves1820_init(struct dvb_frontend* fe)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
        int i;
        int val;
 
@@ -214,7 +213,7 @@ static int ves1820_init(struct dvb_frontend* fe)
 
 static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
        static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 };
        static const u8 reg0x01[] = { 140, 140, 106, 100, 92 };
        static const u8 reg0x05[] = { 135, 100, 70, 54, 38 };
@@ -241,7 +240,7 @@ static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_p
 
 static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
        int sync;
 
        *status = 0;
@@ -267,7 +266,7 @@ static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
 
        u32 _ber = ves1820_readreg(state, 0x14) |
                        (ves1820_readreg(state, 0x15) << 8) |
@@ -279,7 +278,7 @@ static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
 
        u8 gain = ves1820_readreg(state, 0x17);
        *strength = (gain << 8) | gain;
@@ -289,7 +288,7 @@ static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
 
        u8 quality = ~ves1820_readreg(state, 0x18);
        *snr = (quality << 8) | quality;
@@ -299,7 +298,7 @@ static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
 
        *ucblocks = ves1820_readreg(state, 0x13) & 0x7f;
        if (*ucblocks == 0x7f)
@@ -314,7 +313,7 @@ static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
        int sync;
        s8 afc = 0;
 
@@ -345,7 +344,7 @@ static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int ves1820_sleep(struct dvb_frontend* fe)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
 
        ves1820_writereg(state, 0x1b, 0x02);    /* pdown ADC */
        ves1820_writereg(state, 0x00, 0x80);    /* standby */
@@ -364,7 +363,7 @@ static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten
 
 static void ves1820_release(struct dvb_frontend* fe)
 {
-       struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
+       struct ves1820_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -377,7 +376,7 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
        struct ves1820_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct ves1820_state*) kmalloc(sizeof(struct ves1820_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct ves1820_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index edcad283aa86e990a6f3359ba30c5a6671a787eb..821df8e839d056669d594ac1bcf47adb7d65e9b1 100644 (file)
@@ -263,7 +263,7 @@ static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
 
 static int ves1x93_init (struct dvb_frontend* fe)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
        int i;
        int val;
 
@@ -289,7 +289,7 @@ static int ves1x93_init (struct dvb_frontend* fe)
 
 static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
 
        switch (voltage) {
        case SEC_VOLTAGE_13:
@@ -305,7 +305,7 @@ static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
 
 static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
 
        u8 sync = ves1x93_readreg (state, 0x0e);
 
@@ -346,7 +346,7 @@ static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
 
        *ber = ves1x93_readreg (state, 0x15);
        *ber |= (ves1x93_readreg (state, 0x16) << 8);
@@ -358,7 +358,7 @@ static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber)
 
 static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
 
        u8 signal = ~ves1x93_readreg (state, 0x0b);
        *strength = (signal << 8) | signal;
@@ -368,7 +368,7 @@ static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 
 static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
 
        u8 _snr = ~ves1x93_readreg (state, 0x1c);
        *snr = (_snr << 8) | _snr;
@@ -378,7 +378,7 @@ static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr)
 
 static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
 
        *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f;
 
@@ -393,7 +393,7 @@ static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 
 static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
 
        ves1x93_writereg(state, 0x00, 0x11);
        state->config->pll_set(fe, p);
@@ -408,7 +408,7 @@ static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
        int afc;
 
        afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2;
@@ -431,14 +431,14 @@ static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 
 static int ves1x93_sleep(struct dvb_frontend* fe)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
 
        return ves1x93_writereg (state, 0x00, 0x08);
 }
 
 static void ves1x93_release(struct dvb_frontend* fe)
 {
-       struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
+       struct ves1x93_state* state = fe->demodulator_priv;
        kfree(state);
 }
 
@@ -451,7 +451,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
        u8 identity;
 
        /* allocate memory for the internal state */
-       state = (struct ves1x93_state*) kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 922c205a265227fdf1f5919566174ec83e7f2f50..8e33a850e13ebf4696689664cce737843f3b1239 100644 (file)
@@ -130,7 +130,7 @@ static void init_av7110_av(struct av7110 *av7110)
        av7110->current_input = 0;
        if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
                printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
-                       av7110->dvb_adapter->num);
+                       av7110->dvb_adapter.num);
                av7110->adac_type = DVB_ADAC_CRYSTAL;
                i2c_writereg(av7110, 0x20, 0x01, 0xd2);
                i2c_writereg(av7110, 0x20, 0x02, 0x49);
@@ -145,13 +145,13 @@ static void init_av7110_av(struct av7110 *av7110)
        }
        else if (dev->pci->subsystem_vendor == 0x110a) {
                printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
-                       av7110->dvb_adapter->num);
+                       av7110->dvb_adapter.num);
                av7110->adac_type = DVB_ADAC_NONE;
        }
        else {
                av7110->adac_type = adac;
                printk("dvb-ttpci: adac type set to %d @ card %d\n",
-                       av7110->dvb_adapter->num, av7110->adac_type);
+                       av7110->dvb_adapter.num, av7110->adac_type);
        }
 
        if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
@@ -231,7 +231,7 @@ static int arm_thread(void *data)
 
                if (newloops == av7110->arm_loops) {
                        printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
-                              av7110->dvb_adapter->num);
+                              av7110->dvb_adapter.num);
 
                        arm_error(av7110);
                        av7710_set_video_mode(av7110, vidmode);
@@ -1282,7 +1282,7 @@ static int av7110_register(struct av7110 *av7110)
        av7110->dmxdev.demux = &dvbdemux->dmx;
        av7110->dmxdev.capabilities = 0;
 
-       dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
+       dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
 
        av7110->hw_frontend.source = DMX_FRONTEND_0;
 
@@ -1307,11 +1307,11 @@ static int av7110_register(struct av7110 *av7110)
        av7110_ca_register(av7110);
 
 #ifdef CONFIG_DVB_AV7110_OSD
-       dvb_register_device(av7110->dvb_adapter, &av7110->osd_dev,
+       dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
                            &dvbdev_osd, av7110, DVB_DEVICE_OSD);
 #endif
 
-       dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
+       dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
 
        if (budgetpatch) {
                /* initialize software demux1 without its own frontend
@@ -1334,9 +1334,9 @@ static int av7110_register(struct av7110 *av7110)
                av7110->dmxdev1.demux = &dvbdemux1->dmx;
                av7110->dmxdev1.capabilities = 0;
 
-               dvb_dmxdev_init(&av7110->dmxdev1, av7110->dvb_adapter);
+               dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
 
-               dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
+               dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
                printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
        }
        return 0;
@@ -1673,6 +1673,106 @@ static struct stv0299_config alps_bsru6_config = {
 };
 
 
+static u8 alps_bsbe1_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
+       0x06, 0x40,   /* DAC not used, set to high impendance mode */
+       0x07, 0x00,   /* DAC LSB */
+       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
+       0x09, 0x00,   /* FIFO */
+       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
+       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
+       0x10, 0x3f,   // AGC2  0x3d
+       0x11, 0x84,
+       0x12, 0xb5,   // Lock detect: -64  Carrier freq detect:on
+       0x15, 0xc9,   // lock detector threshold
+       0x16, 0x00,
+       0x17, 0x00,
+       0x18, 0x00,
+       0x19, 0x00,
+       0x1a, 0x00,
+       0x1f, 0x50,
+       0x20, 0x00,
+       0x21, 0x00,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
+       0x29, 0x1e,  // 1/2 threshold
+       0x2a, 0x14,  // 2/3 threshold
+       0x2b, 0x0f,  // 3/4 threshold
+       0x2c, 0x09,  // 5/6 threshold
+       0x2d, 0x05,  // 7/8 threshold
+       0x2e, 0x01,
+       0x31, 0x1f,  // test all FECs
+       0x32, 0x19,  // viterbi and synchro search
+       0x33, 0xfc,  // rs control
+       0x34, 0x93,  // error control
+       0x0f, 0x92,
+       0xff, 0xff
+};
+
+static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+       struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
+       int ret;
+       u8 data[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       if ((params->frequency < 950000) || (params->frequency > 2150000))
+               return -EINVAL;
+
+       div = (params->frequency + (125 - 1)) / 125; // round correctly
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
+       data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
+
+       ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
+       return (ret != 1) ? -EIO : 0;
+}
+
+static struct stv0299_config alps_bsbe1_config = {
+       .demod_address = 0x68,
+       .inittab = alps_bsbe1_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .enhanced_tuning = 0,
+       .skip_reinit = 0,
+       .min_delay_ms = 100,
+       .set_symbol_rate = alps_bsru6_set_symbol_rate,
+       .pll_set = alps_bsbe1_pll_set,
+};
+
+static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
+       int ret;
+       u8 data[1];
+       struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       switch(voltage) {
+       case SEC_VOLTAGE_OFF:
+               data[0] = 0x00;
+               break;
+       case SEC_VOLTAGE_13:
+               data[0] = 0x44;
+               break;
+       case SEC_VOLTAGE_18:
+               data[0] = 0x4c;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
+       return (ret != 1) ? -EIO : 0;
+}
+
 
 static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
 {
@@ -2116,6 +2216,14 @@ static int frontend_init(struct av7110 *av7110)
                                av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
                                break;
                        }
+                       break;
+
+               case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
+                       /* ALPS BSBE1 */
+                       av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
+                       if (av7110->fe)
+                               av7110->fe->ops->set_voltage = lnbp21_set_voltage;
+                       break;
                }
        }
 
@@ -2138,7 +2246,7 @@ static int frontend_init(struct av7110 *av7110)
                FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
                FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
 
-               ret = dvb_register_frontend(av7110->dvb_adapter, av7110->fe);
+               ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
                if (ret < 0) {
                        printk("av7110: Frontend registration failed!\n");
                        if (av7110->fe->ops->release)
@@ -2352,7 +2460,7 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
                goto err_dvb_unregister_adapter_2;
 
        ttpci_eeprom_parse_mac(&av7110->i2c_adap,
-                              av7110->dvb_adapter->proposed_mac);
+                              av7110->dvb_adapter.proposed_mac);
        ret = -ENOMEM;
 
        if (budgetpatch) {
@@ -2523,7 +2631,7 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
        if (ret < 0)
                goto err_av7110_unregister_11;
 
-       av7110->dvb_adapter->priv = av7110;
+       av7110->dvb_adapter.priv = av7110;
        ret = frontend_init(av7110);
        if (ret < 0)
                goto err_av7110_exit_v4l_12;
@@ -2558,7 +2666,7 @@ err_saa71466_vfree_4:
 err_i2c_del_3:
        i2c_del_adapter(&av7110->i2c_adap);
 err_dvb_unregister_adapter_2:
-       dvb_unregister_adapter(av7110->dvb_adapter);
+       dvb_unregister_adapter(&av7110->dvb_adapter);
 err_put_firmware_1:
        put_firmware(av7110);
 err_kfree_0:
@@ -2604,7 +2712,7 @@ static int av7110_detach(struct saa7146_dev* saa)
 
        i2c_del_adapter(&av7110->i2c_adap);
 
-       dvb_unregister_adapter (av7110->dvb_adapter);
+       dvb_unregister_adapter (&av7110->dvb_adapter);
 
        av7110_num--;
 
@@ -2672,21 +2780,23 @@ MAKE_AV7110_INFO(ttt_1_X,    "Technotrend/Hauppauge WinTV DVB-T rev1.X");
 MAKE_AV7110_INFO(ttc_1_X,    "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
 MAKE_AV7110_INFO(ttc_2_X,    "Technotrend/Hauppauge WinTV DVB-C rev2.X");
 MAKE_AV7110_INFO(tts_2_X,    "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
+MAKE_AV7110_INFO(tts_2_3,    "Technotrend/Hauppauge WinTV Nexus-S rev2.3");
 MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
 MAKE_AV7110_INFO(ttt,        "Technotrend/Hauppauge DVB-T");
 MAKE_AV7110_INFO(fsc,        "Fujitsu Siemens DVB-C");
 MAKE_AV7110_INFO(fss,        "Fujitsu Siemens DVB-S rev1.6");
 
 static struct pci_device_id pci_tbl[] = {
+       MAKE_EXTENSION_PCI(fsc,       0x110a, 0x0000),
        MAKE_EXTENSION_PCI(tts_1_X,   0x13c2, 0x0000),
        MAKE_EXTENSION_PCI(ttt_1_X,   0x13c2, 0x0001),
        MAKE_EXTENSION_PCI(ttc_2_X,   0x13c2, 0x0002),
        MAKE_EXTENSION_PCI(tts_2_X,   0x13c2, 0x0003),
-       MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
-       MAKE_EXTENSION_PCI(fsc,       0x110a, 0x0000),
-       MAKE_EXTENSION_PCI(ttc_1_X,   0x13c2, 0x000a),
        MAKE_EXTENSION_PCI(fss,       0x13c2, 0x0006),
        MAKE_EXTENSION_PCI(ttt,       0x13c2, 0x0008),
+       MAKE_EXTENSION_PCI(ttc_1_X,   0x13c2, 0x000a),
+       MAKE_EXTENSION_PCI(tts_2_3,   0x13c2, 0x000e),
+       MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
 
 /*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
 /*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
index 5070e0523da71f2e5f8e8d71d6cd53869817dd9d..4f69b4d01479232c6a3eb7e4460aab3290ffd158 100644 (file)
@@ -220,7 +220,7 @@ struct av7110 {
 
        struct audio_mixer      mixer;
 
-       struct dvb_adapter       *dvb_adapter;
+       struct dvb_adapter       dvb_adapter;
        struct dvb_device        *video_dev;
        struct dvb_device        *audio_dev;
        struct dvb_device        *ca_dev;
@@ -274,7 +274,6 @@ extern void av7110_ir_exit (void);
 extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val);
 extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg);
 extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val);
-extern int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val);
 
 
 extern int av7110_init_analog_module(struct av7110 *av7110);
index d77e8a00688fc9f7daa195a970728a16a5b95ae3..ccf946125d028fb2f22273143d4e62bdfd35fbb9 100644 (file)
@@ -1075,7 +1075,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
                }
                if (ret < 0)
                        break;
-               av7110->videostate.video_format = format;
+               av7110->videostate.display_format = format;
                ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,
                                    1, (u16) val);
                break;
@@ -1230,14 +1230,20 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
                switch(av7110->audiostate.channel_select) {
                case AUDIO_STEREO:
                        audcom(av7110, AUDIO_CMD_STEREO);
+                       if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+                               i2c_writereg(av7110, 0x20, 0x02, 0x49);
                        break;
 
                case AUDIO_MONO_LEFT:
                        audcom(av7110, AUDIO_CMD_MONO_L);
+                       if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+                               i2c_writereg(av7110, 0x20, 0x02, 0x4a);
                        break;
 
                case AUDIO_MONO_RIGHT:
                        audcom(av7110, AUDIO_CMD_MONO_R);
+                       if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+                               i2c_writereg(av7110, 0x20, 0x02, 0x45);
                        break;
 
                default:
@@ -1409,10 +1415,10 @@ int av7110_av_register(struct av7110 *av7110)
        av7110->video_events.overflow = 0;
        memset(&av7110->video_size, 0, sizeof (video_size_t));
 
-       dvb_register_device(av7110->dvb_adapter, &av7110->video_dev,
+       dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev,
                            &dvbdev_video, av7110, DVB_DEVICE_VIDEO);
 
-       dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev,
+       dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev,
                            &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);
 
        return 0;
index 21f7aacf77266163690eeed7d94b51550fcb6b1b..c3801e328fe912d2caf810e775b8129fd4d78d33 100644 (file)
@@ -123,7 +123,7 @@ static void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *
 }
 
 static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file,
-               int slots, ca_slot_info_t *slot)
+                      int slots, ca_slot_info_t *slot)
 {
        int i;
        int len = 0;
@@ -370,7 +370,7 @@ static struct dvb_device dvbdev_ca = {
 
 int av7110_ca_register(struct av7110 *av7110)
 {
-       return dvb_register_device(av7110->dvb_adapter, &av7110->ca_dev,
+       return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev,
                                   &dvbdev_ca, av7110, DVB_DEVICE_CA);
 }
 
index bd6e5ea4aefe3768ab960bff0d1440c5190d6e18..7fa4a0ebe133db1e2976be272245a4ba1dd61efe 100644 (file)
@@ -104,7 +104,7 @@ u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count)
 
 
 /* av7110 ARM core boot stuff */
-
+#if 0
 void av7110_reset_arm(struct av7110 *av7110)
 {
        saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
@@ -124,7 +124,7 @@ void av7110_reset_arm(struct av7110 *av7110)
        av7110->arm_ready = 1;
        dprintk(1, "reset ARM\n");
 }
-
+#endif  /*  0  */
 
 static int waitdebi(struct av7110 *av7110, int adr, int state)
 {
@@ -335,7 +335,7 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
        return 0;
 }
 
-int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
+static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
 {
        int i;
        unsigned long start;
@@ -455,7 +455,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
        return 0;
 }
 
-int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
+static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
 {
        int ret;
 
@@ -500,6 +500,7 @@ int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
        return ret;
 }
 
+#if 0
 int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
 {
        int i, ret;
@@ -521,6 +522,7 @@ int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
                printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
        return ret;
 }
+#endif  /*  0  */
 
 int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
                      int request_buf_len, u16 *reply_buf, int reply_buf_len)
@@ -593,7 +595,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
        return 0;
 }
 
-int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length)
+static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length)
 {
        int ret;
        ret = av7110_fw_request(av7110, &tag, 0, buf, length);
@@ -617,7 +619,7 @@ int av7110_firmversion(struct av7110 *av7110)
 
        if (av7110_fw_query(av7110, tag, buf, 16)) {
                printk("dvb-ttpci: failed to boot firmware @ card %d\n",
-                      av7110->dvb_adapter->num);
+                      av7110->dvb_adapter.num);
                return -EIO;
        }
 
@@ -628,16 +630,16 @@ int av7110_firmversion(struct av7110 *av7110)
        av7110->avtype = (buf[8] << 16) + buf[9];
 
        printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
-              av7110->dvb_adapter->num, av7110->arm_fw,
+              av7110->dvb_adapter.num, av7110->arm_fw,
               av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
 
        /* print firmware capabilities */
        if (FW_CI_LL_SUPPORT(av7110->arm_app))
                printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
-                      av7110->dvb_adapter->num);
+                      av7110->dvb_adapter.num);
        else
                printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
-                      av7110->dvb_adapter->num);
+                      av7110->dvb_adapter.num);
 
        return 0;
 }
index bf901c6246821d85965f3eba25809fc7df5f046b..52061e17c6dd8607a2990b2b770a69ea8ba91855 100644 (file)
@@ -364,7 +364,6 @@ enum av7110_command_type {
 
 
 
-extern void av7110_reset_arm(struct av7110 *av7110);
 extern int av7110_bootarm(struct av7110 *av7110);
 extern int av7110_firmversion(struct av7110 *av7110);
 #define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
@@ -373,12 +372,8 @@ extern int av7110_firmversion(struct av7110 *av7110);
 
 extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags);
 extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...);
-extern int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length);
-extern int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length);
-extern int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len);
 extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
                             int request_buf_len, u16 *reply_buf, int reply_buf_len);
-extern int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* Buff, s16 length);
 
 
 /* DEBI (saa7146 data extension bus interface) access */
index 6d2256f1e3542511707c519ab7adf80f837a6bc9..665cdb8a3f718db433aa7c3c12c1b549429d3e53 100644 (file)
@@ -10,7 +10,7 @@
 
 #define UP_TIMEOUT (HZ/4)
 
-/* enable ir debugging by or'ing av7110_debug with 16 */
+/* enable ir debugging by or'ing debug with 16 */
 
 static int ir_initialized;
 static struct input_dev input_dev;
index eb84fb08d95cdd0926c20758e5ec7de800604e88..e65fc36e2ce8327884fa02f38d8bfc62bcfba487 100644 (file)
@@ -46,13 +46,13 @@ int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
 
        if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
                dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
-                      av7110->dvb_adapter->num, reg, val);
+                      av7110->dvb_adapter.num, reg, val);
                return -EIO;
        }
        return 0;
 }
 
-int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
+static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
 {
        u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
        u8 msg2[2];
@@ -63,7 +63,7 @@ int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
 
        if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
                dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
-                      av7110->dvb_adapter->num, reg);
+                      av7110->dvb_adapter.num, reg);
                return -EIO;
        }
        *val = (msg2[0] << 8) | msg2[1];
@@ -552,13 +552,13 @@ int av7110_init_analog_module(struct av7110 *av7110)
                return -ENODEV;
 
        printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
-               av7110->dvb_adapter->num);
+               av7110->dvb_adapter.num);
        av7110->adac_type = DVB_ADAC_MSP;
        msleep(100); // the probing above resets the msp...
        msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
        msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
        dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n",
-               av7110->dvb_adapter->num, version1, version2);
+               av7110->dvb_adapter.num, version1, version2);
        msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
        msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
        msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
@@ -596,7 +596,7 @@ int av7110_init_analog_module(struct av7110 *av7110)
                /* init the saa7113 */
                while (*i != 0xff) {
                        if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
-                               dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter->num);
+                               dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter.num);
                                break;
                        }
                        i += 2;
@@ -726,11 +726,11 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
 {
        struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
 
-       if (std->id == V4L2_STD_PAL) {
+       if (std->id & V4L2_STD_PAL) {
                av7110->vidmode = VIDEO_MODE_PAL;
                av7110_set_vidmode(av7110, av7110->vidmode);
        }
-       else if (std->id == V4L2_STD_NTSC) {
+       else if (std->id & V4L2_STD_NTSC) {
                av7110->vidmode = VIDEO_MODE_NTSC;
                av7110_set_vidmode(av7110, av7110->vidmode);
        }
index 14e963206b8901b7baa15d6668a090d36590605e..6e0f5d307c52de21c56ce2fa499272a85a6ed801 100644 (file)
@@ -59,8 +59,12 @@ struct budget_av {
        struct dvb_ca_en50221 ca;
 };
 
-static int enable_ci = 0;
-
+/* GPIO CI Connections:
+ * 0 - Vcc/Reset (Reset is controlled by capacitor)
+ * 1 - Attribute Memory
+ * 2 - Card Enable (Active Low)
+ * 3 - Card Detect
+ */
 
 /****************************************************************************
  * INITIALIZATION
@@ -188,22 +192,35 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
 {
        struct budget_av *budget_av = (struct budget_av *) ca->data;
        struct saa7146_dev *saa = budget_av->budget.dev;
-       int max = 20;
+       int timeout = 50; // 5 seconds (4.4.6 Ready)
 
        if (slot != 0)
                return -EINVAL;
 
        dprintk(1, "ciintf_slot_reset\n");
 
-       /* reset the card */
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
-       msleep(100);
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
+       saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
 
-       while (--max > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
+       msleep(2);
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
+       msleep(20); /* 20 ms Vcc settling time */
+
+       saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
+
+       /* This should have been based on pin 16 READY of the pcmcia port,
+        * but AFAICS it is not routed to the saa7146 */
+       while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
                msleep(100);
 
-       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
+       if (timeout <= 0)
+       {
+               printk(KERN_ERR "budget-av: cam reset failed (timeout).\n");
+               saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
+               saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
+               return -ETIMEDOUT;
+       }
+
        return 0;
 }
 
@@ -240,7 +257,6 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open
 {
        struct budget_av *budget_av = (struct budget_av *) ca->data;
        struct saa7146_dev *saa = budget_av->budget.dev;
-       int cam = 0;
 
        if (slot != 0)
                return -EINVAL;
@@ -248,15 +264,21 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open
        if (!budget_av->slot_status) {
                saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
                udelay(1);
-               cam = saa7146_read(saa, PSR) & MASK_06;
-               saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
-
-               if (cam)
+               if (saa7146_read(saa, PSR) & MASK_06)
+               {
+                       printk(KERN_INFO "budget-av: cam inserted\n");
                        budget_av->slot_status = 1;
+               }
+               saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
        } else if (!open) {
                saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
                if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT)
+               {
+                       printk(KERN_INFO "budget-av: cam ejected\n");
+                       saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
+                       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
                        budget_av->slot_status = 0;
+               }
        }
 
        if (budget_av->slot_status == 1)
@@ -272,17 +294,11 @@ static int ciintf_init(struct budget_av *budget_av)
 
        memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
 
-       /* setup GPIOs */
-       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
+       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
        saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
        saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
 
-       /* Reset the card */
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
-       msleep(50);
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
-       msleep(100);
-
        /* Enable DEBI pins */
        saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
 
@@ -297,13 +313,14 @@ static int ciintf_init(struct budget_av *budget_av)
        budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
        budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
        budget_av->ca.data = budget_av;
-       if ((result = dvb_ca_en50221_init(budget_av->budget.dvb_adapter,
+
+       if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
                                          &budget_av->ca, 0, 1)) != 0) {
-               printk("budget_av: CI interface detected, but initialisation failed.\n");
+               printk(KERN_ERR "budget-av: ci initialisation failed.\n");
                goto error;
        }
-       // success!
-       printk("ciintf_init: CI interface initialised\n");
+
+       printk(KERN_INFO "budget-av: ci interface initialised.\n");
        budget_av->budget.ci_present = 1;
        return 0;
 
@@ -361,8 +378,12 @@ static const u8 saa7113_tab[] = {
 static int saa7113_init(struct budget_av *budget_av)
 {
        struct budget *budget = &budget_av->budget;
+       struct saa7146_dev *saa = budget->dev;
        const u8 *data = saa7113_tab;
 
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
+       msleep(200);
+
        if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
                dprintk(1, "saa7113 not found on KNC card\n");
                return -ENODEV;
@@ -697,75 +718,90 @@ static u8 read_pwm(struct budget_av *budget_av)
        return pwm;
 }
 
+#define SUBID_DVBS_KNC1                0x0010
+#define SUBID_DVBS_KNC1_PLUS   0x0011
+#define SUBID_DVBS_TYPHOON     0x4f56
+#define SUBID_DVBS_CINERGY1200 0x1154
+
+#define SUBID_DVBC_KNC1                0x0020
+#define SUBID_DVBC_KNC1_PLUS   0x0021
+#define SUBID_DVBC_CINERGY1200 0x1156
+
+#define SUBID_DVBT_KNC1_PLUS   0x0031
+#define SUBID_DVBT_KNC1                0x0030
+#define SUBID_DVBT_CINERGY1200 0x1157
 
 static void frontend_init(struct budget_av *budget_av)
 {
-       switch (budget_av->budget.dev->pci->subsystem_device) {
-       case 0x4f56:            // Typhoon/KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059))
-               budget_av->budget.dvb_frontend =
-                       stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap);
-               if (budget_av->budget.dvb_frontend != NULL) {
+       struct saa7146_dev * saa = budget_av->budget.dev;
+       struct dvb_frontend * fe = NULL;
+
+       switch (saa->pci->subsystem_device) {
+               case SUBID_DVBS_KNC1_PLUS:
+               case SUBID_DVBC_KNC1_PLUS:
+               case SUBID_DVBT_KNC1_PLUS:
+                       // Enable / PowerON Frontend
+                       saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
                        break;
-               }
+       }
+
+       switch (saa->pci->subsystem_device) {
+
+       case SUBID_DVBS_KNC1:
+       case SUBID_DVBS_KNC1_PLUS:
+       case SUBID_DVBS_TYPHOON:
+               fe = stv0299_attach(&typhoon_config,
+                                   &budget_av->budget.i2c_adap);
                break;
 
-       case 0x0020:            // KNC1 DVB-C budget (tda10021/Philips CU1216(tua6034))
-               budget_av->budget.dvb_frontend =
-                       tda10021_attach(&philips_cu1216_config,
-                                       &budget_av->budget.i2c_adap, read_pwm(budget_av));
-               if (budget_av->budget.dvb_frontend != NULL) {
-                       break;
-               }
+       case SUBID_DVBS_CINERGY1200:
+               fe = stv0299_attach(&cinergy_1200s_config,
+                                   &budget_av->budget.i2c_adap);
                break;
 
-       case 0x0030:            // KNC1 DVB-T budget (tda10046/Philips TU1216(tda6651tt))
-               budget_av->budget.dvb_frontend =
-                       tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
-               if (budget_av->budget.dvb_frontend != NULL) {
-                       break;
-               }
+       case SUBID_DVBC_KNC1:
+       case SUBID_DVBC_KNC1_PLUS:
+               fe = tda10021_attach(&philips_cu1216_config,
+                                    &budget_av->budget.i2c_adap,
+                                    read_pwm(budget_av));
                break;
 
-       case 0x1154:            // TerraTec Cinergy 1200 DVB-S (stv0299/Philips SU1278(tsa5059))
-               budget_av->budget.dvb_frontend =
-                       stv0299_attach(&cinergy_1200s_config, &budget_av->budget.i2c_adap);
-               if (budget_av->budget.dvb_frontend != NULL) {
-                       break;
-               }
+       case SUBID_DVBT_KNC1:
+       case SUBID_DVBT_KNC1_PLUS:
+               fe = tda10046_attach(&philips_tu1216_config,
+                                    &budget_av->budget.i2c_adap);
                break;
 
-       case 0x1156:            // Terratec Cinergy 1200 DVB-C (tda10021/Philips CU1216(tua6034))
-               budget_av->budget.dvb_frontend =
-                       tda10021_attach(&philips_cu1216_config,
-                                       &budget_av->budget.i2c_adap, read_pwm(budget_av));
-               if (budget_av->budget.dvb_frontend) {
-                       break;
-               }
+       case SUBID_DVBC_CINERGY1200:
+               fe = tda10021_attach(&philips_cu1216_config,
+                                    &budget_av->budget.i2c_adap,
+                                    read_pwm(budget_av));
                break;
 
-       case 0x1157:            // Terratec Cinergy 1200 DVB-T (tda10046/Philips TU1216(tda6651tt))
-               budget_av->budget.dvb_frontend =
-                       tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
-               if (budget_av->budget.dvb_frontend) {
-                       break;
-               }
+       case SUBID_DVBT_CINERGY1200:
+               fe = tda10046_attach(&philips_tu1216_config,
+                                    &budget_av->budget.i2c_adap);
                break;
        }
 
-       if (budget_av->budget.dvb_frontend == NULL) {
-               printk("budget_av: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
-                      budget_av->budget.dev->pci->vendor,
-                      budget_av->budget.dev->pci->device,
-                      budget_av->budget.dev->pci->subsystem_vendor,
-                      budget_av->budget.dev->pci->subsystem_device);
-       } else {
-               if (dvb_register_frontend
-                   (budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) {
-                       printk("budget-av: Frontend registration failed!\n");
-                       if (budget_av->budget.dvb_frontend->ops->release)
-                               budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend);
-                       budget_av->budget.dvb_frontend = NULL;
-               }
+       if (fe == NULL) {
+               printk(KERN_ERR "budget-av: A frontend driver was not found "
+                               "for device %04x/%04x subsystem %04x/%04x\n",
+                      saa->pci->vendor,
+                      saa->pci->device,
+                      saa->pci->subsystem_vendor,
+                      saa->pci->subsystem_device);
+               return;
+       }
+
+       budget_av->budget.dvb_frontend = fe;
+
+       if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
+                                 budget_av->budget.dvb_frontend)) {
+               printk(KERN_ERR "budget-av: Frontend registration failed!\n");
+               if (budget_av->budget.dvb_frontend->ops->release)
+                       budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend);
+               budget_av->budget.dvb_frontend = NULL;
        }
 }
 
@@ -822,6 +858,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
 
        memset(budget_av, 0, sizeof(struct budget_av));
 
+       budget_av->has_saa7113 = 0;
        budget_av->budget.ci_present = 0;
 
        dev->ext_priv = budget_av;
@@ -836,10 +873,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
        saa7146_write(dev, DD1_INIT, 0x07000600);
        saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
 
-       saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
-       msleep(500);
-
-       if (0 == saa7113_init(budget_av)) {
+       if (saa7113_init(budget_av) == 0) {
                budget_av->has_saa7113 = 1;
 
                if (0 != saa7146_vv_init(dev, &vv_data)) {
@@ -860,31 +894,26 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
 
                saa7113_setinput(budget_av, 0);
        } else {
-               budget_av->has_saa7113 = 0;
-
-               saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
+               ciintf_init(budget_av);
        }
 
        /* fixme: find some sane values here... */
        saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
 
-       mac = budget_av->budget.dvb_adapter->proposed_mac;
+       mac = budget_av->budget.dvb_adapter.proposed_mac;
        if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
-               printk("KNC1-%d: Could not read MAC from KNC1 card\n",
-                      budget_av->budget.dvb_adapter->num);
+               printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n",
+                      budget_av->budget.dvb_adapter.num);
                memset(mac, 0, 6);
        } else {
-               printk("KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
-                      budget_av->budget.dvb_adapter->num,
+               printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+                      budget_av->budget.dvb_adapter.num,
                       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
        }
 
-       budget_av->budget.dvb_adapter->priv = budget_av;
+       budget_av->budget.dvb_adapter.priv = budget_av;
        frontend_init(budget_av);
 
-       if (enable_ci)
-               ciintf_init(budget_av);
-
        return 0;
 }
 
@@ -963,14 +992,21 @@ static struct saa7146_extension budget_extension;
 MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
+MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
+MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
+MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
 MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
 MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
 MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
 
 static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
+       MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
+       MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
        MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
+       MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
        MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
+       MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
        MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
        MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
        MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
@@ -1010,5 +1046,3 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
                   "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");
-module_param_named(enable_ci, enable_ci, int, 0644);
-MODULE_PARM_DESC(enable_ci, "Turn on/off CI module (default:off).");
index 521111be355822e78301f4ff3c54a55fb481848e..dce116111376e8c7322d5c35604e7882c3b67423 100644 (file)
@@ -395,7 +395,7 @@ static int ciintf_init(struct budget_ci *budget_ci)
        budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
        budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
        budget_ci->ca.data = budget_ci;
-       if ((result = dvb_ca_en50221_init(budget_ci->budget.dvb_adapter,
+       if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
                                          &budget_ci->ca,
                                          DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
                                          DVB_CA_EN50221_FLAG_IRQ_FR |
@@ -881,7 +881,7 @@ static void frontend_init(struct budget_ci *budget_ci)
                       budget_ci->budget.dev->pci->subsystem_device);
        } else {
                if (dvb_register_frontend
-                   (budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
+                   (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
                        printk("budget-ci: Frontend registration failed!\n");
                        if (budget_ci->budget.dvb_frontend->ops->release)
                                budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
@@ -916,7 +916,7 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
 
        ciintf_init(budget_ci);
 
-       budget_ci->budget.dvb_adapter->priv = budget_ci;
+       budget_ci->budget.dvb_adapter.priv = budget_ci;
        frontend_init(budget_ci);
 
        return 0;
index 93a9b40917e4302f172fde11ed012bcc72fd5dd3..0498a055a4cdfbe2d07df5b782e16c3644d35ebd 100644 (file)
@@ -298,7 +298,7 @@ static int budget_register(struct budget *budget)
        budget->dmxdev.demux = &dvbdemux->dmx;
        budget->dmxdev.capabilities = 0;
 
-       dvb_dmxdev_init(&budget->dmxdev, budget->dvb_adapter);
+       dvb_dmxdev_init(&budget->dmxdev, &budget->dvb_adapter);
 
        budget->hw_frontend.source = DMX_FRONTEND_0;
 
@@ -316,7 +316,7 @@ static int budget_register(struct budget *budget)
        if (ret < 0)
                return ret;
 
-       dvb_net_init(budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
+       dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
 
        return 0;
 }
@@ -385,11 +385,11 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
        strcpy(budget->i2c_adap.name, budget->card->name);
 
        if (i2c_add_adapter(&budget->i2c_adap) < 0) {
-               dvb_unregister_adapter(budget->dvb_adapter);
+               dvb_unregister_adapter(&budget->dvb_adapter);
                return -ENOMEM;
        }
 
-       ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter->proposed_mac);
+       ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);
 
        if (NULL ==
            (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, length, &budget->pt))) {
@@ -417,7 +417,7 @@ err:
 
        vfree(budget->grabbing);
 
-       dvb_unregister_adapter(budget->dvb_adapter);
+       dvb_unregister_adapter(&budget->dvb_adapter);
 
        return ret;
 }
@@ -432,7 +432,7 @@ int ttpci_budget_deinit(struct budget *budget)
 
        i2c_del_adapter(&budget->i2c_adap);
 
-       dvb_unregister_adapter(budget->dvb_adapter);
+       dvb_unregister_adapter(&budget->dvb_adapter);
 
        tasklet_kill(&budget->vpe_tasklet);
 
index 5d524a4f213f3bbfc495b7e7cdf97f2bf4b9d0a6..8142e26b47f5d4bb5e2f460245e48254a2b7f96c 100644 (file)
@@ -453,7 +453,7 @@ static void frontend_init(struct budget_patch* budget)
                       budget->dev->pci->subsystem_vendor,
                       budget->dev->pci->subsystem_device);
        } else {
-               if (dvb_register_frontend(budget->dvb_adapter, budget->dvb_frontend)) {
+               if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
                        printk("budget-av: Frontend registration failed!\n");
                        if (budget->dvb_frontend->ops->release)
                                budget->dvb_frontend->ops->release(budget->dvb_frontend);
@@ -702,7 +702,7 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte
 
         dev->ext_priv = budget;
 
-       budget->dvb_adapter->priv = budget;
+       budget->dvb_adapter.priv = budget;
        frontend_init(budget);
 
         return 0;
index 5e6a10f4ad95bb84f9181722622dc2da5be13bc2..083fd44e5f905e539abe8e83fe1f3d2f3ec98cdd 100644 (file)
@@ -468,7 +468,7 @@ static void frontend_init(struct budget *budget)
                       budget->dev->pci->subsystem_vendor,
                       budget->dev->pci->subsystem_device);
        } else {
-               if (dvb_register_frontend(budget->dvb_adapter, budget->dvb_frontend)) {
+               if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
                        printk("budget: Frontend registration failed!\n");
                        if (budget->dvb_frontend->ops->release)
                                budget->dvb_frontend->ops->release(budget->dvb_frontend);
@@ -497,7 +497,7 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_
                return err;
        }
 
-       budget->dvb_adapter->priv = budget;
+       budget->dvb_adapter.priv = budget;
        frontend_init(budget);
 
        return 0;
index 10bd41f0363b05c59567f9b2c48e5f95bffde669..c6ef496ba70a069874cbee3443462f8755cb6691 100644 (file)
@@ -64,7 +64,7 @@ struct budget {
 
        spinlock_t debilock;
 
-       struct dvb_adapter *dvb_adapter;
+       struct dvb_adapter dvb_adapter;
        struct dvb_frontend *dvb_frontend;
        void *priv;
 };
@@ -92,6 +92,9 @@ static struct saa7146_pci_extension_data x_var = { \
 #define BUDGET_KNC1S              8
 #define BUDGET_KNC1C              9
 #define BUDGET_KNC1T              10
+#define BUDGET_KNC1SP             11
+#define BUDGET_KNC1CP             12
+#define BUDGET_KNC1TP             13
 
 #define BUDGET_VIDEO_PORTA         0
 #define BUDGET_VIDEO_PORTB         1
index 4c046ece883a8978c49033934bd1c5b3a39fd1e6..afa0e7a0e5067a68180e595a0cd88b4e8c13b904 100644 (file)
@@ -84,7 +84,7 @@ struct ttusb {
        struct semaphore semi2c;
        struct semaphore semusb;
 
-       struct dvb_adapter *adapter;
+       struct dvb_adapter adapter;
        struct usb_device *dev;
 
        struct i2c_adapter i2c_adap;
@@ -1065,7 +1065,7 @@ static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
        return 0;
 }
 
-struct cx22700_config alps_tdmb7_config = {
+static struct cx22700_config alps_tdmb7_config = {
        .demod_address = 0x43,
        .pll_set = alps_tdmb7_pll_set,
 };
@@ -1412,7 +1412,7 @@ static void frontend_init(struct ttusb* ttusb)
                       le16_to_cpu(ttusb->dev->descriptor.idVendor),
                       le16_to_cpu(ttusb->dev->descriptor.idProduct));
        } else {
-               if (dvb_register_frontend(ttusb->adapter, ttusb->fe)) {
+               if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
                        printk("dvb-ttusb-budget: Frontend registration failed!\n");
                        if (ttusb->fe->ops->release)
                                ttusb->fe->ops->release(ttusb->fe);
@@ -1462,7 +1462,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        up(&ttusb->semi2c);
 
        dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE);
-       ttusb->adapter->priv = ttusb;
+       ttusb->adapter.priv = ttusb;
 
        /* i2c */
        memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
@@ -1481,7 +1481,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
 
        result = i2c_add_adapter(&ttusb->i2c_adap);
        if (result) {
-               dvb_unregister_adapter (ttusb->adapter);
+               dvb_unregister_adapter (&ttusb->adapter);
                return result;
        }
 
@@ -1503,7 +1503,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
                printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
                i2c_del_adapter(&ttusb->i2c_adap);
-               dvb_unregister_adapter (ttusb->adapter);
+               dvb_unregister_adapter (&ttusb->adapter);
                return -ENODEV;
        }
 //FIXME dmxdev (nur WAS?)
@@ -1511,21 +1511,21 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
        ttusb->dmxdev.capabilities = 0;
 
-       if ((result = dvb_dmxdev_init(&ttusb->dmxdev, ttusb->adapter)) < 0) {
+       if ((result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter)) < 0) {
                printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
                       result);
                dvb_dmx_release(&ttusb->dvb_demux);
                i2c_del_adapter(&ttusb->i2c_adap);
-               dvb_unregister_adapter (ttusb->adapter);
+               dvb_unregister_adapter (&ttusb->adapter);
                return -ENODEV;
        }
 
-       if (dvb_net_init(ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
+       if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
                printk("ttusb_dvb: dvb_net_init failed!\n");
                dvb_dmxdev_release(&ttusb->dmxdev);
                dvb_dmx_release(&ttusb->dvb_demux);
                i2c_del_adapter(&ttusb->i2c_adap);
-               dvb_unregister_adapter (ttusb->adapter);
+               dvb_unregister_adapter (&ttusb->adapter);
                return -ENODEV;
        }
 
@@ -1559,7 +1559,7 @@ static void ttusb_disconnect(struct usb_interface *intf)
        dvb_dmx_release(&ttusb->dvb_demux);
        if (ttusb->fe != NULL) dvb_unregister_frontend(ttusb->fe);
        i2c_del_adapter(&ttusb->i2c_adap);
-       dvb_unregister_adapter(ttusb->adapter);
+       dvb_unregister_adapter(&ttusb->adapter);
 
        ttusb_free_iso_urbs(ttusb);
 
index 64e771bd890782f51fb836ec29f902d49f651597..505bdaff5a7eea16ff148ba87d9f74d7ea93043b 100644 (file)
@@ -98,7 +98,7 @@ struct ttusb_dec {
        int                             can_playback;
 
        /* DVB bits */
-       struct dvb_adapter              *adapter;
+       struct dvb_adapter              adapter;
        struct dmxdev                   dmxdev;
        struct dvb_demux                demux;
        struct dmx_frontend             frontend;
@@ -1435,7 +1435,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
                printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
                       result);
 
-               dvb_unregister_adapter(dec->adapter);
+               dvb_unregister_adapter(&dec->adapter);
 
                return result;
        }
@@ -1444,12 +1444,12 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
        dec->dmxdev.demux = &dec->demux.dmx;
        dec->dmxdev.capabilities = 0;
 
-       if ((result = dvb_dmxdev_init(&dec->dmxdev, dec->adapter)) < 0) {
+       if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) {
                printk("%s: dvb_dmxdev_init failed: error %d\n",
                       __FUNCTION__, result);
 
                dvb_dmx_release(&dec->demux);
-               dvb_unregister_adapter(dec->adapter);
+               dvb_unregister_adapter(&dec->adapter);
 
                return result;
        }
@@ -1463,7 +1463,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
 
                dvb_dmxdev_release(&dec->dmxdev);
                dvb_dmx_release(&dec->demux);
-               dvb_unregister_adapter(dec->adapter);
+               dvb_unregister_adapter(&dec->adapter);
 
                return result;
        }
@@ -1476,12 +1476,12 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
                dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
                dvb_dmxdev_release(&dec->dmxdev);
                dvb_dmx_release(&dec->demux);
-               dvb_unregister_adapter(dec->adapter);
+               dvb_unregister_adapter(&dec->adapter);
 
                return result;
        }
 
-       dvb_net_init(dec->adapter, &dec->dvb_net, &dec->demux.dmx);
+       dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx);
 
        return 0;
 }
@@ -1496,7 +1496,7 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
        dvb_dmxdev_release(&dec->dmxdev);
        dvb_dmx_release(&dec->demux);
        if (dec->fe) dvb_unregister_frontend(dec->fe);
-       dvb_unregister_adapter(dec->adapter);
+       dvb_unregister_adapter(&dec->adapter);
 }
 
 static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
@@ -1565,15 +1565,15 @@ static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
        }
 }
 
-int fe_send_command(struct dvb_frontend* fe, const u8 command,
-                   int param_length, const u8 params[],
-                   int *result_length, u8 cmd_result[])
+static int fe_send_command(struct dvb_frontend* fe, const u8 command,
+                          int param_length, const u8 params[],
+                          int *result_length, u8 cmd_result[])
 {
        struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv;
        return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
 }
 
-struct ttusbdecfe_config fe_config = {
+static struct ttusbdecfe_config fe_config = {
        .send_command = fe_send_command
 };
 
@@ -1620,7 +1620,7 @@ static int ttusb_dec_probe(struct usb_interface *intf,
        }
        ttusb_dec_init_dvb(dec);
 
-       dec->adapter->priv = dec;
+       dec->adapter.priv = dec;
        switch (le16_to_cpu(id->idProduct)) {
        case 0x1006:
                dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
@@ -1637,7 +1637,7 @@ static int ttusb_dec_probe(struct usb_interface *intf,
                       le16_to_cpu(dec->udev->descriptor.idVendor),
                       le16_to_cpu(dec->udev->descriptor.idProduct));
        } else {
-               if (dvb_register_frontend(dec->adapter, dec->fe)) {
+               if (dvb_register_frontend(&dec->adapter, dec->fe)) {
                        printk("budget-ci: Frontend registration failed!\n");
                        if (dec->fe->ops->release)
                                dec->fe->ops->release(dec->fe);
index d3dd4228b72d46c72a2ee7bbe7c4e6a2dfd03ba0..6c05fddb69ab484841abefdf007e52ebc4d17bf5 100644 (file)
@@ -240,6 +240,7 @@ config VIDEO_SAA7134
        select VIDEO_BUF
        select VIDEO_IR
        select VIDEO_TUNER
+       select CRC32
        ---help---
          This is a video4linux driver for Philips SAA7130/7134 based
          TV cards.
index 85224b90e394643ef40e18deaa146867ae47105f..6334122704aecead4a200695d649c2f544522110 100644 (file)
@@ -1946,7 +1946,6 @@ struct tvcard bttv_tvcards[] = {
         .no_tda9875     = 1,
         .no_tda7432     = 1,
         .tuner_type     = TUNER_ABSENT,
-        .no_video       = 1,
        .pll            = PLL_28,
 },{
        .name           = "Teppro TEV-560/InterVision IV-560",
index e42f1ec13f3e66900d1e08546d1e4f7b38d591f3..c2368bc832edc248978cb646218184da59d0b4bc 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
 #include <asm/io.h>
 
 #include "bttvp.h"
@@ -130,17 +131,14 @@ static u32 functionality(struct i2c_adapter *adap)
 static int
 bttv_i2c_wait_done(struct bttv *btv)
 {
-       DECLARE_WAITQUEUE(wait, current);
        int rc = 0;
 
-       add_wait_queue(&btv->i2c_queue, &wait);
-       if (0 == btv->i2c_done)
-               msleep_interruptible(20);
-       remove_wait_queue(&btv->i2c_queue, &wait);
+       /* timeout */
+       if (wait_event_interruptible_timeout(btv->i2c_queue,
+               btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS)
+
+       rc = -EIO;
 
-       if (0 == btv->i2c_done)
-               /* timeout */
-               rc = -EIO;
        if (btv->i2c_done & BT848_INT_RACK)
                rc = 1;
        btv->i2c_done = 0;
@@ -365,6 +363,9 @@ int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
 /* read EEPROM content */
 void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
 {
+       memset(eedata, 0, 256);
+       if (0 != btv->i2c_rc)
+               return;
        btv->i2c_client.addr = addr >> 1;
        tveeprom_read(&btv->i2c_client, eedata, 256);
 }
index cee13584c9cfa123612e3dfa6ade71a8fa3d09b3..1db0226829806af405a786df5d0ae5e20f4beee7 100644 (file)
@@ -32,9 +32,32 @@ MODULE_LICENSE("GPL");
 static struct i2c_driver driver;
 static struct i2c_client client_template;
 
+enum saa6752hs_videoformat {
+       SAA6752HS_VF_D1 = 0,    /* standard D1 video format: 720x576 */
+       SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */
+       SAA6752HS_VF_1_2_D1 = 2,/* 1/2D1 video format: 352x576 */
+       SAA6752HS_VF_SIF = 3,   /* SIF video format: 352x288 */
+       SAA6752HS_VF_UNKNOWN,
+};
+
+static const struct v4l2_format v4l2_format_table[] =
+{
+       [SAA6752HS_VF_D1] = {
+               .fmt = { .pix = { .width = 720, .height = 576 }, }, },
+       [SAA6752HS_VF_2_3_D1] = {
+               .fmt = { .pix = { .width = 480, .height = 576 }, }, },
+       [SAA6752HS_VF_1_2_D1] = {
+               .fmt = { .pix = { .width = 352, .height = 576 }, }, },
+       [SAA6752HS_VF_SIF] = {
+               .fmt = { .pix = { .width = 352, .height = 288 }, }, },
+       [SAA6752HS_VF_UNKNOWN] = {
+               .fmt = { .pix = { .width = 0, .height = 0 }, }, },
+};
+
 struct saa6752hs_state {
        struct i2c_client             client;
        struct v4l2_mpeg_compression  params;
+       enum saa6752hs_videoformat    video_format;
 };
 
 enum saa6752hs_command {
@@ -256,6 +279,51 @@ static int saa6752hs_set_bitrate(struct i2c_client* client,
        return 0;
 }
 
+static void saa6752hs_set_subsampling(struct i2c_client* client,
+                                     struct v4l2_format* f)
+{
+       struct saa6752hs_state *h = i2c_get_clientdata(client);
+       int dist_352, dist_480, dist_720;
+
+       /*
+         FIXME: translate and round width/height into EMPRESS
+         subsample type:
+
+         type   |   PAL   |  NTSC
+         ---------------------------
+         SIF    | 352x288 | 352x240
+         1/2 D1 | 352x576 | 352x480
+         2/3 D1 | 480x576 | 480x480
+         D1     | 720x576 | 720x480
+       */
+
+       dist_352 = abs(f->fmt.pix.width - 352);
+       dist_480 = abs(f->fmt.pix.width - 480);
+       dist_720 = abs(f->fmt.pix.width - 720);
+       if (dist_720 < dist_480) {
+               f->fmt.pix.width = 720;
+               f->fmt.pix.height = 576;
+               h->video_format = SAA6752HS_VF_D1;
+       }
+       else if (dist_480 < dist_352) {
+               f->fmt.pix.width = 480;
+               f->fmt.pix.height = 576;
+               h->video_format = SAA6752HS_VF_2_3_D1;
+       }
+       else {
+               f->fmt.pix.width = 352;
+               if (abs(f->fmt.pix.height - 576) <
+                   abs(f->fmt.pix.height - 288)) {
+                       f->fmt.pix.height = 576;
+                       h->video_format = SAA6752HS_VF_1_2_D1;
+               }
+               else {
+                       f->fmt.pix.height = 288;
+                       h->video_format = SAA6752HS_VF_SIF;
+               }
+       }
+}
+
 
 static void saa6752hs_set_params(struct i2c_client* client,
                                 struct v4l2_mpeg_compression* params)
@@ -315,7 +383,7 @@ static int saa6752hs_init(struct i2c_client* client)
 
        // Set video format - must be done first as it resets other settings
        buf[0] = 0x41;
-       buf[1] = 0 /* MPEG_VIDEO_FORMAT_D1 */;
+       buf[1] = h->video_format;
        i2c_master_send(client, buf, 2);
 
         // set bitrate
@@ -494,6 +562,25 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
        case VIDIOC_G_MPEGCOMP:
                *params = h->params;
                break;
+       case VIDIOC_G_FMT:
+       {
+           struct v4l2_format *f = arg;
+
+          if (h->video_format == SAA6752HS_VF_UNKNOWN)
+                  h->video_format = SAA6752HS_VF_D1;
+          f->fmt.pix.width =
+                  v4l2_format_table[h->video_format].fmt.pix.width;
+          f->fmt.pix.height =
+                  v4l2_format_table[h->video_format].fmt.pix.height;
+          break ;
+       }
+       case VIDIOC_S_FMT:
+       {
+               struct v4l2_format *f = arg;
+
+               saa6752hs_set_subsampling(client, f);
+               break;
+       }
        default:
                /* nothing */
                break;
index 2021e099e35ace85f2cda86c97ab02bbb3642271..fa1357336907cd6df71614e39f61d133b8428607 100644 (file)
@@ -233,10 +233,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
                memset(f,0,sizeof(*f));
                f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
-               /* FIXME: translate subsampling type EMPRESS into
-                *        width/height: */
-               f->fmt.pix.width        = 720; /* D1 */
-               f->fmt.pix.height       = 576;
+               saa7134_i2c_call_clients(dev, cmd, arg);
                f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
                f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
                return 0;
@@ -249,20 +246,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
                if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                    return -EINVAL;
 
-               /*
-                 FIXME: translate and round width/height into EMPRESS
-                 subsample type:
-
-                         type  |   PAL   |  NTSC
-                       ---------------------------
-                         SIF   | 352x288 | 352x240
-                        1/2 D1 | 352x576 | 352x480
-                        2/3 D1 | 480x576 | 480x480
-                         D1    | 720x576 | 720x480
-               */
-
-               f->fmt.pix.width        = 720; /* D1 */
-               f->fmt.pix.height       = 576;
+               saa7134_i2c_call_clients(dev, cmd, arg);
                f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
                f->fmt.pix.sizeimage    = TS_PACKET_SIZE* dev->ts.nr_packets;
                return 0;
index 881a0539fc1704c04be38a455a87918d1315dd84..6212388edb75b0035b19761eb00bfec503b0a4ce 100644 (file)
@@ -357,8 +357,16 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                    V4L2_TUNER_RADIO != t->mode)
                        set_tv_freq(client,400*16);
                t->mode  = f->type;
-               t->freq  = f->frequency;
-               set_freq(client,t->freq);
+               set_freq(client,f->frequency);
+               break;
+       }
+       case VIDIOC_G_FREQUENCY:
+       {
+               struct v4l2_frequency *f = arg;
+
+               SWITCH_V4L2;
+               f->type = t->mode;
+               f->frequency = t->freq;
                break;
        }
        case VIDIOC_G_TUNER:
@@ -368,6 +376,8 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                SWITCH_V4L2;
                if (V4L2_TUNER_RADIO == t->mode  &&  t->has_signal)
                        tuner->signal = t->has_signal(client);
+               tuner->rangelow = tv_range[0] * 16;
+               tuner->rangehigh = tv_range[1] * 16;
                break;
        }
        default:
index 31cc4ed9b74730673a550ad2d62a45a9caf0573e..5f870075b55e595df3e8384d0812279092ed3259 100644 (file)
@@ -149,10 +149,10 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
                       dvb->name, result);
                goto fail_adapter;
        }
-       dvb->adapter->priv = adapter_priv;
+       dvb->adapter.priv = adapter_priv;
 
        /* register frontend */
-       result = dvb_register_frontend(dvb->adapter, dvb->frontend);
+       result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
        if (result < 0) {
                printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
                       dvb->name, result);
@@ -178,7 +178,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
        dvb->dmxdev.filternum    = 256;
        dvb->dmxdev.demux        = &dvb->demux.dmx;
        dvb->dmxdev.capabilities = 0;
-       result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter);
+       result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
        if (result < 0) {
                printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
                       dvb->name, result);
@@ -209,7 +209,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
        }
 
        /* register network adapter */
-       dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx);
+       dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
        return 0;
 
 fail_fe_conn:
@@ -223,7 +223,7 @@ fail_dmxdev:
 fail_dmx:
        dvb_unregister_frontend(dvb->frontend);
 fail_frontend:
-       dvb_unregister_adapter(dvb->adapter);
+       dvb_unregister_adapter(&dvb->adapter);
 fail_adapter:
        return result;
 }
@@ -236,7 +236,7 @@ void videobuf_dvb_unregister(struct videobuf_dvb *dvb)
        dvb_dmxdev_release(&dvb->dmxdev);
        dvb_dmx_release(&dvb->demux);
        dvb_unregister_frontend(dvb->frontend);
-       dvb_unregister_adapter(dvb->adapter);
+       dvb_unregister_adapter(&dvb->adapter);
 }
 
 EXPORT_SYMBOL(videobuf_dvb_register);
index 7b74c87b569e77869cbbe72a8c574c1a258059f7..4830b775906104d718b882c720a3ea1d306b96f3 100644 (file)
@@ -573,6 +573,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
 static void i2o_block_event(struct i2o_event *evt)
 {
        osm_info("block-osm: event received\n");
+       kfree(evt);
 };
 
 /*
index 72f2b466b8167a0b35f35d2a1e00897d3c029a21..4991bbd054f31fcbc86b4b0871dec7777d00154c 100644 (file)
@@ -51,7 +51,7 @@ config MMC_PXA
 
 config MMC_WBSD
        tristate "Winbond W83L51xD SD/MMC Card Interface support"
-       depends on MMC && ISA
+       depends on MMC && ISA_DMA_API
        help
          This selects the Winbond(R) W83L51xD Secure digital and
           Multimedia card Interface.
index b5b4a7b1190349236fd42f073eb522da471177d1..d4eee99c2bf65ffe86798deb86cdd5ef0a2e81da 100644 (file)
@@ -383,7 +383,10 @@ static int mmc_blk_probe(struct mmc_card *card)
        struct mmc_blk_data *md;
        int err;
 
-       if (card->csd.cmdclass & ~0x1ff)
+       /*
+        * Check that the card supports the command class(es) we need.
+        */
+       if (!(card->csd.cmdclass & CCC_BLOCK_READ))
                return -ENODEV;
 
        if (card->csd.read_blkbits < 9) {
index 39747526c719ff1f93241e08206e7fd61884b673..b7fbd30b49a0de18d1b05cf30bcfe62c0f64efac 100644 (file)
@@ -28,7 +28,9 @@
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/pnp.h>
 #include <linux/highmem.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
@@ -40,7 +42,7 @@
 #include "wbsd.h"
 
 #define DRIVER_NAME "wbsd"
-#define DRIVER_VERSION "1.1"
+#define DRIVER_VERSION "1.2"
 
 #ifdef CONFIG_MMC_DEBUG
 #define DBG(x...) \
 #define DBGF(x...)     do { } while (0)
 #endif
 
-static unsigned int io = 0x248;
-static unsigned int irq = 6;
-static int dma = 2;
-
 #ifdef CONFIG_MMC_DEBUG
 void DBG_REG(int reg, u8 value)
 {
@@ -78,29 +76,62 @@ void DBG_REG(int reg, u8 value)
 #define DBG_REG(r, v) do {}  while (0)
 #endif
 
+/*
+ * Device resources
+ */
+
+#ifdef CONFIG_PNP
+
+static const struct pnp_device_id pnp_dev_table[] = {
+       { "WEC0517", 0 },
+       { "WEC0518", 0 },
+       { "", 0 },
+};
+
+MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
+
+#endif /* CONFIG_PNP */
+
+#ifdef CONFIG_PNP
+static unsigned int nopnp = 0;
+#else
+static const unsigned int nopnp = 1;
+#endif
+static unsigned int io = 0x248;
+static unsigned int irq = 6;
+static int dma = 2;
+
 /*
  * Basic functions
  */
 
 static inline void wbsd_unlock_config(struct wbsd_host* host)
 {
+       BUG_ON(host->config == 0);
+       
        outb(host->unlock_code, host->config);
        outb(host->unlock_code, host->config);
 }
 
 static inline void wbsd_lock_config(struct wbsd_host* host)
 {
+       BUG_ON(host->config == 0);
+       
        outb(LOCK_CODE, host->config);
 }
 
 static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
 {
+       BUG_ON(host->config == 0);
+       
        outb(reg, host->config);
        outb(value, host->config + 1);
 }
 
 static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg)
 {
+       BUG_ON(host->config == 0);
+       
        outb(reg, host->config);
        return inb(host->config + 1);
 }
@@ -132,6 +163,13 @@ static void wbsd_init_device(struct wbsd_host* host)
        setup |= WBSD_FIFO_RESET | WBSD_SOFT_RESET;
        wbsd_write_index(host, WBSD_IDX_SETUP, setup);
        
+       /*
+        * Set DAT3 to input
+        */
+       setup &= ~WBSD_DAT3_H;
+       wbsd_write_index(host, WBSD_IDX_SETUP, setup);
+       host->flags &= ~WBSD_FIGNORE_DETECT;
+       
        /*
         * Read back default clock.
         */
@@ -147,6 +185,14 @@ static void wbsd_init_device(struct wbsd_host* host)
         */
        wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F);
        
+       /*
+        * Test for card presence
+        */
+       if (inb(host->base + WBSD_CSR) & WBSD_CARDPRESENT)
+               host->flags |= WBSD_FCARD_PRESENT;
+       else
+               host->flags &= ~WBSD_FCARD_PRESENT;
+       
        /*
         * Enable interesting interrupts.
         */
@@ -407,8 +453,6 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
        }
 }
 
-static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs);
-
 static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
 {
        int i;
@@ -646,6 +690,13 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
        }
        
        wbsd_kunmap_sg(host);
+       
+       /*
+        * The controller stops sending interrupts for
+        * 'FIFO empty' under certain conditions. So we
+        * need to be a bit more pro-active.
+        */
+       tasklet_schedule(&host->fifo_tasklet);
 }
 
 static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
@@ -850,9 +901,11 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
        wbsd_request_end(host, host->mrq);
 }
 
-/*
- * MMC Callbacks
- */
+/*****************************************************************************\
+ *                                                                           *
+ * MMC layer callbacks                                                       *
+ *                                                                           *
+\*****************************************************************************/
 
 static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
 {
@@ -874,7 +927,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
         * If there is no card in the slot then
         * timeout immediatly.
         */
-       if (!(inb(host->base + WBSD_CSR) & WBSD_CARDPRESENT))
+       if (!(host->flags & WBSD_FCARD_PRESENT))
        {
                cmd->error = MMC_ERR_TIMEOUT;
                goto done;
@@ -953,33 +1006,50 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
                host->clk = clk;
        }
 
+       /*
+        * Power up card.
+        */
        if (ios->power_mode != MMC_POWER_OFF)
        {
-               /*
-                * Power up card.
-                */
                pwr = inb(host->base + WBSD_CSR);
                pwr &= ~WBSD_POWER_N;
                outb(pwr, host->base + WBSD_CSR);
-
-               /*
-                * This behaviour is stolen from the
-                * Windows driver. Don't know why, but
-                * it is needed.
-                */
-               setup = wbsd_read_index(host, WBSD_IDX_SETUP);
-               if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
-                       setup |= WBSD_DAT3_H;
-               else
-                       setup &= ~WBSD_DAT3_H;
-               wbsd_write_index(host, WBSD_IDX_SETUP, setup);
-
-               mdelay(1);
        }
 
+       /*
+        * MMC cards need to have pin 1 high during init.
+        * Init time corresponds rather nicely with the bus mode.
+        * It wreaks havoc with the card detection though so
+        * that needs to be disabed.
+        */
+       setup = wbsd_read_index(host, WBSD_IDX_SETUP);
+       if ((ios->power_mode == MMC_POWER_ON) &&
+               (ios->bus_mode == MMC_BUSMODE_OPENDRAIN))
+       {
+               setup |= WBSD_DAT3_H;
+               host->flags |= WBSD_FIGNORE_DETECT;
+       }
+       else
+       {
+               setup &= ~WBSD_DAT3_H;
+               host->flags &= ~WBSD_FIGNORE_DETECT;
+       }
+       wbsd_write_index(host, WBSD_IDX_SETUP, setup);
+       
        spin_unlock_bh(&host->lock);
 }
 
+static struct mmc_host_ops wbsd_ops = {
+       .request        = wbsd_request,
+       .set_ios        = wbsd_set_ios,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Interrupt handling                                                        *
+ *                                                                           *
+\*****************************************************************************/
+
 /*
  * Tasklets
  */
@@ -1005,17 +1075,33 @@ static void wbsd_tasklet_card(unsigned long param)
 {
        struct wbsd_host* host = (struct wbsd_host*)param;
        u8 csr;
+       int change = 0;
        
        spin_lock(&host->lock);
        
+       if (host->flags & WBSD_FIGNORE_DETECT)
+       {
+               spin_unlock(&host->lock);
+               return;
+       }
+       
        csr = inb(host->base + WBSD_CSR);
        WARN_ON(csr == 0xff);
        
        if (csr & WBSD_CARDPRESENT)
-               DBG("Card inserted\n");
-       else
+       {
+               if (!(host->flags & WBSD_FCARD_PRESENT))
+               {
+                       DBG("Card inserted\n");
+                       host->flags |= WBSD_FCARD_PRESENT;
+                       change = 1;
+               }
+       }
+       else if (host->flags & WBSD_FCARD_PRESENT)
        {
                DBG("Card removed\n");
+               host->flags &= ~WBSD_FCARD_PRESENT;
+               change = 1;
                
                if (host->mrq)
                {
@@ -1033,7 +1119,8 @@ static void wbsd_tasklet_card(unsigned long param)
         */
        spin_unlock(&host->lock);
 
-       mmc_detect_change(host->mmc);
+       if (change)
+               mmc_detect_change(host->mmc);
 }
 
 static void wbsd_tasklet_fifo(unsigned long param)
@@ -1200,11 +1287,85 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
+/*****************************************************************************\
+ *                                                                           *
+ * Device initialisation and shutdown                                        *
+ *                                                                           *
+\*****************************************************************************/
+
 /*
- * Support functions for probe
+ * Allocate/free MMC structure.
  */
 
-static int wbsd_scan(struct wbsd_host* host)
+static int __devinit wbsd_alloc_mmc(struct device* dev)
+{
+       struct mmc_host* mmc;
+       struct wbsd_host* host;
+       
+       /*
+        * Allocate MMC structure.
+        */
+       mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev);
+       if (!mmc)
+               return -ENOMEM;
+       
+       host = mmc_priv(mmc);
+       host->mmc = mmc;
+
+       host->dma = -1;
+
+       /*
+        * Set host parameters.
+        */
+       mmc->ops = &wbsd_ops;
+       mmc->f_min = 375000;
+       mmc->f_max = 24000000;
+       mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
+       
+       spin_lock_init(&host->lock);
+       
+       /*
+        * Maximum number of segments. Worst case is one sector per segment
+        * so this will be 64kB/512.
+        */
+       mmc->max_hw_segs = 128;
+       mmc->max_phys_segs = 128;
+       
+       /*
+        * Maximum number of sectors in one transfer. Also limited by 64kB
+        * buffer.
+        */
+       mmc->max_sectors = 128;
+       
+       /*
+        * Maximum segment size. Could be one segment with the maximum number
+        * of segments.
+        */
+       mmc->max_seg_size = mmc->max_sectors * 512;
+       
+       dev_set_drvdata(dev, mmc);
+       
+       return 0;
+}
+
+static void __devexit wbsd_free_mmc(struct device* dev)
+{
+       struct mmc_host* mmc;
+       
+       mmc = dev_get_drvdata(dev);
+       if (!mmc)
+               return;
+       
+       mmc_free_host(mmc);
+       
+       dev_set_drvdata(dev, NULL);
+}
+
+/*
+ * Scan for known chip id:s
+ */
+
+static int __devinit wbsd_scan(struct wbsd_host* host)
 {
        int i, j, k;
        int id;
@@ -1258,12 +1419,16 @@ static int wbsd_scan(struct wbsd_host* host)
        return -ENODEV;
 }
 
-static int wbsd_request_regions(struct wbsd_host* host)
+/*
+ * Allocate/free io port ranges
+ */
+
+static int __devinit wbsd_request_region(struct wbsd_host* host, int base)
 {
        if (io & 0x7)
                return -EINVAL;
        
-       if (!request_region(io, 8, DRIVER_NAME))
+       if (!request_region(base, 8, DRIVER_NAME))
                return -EIO;
        
        host->base = io;
@@ -1271,19 +1436,25 @@ static int wbsd_request_regions(struct wbsd_host* host)
        return 0;
 }
 
-static void wbsd_release_regions(struct wbsd_host* host)
+static void __devexit wbsd_release_regions(struct wbsd_host* host)
 {
        if (host->base)
                release_region(host->base, 8);
+       
+       host->base = 0;
 
        if (host->config)
                release_region(host->config, 2);
+       
+       host->config = 0;
 }
 
-static void wbsd_init_dma(struct wbsd_host* host)
+/*
+ * Allocate/free DMA port and buffer
+ */
+
+static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
 {
-       host->dma = -1;
-       
        if (dma < 0)
                return;
        
@@ -1294,7 +1465,7 @@ static void wbsd_init_dma(struct wbsd_host* host)
         * We need to allocate a special buffer in
         * order for ISA to be able to DMA to it.
         */
-       host->dma_buffer = kmalloc(65536,
+       host->dma_buffer = kmalloc(WBSD_DMA_SIZE,
                GFP_NOIO | GFP_DMA | __GFP_REPEAT | __GFP_NOWARN);
        if (!host->dma_buffer)
                goto free;
@@ -1302,7 +1473,8 @@ static void wbsd_init_dma(struct wbsd_host* host)
        /*
         * Translate the address to a physical address.
         */
-       host->dma_addr = isa_virt_to_bus(host->dma_buffer);
+       host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer,
+               WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
                        
        /*
         * ISA DMA must be aligned on a 64k basis.
@@ -1325,6 +1497,10 @@ kfree:
         */
        BUG_ON(1);
        
+       dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
+               DMA_BIDIRECTIONAL);
+       host->dma_addr = (dma_addr_t)NULL;
+       
        kfree(host->dma_buffer);
        host->dma_buffer = NULL;
 
@@ -1336,60 +1512,122 @@ err:
                "Falling back on FIFO.\n", dma);
 }
 
-static struct mmc_host_ops wbsd_ops = {
-       .request        = wbsd_request,
-       .set_ios        = wbsd_set_ios,
-};
+static void __devexit wbsd_release_dma(struct wbsd_host* host)
+{
+       if (host->dma_addr)
+               dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
+                       DMA_BIDIRECTIONAL);
+       if (host->dma_buffer)
+               kfree(host->dma_buffer);
+       if (host->dma >= 0)
+               free_dma(host->dma);
+       
+       host->dma = -1;
+       host->dma_buffer = NULL;
+       host->dma_addr = (dma_addr_t)NULL;
+}
 
 /*
- * Device probe
+ * Allocate/free IRQ.
  */
 
-static int wbsd_probe(struct device* dev)
+static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
 {
-       struct wbsd_host* host = NULL;
-       struct mmc_host* mmc = NULL;
        int ret;
        
        /*
-        * Allocate MMC structure.
+        * Allocate interrupt.
         */
-       mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev);
-       if (!mmc)
-               return -ENOMEM;
-       
-       host = mmc_priv(mmc);
-       host->mmc = mmc;
+
+       ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host);
+       if (ret)
+               return ret;
        
+       host->irq = irq;
+
        /*
-        * Scan for hardware.
+        * Set up tasklets.
         */
-       ret = wbsd_scan(host);
-       if (ret)
-               goto freemmc;
+       tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host);
+       tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host);
+       tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host);
+       tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host);
+       tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host);
+       tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host);
+       
+       return 0;
+}
 
-       /*
-        * Reset the chip.
-        */     
-       wbsd_write_config(host, WBSD_CONF_SWRST, 1);
-       wbsd_write_config(host, WBSD_CONF_SWRST, 0);
+static void __devexit wbsd_release_irq(struct wbsd_host* host)
+{
+       if (!host->irq)
+               return;
 
+       free_irq(host->irq, host);
+       
+       host->irq = 0;
+               
+       tasklet_kill(&host->card_tasklet);
+       tasklet_kill(&host->fifo_tasklet);
+       tasklet_kill(&host->crc_tasklet);
+       tasklet_kill(&host->timeout_tasklet);
+       tasklet_kill(&host->finish_tasklet);
+       tasklet_kill(&host->block_tasklet);
+}
+
+/*
+ * Allocate all resources for the host.
+ */
+
+static int __devinit wbsd_request_resources(struct wbsd_host* host,
+       int base, int irq, int dma)
+{
+       int ret;
+       
        /*
         * Allocate I/O ports.
         */
-       ret = wbsd_request_regions(host);
+       ret = wbsd_request_region(host, base);
        if (ret)
-               goto release;
+               return ret;
 
        /*
-        * Set host parameters.
+        * Allocate interrupt.
         */
-       mmc->ops = &wbsd_ops;
-       mmc->f_min = 375000;
-       mmc->f_max = 24000000;
-       mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
+       ret = wbsd_request_irq(host, irq);
+       if (ret)
+               return ret;
+
+       /*
+        * Allocate DMA.
+        */
+       wbsd_request_dma(host, dma);
        
-       spin_lock_init(&host->lock);
+       return 0;
+}
+
+/*
+ * Release all resources for the host.
+ */
+
+static void __devexit wbsd_release_resources(struct wbsd_host* host)
+{
+       wbsd_release_dma(host);
+       wbsd_release_irq(host);
+       wbsd_release_regions(host);
+}
+
+/*
+ * Configure the resources the chip should use.
+ */
+
+static void __devinit wbsd_chip_config(struct wbsd_host* host)
+{
+       /*
+        * Reset the chip.
+        */     
+       wbsd_write_config(host, WBSD_CONF_SWRST, 1);
+       wbsd_write_config(host, WBSD_CONF_SWRST, 0);
 
        /*
         * Select SD/MMC function.
@@ -1399,165 +1637,241 @@ static int wbsd_probe(struct device* dev)
        /*
         * Set up card detection.
         */
-       wbsd_write_config(host, WBSD_CONF_PINS, 0x02);
+       wbsd_write_config(host, WBSD_CONF_PINS, WBSD_PINS_DETECT_GP11);
        
        /*
-        * Configure I/O port.
+        * Configure chip
         */
        wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8);
        wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff);
-
-       /*
-        * Allocate interrupt.
-        */
-       ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host);
-       if (ret)
-               goto release;
        
-       host->irq = irq;
+       wbsd_write_config(host, WBSD_CONF_IRQ, host->irq);
        
-       /*
-        * Set up tasklets.
-        */
-       tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host);
-       tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host);
-       tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host);
-       tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host);
-       tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host);
-       tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host);
+       if (host->dma >= 0)
+               wbsd_write_config(host, WBSD_CONF_DRQ, host->dma);
        
        /*
-        * Configure interrupt.
+        * Enable and power up chip.
         */
-       wbsd_write_config(host, WBSD_CONF_IRQ, host->irq);
+       wbsd_write_config(host, WBSD_CONF_ENABLE, 1);
+       wbsd_write_config(host, WBSD_CONF_POWER, 0x20);
+}
+
+/*
+ * Check that configured resources are correct.
+ */
+static int __devinit wbsd_chip_validate(struct wbsd_host* host)
+{
+       int base, irq, dma;
        
        /*
-        * Allocate DMA.
+        * Select SD/MMC function.
         */
-       wbsd_init_dma(host);
+       wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
        
        /*
-        * If all went well, then configure DMA.
+        * Read configuration.
         */
-       if (host->dma >= 0)
-               wbsd_write_config(host, WBSD_CONF_DRQ, host->dma);
+       base = wbsd_read_config(host, WBSD_CONF_PORT_HI) << 8;
+       base |= wbsd_read_config(host, WBSD_CONF_PORT_LO);
        
-       /*
-        * Maximum number of segments. Worst case is one sector per segment
-        * so this will be 64kB/512.
-        */
-       mmc->max_hw_segs = 128;
-       mmc->max_phys_segs = 128;
+       irq = wbsd_read_config(host, WBSD_CONF_IRQ);
+       
+       dma = wbsd_read_config(host, WBSD_CONF_DRQ);
        
        /*
-        * Maximum number of sectors in one transfer. Also limited by 64kB
-        * buffer.
+        * Validate against given configuration.
         */
-       mmc->max_sectors = 128;
+       if (base != host->base)
+               return 0;
+       if (irq != host->irq)
+               return 0;
+       if ((dma != host->dma) && (host->dma != -1))
+               return 0;
+       
+       return 1;
+}
+
+/*****************************************************************************\
+ *                                                                           *
+ * Devices setup and shutdown                                                *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
+       int pnp)
+{
+       struct wbsd_host* host = NULL;
+       struct mmc_host* mmc = NULL;
+       int ret;
+       
+       ret = wbsd_alloc_mmc(dev);
+       if (ret)
+               return ret;
+       
+       mmc = dev_get_drvdata(dev);
+       host = mmc_priv(mmc);
        
        /*
-        * Maximum segment size. Could be one segment with the maximum number
-        * of segments.
+        * Scan for hardware.
         */
-       mmc->max_seg_size = mmc->max_sectors * 512;
+       ret = wbsd_scan(host);
+       if (ret)
+       {
+               if (pnp && (ret == -ENODEV))
+               {
+                       printk(KERN_WARNING DRIVER_NAME
+                               ": Unable to confirm device presence. You may "
+                               "experience lock-ups.\n");
+               }
+               else
+               {
+                       wbsd_free_mmc(dev);
+                       return ret;
+               }
+       }
        
        /*
-        * Enable chip.
+        * Request resources.
         */
-       wbsd_write_config(host, WBSD_CONF_ENABLE, 1);
+       ret = wbsd_request_resources(host, io, irq, dma);
+       if (ret)
+       {
+               wbsd_release_resources(host);
+               wbsd_free_mmc(dev);
+               return ret;
+       }
        
        /*
-        * Power up chip.
+        * See if chip needs to be configured.
         */
-       wbsd_write_config(host, WBSD_CONF_POWER, 0x20);
+       if (pnp && (host->config != 0))
+       {
+               if (!wbsd_chip_validate(host))
+               {
+                       printk(KERN_WARNING DRIVER_NAME
+                               ": PnP active but chip not configured! "
+                               "You probably have a buggy BIOS. "
+                               "Configuring chip manually.\n");
+                       wbsd_chip_config(host);
+               }
+       }
+       else
+               wbsd_chip_config(host);
        
        /*
         * Power Management stuff. No idea how this works.
         * Not tested.
         */
 #ifdef CONFIG_PM
-       wbsd_write_config(host, WBSD_CONF_PME, 0xA0);
+       if (host->config)
+               wbsd_write_config(host, WBSD_CONF_PME, 0xA0);
 #endif
+       /*
+        * Allow device to initialise itself properly.
+        */
+       mdelay(5);
 
        /*
         * Reset the chip into a known state.
         */
        wbsd_init_device(host);
        
-       dev_set_drvdata(dev, mmc);
-       
-       /*
-        * Add host to MMC layer.
-        */
        mmc_add_host(mmc);
 
-       printk(KERN_INFO "%s: W83L51xD id %x at 0x%x irq %d dma %d\n",
-               mmc->host_name, (int)host->chip_id, (int)host->base,
-               (int)host->irq, (int)host->dma);
+       printk(KERN_INFO "%s: W83L51xD", mmc->host_name);
+       if (host->chip_id != 0)
+               printk(" id %x", (int)host->chip_id);
+       printk(" at 0x%x irq %d", (int)host->base, (int)host->irq);
+       if (host->dma >= 0)
+               printk(" dma %d", (int)host->dma);
+       else
+               printk(" FIFO");
+       if (pnp)
+               printk(" PnP");
+       printk("\n");
 
        return 0;
-
-release:
-       wbsd_release_regions(host);
-
-freemmc:
-       mmc_free_host(mmc);
-
-       return ret;
 }
 
-/*
- * Device remove
- */
-
-static int wbsd_remove(struct device* dev)
+static void __devexit wbsd_shutdown(struct device* dev, int pnp)
 {
        struct mmc_host* mmc = dev_get_drvdata(dev);
        struct wbsd_host* host;
        
        if (!mmc)
-               return 0;
+               return;
 
        host = mmc_priv(mmc);
        
-       /*
-        * Unregister host with MMC layer.
-        */
        mmc_remove_host(mmc);
 
-       /*
-        * Power down the SD/MMC function.
-        */
-       wbsd_unlock_config(host);
-       wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
-       wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
-       wbsd_lock_config(host);
+       if (!pnp)
+       {
+               /*
+                * Power down the SD/MMC function.
+                */
+               wbsd_unlock_config(host);
+               wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
+               wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
+               wbsd_lock_config(host);
+       }
        
-       /*
-        * Free resources.
-        */
-       if (host->dma_buffer)
-               kfree(host->dma_buffer);
+       wbsd_release_resources(host);
        
-       if (host->dma >= 0)
-               free_dma(host->dma);
+       wbsd_free_mmc(dev);
+}
 
-       free_irq(host->irq, host);
+/*
+ * Non-PnP
+ */
+
+static int __devinit wbsd_probe(struct device* dev)
+{
+       return wbsd_init(dev, io, irq, dma, 0);
+}
+
+static int __devexit wbsd_remove(struct device* dev)
+{
+       wbsd_shutdown(dev, 0);
+
+       return 0;
+}
+
+/*
+ * PnP
+ */
+
+#ifdef CONFIG_PNP
+
+static int __devinit
+wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
+{
+       int io, irq, dma;
        
-       tasklet_kill(&host->card_tasklet);
-       tasklet_kill(&host->fifo_tasklet);
-       tasklet_kill(&host->crc_tasklet);
-       tasklet_kill(&host->timeout_tasklet);
-       tasklet_kill(&host->finish_tasklet);
-       tasklet_kill(&host->block_tasklet);
+       /*
+        * Get resources from PnP layer.
+        */
+       io = pnp_port_start(pnpdev, 0);
+       irq = pnp_irq(pnpdev, 0);
+       if (pnp_dma_valid(pnpdev, 0))
+               dma = pnp_dma(pnpdev, 0);
+       else
+               dma = -1;
        
-       wbsd_release_regions(host);
+       DBGF("PnP resources: port %3x irq %d dma %d\n", io, irq, dma);
        
-       mmc_free_host(mmc);
+       return wbsd_init(&pnpdev->dev, io, irq, dma, 1);
+}
 
-       return 0;
+static void __devexit wbsd_pnp_remove(struct pnp_dev * dev)
+{
+       wbsd_shutdown(&dev->dev, 1);
 }
 
+#endif /* CONFIG_PNP */
+
 /*
  * Power management
  */
@@ -1581,17 +1895,7 @@ static int wbsd_resume(struct device *dev, u32 level)
 #define wbsd_resume NULL
 #endif
 
-static void wbsd_release(struct device *dev)
-{
-}
-
-static struct platform_device wbsd_device = {
-       .name           = DRIVER_NAME,
-       .id                     = -1,
-       .dev            = {
-               .release = wbsd_release,
-       },
-};
+static struct platform_device *wbsd_device;
 
 static struct device_driver wbsd_driver = {
        .name           = DRIVER_NAME,
@@ -1603,6 +1907,17 @@ static struct device_driver wbsd_driver = {
        .resume         = wbsd_resume,
 };
 
+#ifdef CONFIG_PNP
+
+static struct pnp_driver wbsd_pnp_driver = {
+       .name           = DRIVER_NAME,
+       .id_table       = pnp_dev_table,
+       .probe          = wbsd_pnp_probe,
+       .remove         = wbsd_pnp_remove,
+};
+
+#endif /* CONFIG_PNP */
+
 /*
  * Module loading/unloading
  */
@@ -1615,29 +1930,57 @@ static int __init wbsd_drv_init(void)
                ": Winbond W83L51xD SD/MMC card interface driver, "
                DRIVER_VERSION "\n");
        printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
-       
-       result = driver_register(&wbsd_driver);
-       if (result < 0)
-               return result;
 
-       result = platform_device_register(&wbsd_device);
-       if (result < 0)
-               return result;
+#ifdef CONFIG_PNP
+
+       if (!nopnp)
+       {
+               result = pnp_register_driver(&wbsd_pnp_driver);
+               if (result < 0)
+                       return result;
+       }
+
+#endif /* CONFIG_PNP */        
+       
+       if (nopnp)
+       {
+               result = driver_register(&wbsd_driver);
+               if (result < 0)
+                       return result;
+
+               wbsd_device = platform_device_register_simple(DRIVER_NAME, -1,
+                       NULL, 0);
+               if (IS_ERR(wbsd_device))
+                       return PTR_ERR(wbsd_device);
+       }
 
        return 0;
 }
 
 static void __exit wbsd_drv_exit(void)
 {
-       platform_device_unregister(&wbsd_device);
+#ifdef CONFIG_PNP
+
+       if (!nopnp)
+               pnp_unregister_driver(&wbsd_pnp_driver);
        
-       driver_unregister(&wbsd_driver);
+#endif /* CONFIG_PNP */        
+
+       if (nopnp)
+       {
+               platform_device_unregister(wbsd_device);
+       
+               driver_unregister(&wbsd_driver);
+       }
 
        DBG("unloaded\n");
 }
 
 module_init(wbsd_drv_init);
 module_exit(wbsd_drv_exit);
+#ifdef CONFIG_PNP
+module_param(nopnp, uint, 0444);
+#endif
 module_param(io, uint, 0444);
 module_param(irq, uint, 0444);
 module_param(dma, int, 0444);
@@ -1646,6 +1989,9 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");
 MODULE_VERSION(DRIVER_VERSION);
 
+#ifdef CONFIG_PNP
+MODULE_PARM_DESC(nopnp, "Scan for device instead of relying on PNP. (default 0)");
+#endif
 MODULE_PARM_DESC(io, "I/O base to allocate. Must be 8 byte aligned. (default 0x248)");
 MODULE_PARM_DESC(irq, "IRQ to allocate. (default 6)");
 MODULE_PARM_DESC(dma, "DMA channel to allocate. -1 for no DMA. (default 2)");
index fdc03b56a81fbdecb38b0a394927efcc750ba442..864f30828d01fe4f52da21502c91f3cec18e6ed4 100644 (file)
@@ -35,6 +35,12 @@ const int valid_ids[] = {
 
 #define DEVICE_SD              0x03
 
+#define WBSD_PINS_DAT3_HI      0x20
+#define WBSD_PINS_DAT3_OUT     0x10
+#define WBSD_PINS_GP11_HI      0x04
+#define WBSD_PINS_DETECT_GP11  0x02
+#define WBSD_PINS_DETECT_DAT3  0x01
+
 #define WBSD_CMDR              0x00
 #define WBSD_DFR               0x01
 #define WBSD_EIR               0x02
@@ -133,6 +139,7 @@ const int valid_ids[] = {
 #define WBSD_CRC_OK            0x05 /* S010E (00101) */
 #define WBSD_CRC_FAIL          0x0B /* S101E (01011) */
 
+#define WBSD_DMA_SIZE          65536
 
 struct wbsd_host
 {
@@ -140,6 +147,11 @@ struct wbsd_host
        
        spinlock_t              lock;           /* Mutex */
 
+       int                     flags;          /* Driver states */
+
+#define WBSD_FCARD_PRESENT     (1<<0)          /* Card is present */
+#define WBSD_FIGNORE_DETECT    (1<<1)          /* Ignore card detection */
+       
        struct mmc_request*     mrq;            /* Current request */
        
        u8                      isr;            /* Accumulated ISR */
index 43e2ac532f82e51bd4070dcd9fd59de16531fd61..b5e076043431aa69769503a41486c591aa7d23ea 100644 (file)
@@ -1581,7 +1581,8 @@ vortex_up(struct net_device *dev)
 
        if (VORTEX_PCI(vp)) {
                pci_set_power_state(VORTEX_PCI(vp), PCI_D0);    /* Go active */
-               pci_restore_state(VORTEX_PCI(vp));
+               if (vp->pm_state_valid)
+                       pci_restore_state(VORTEX_PCI(vp));
                pci_enable_device(VORTEX_PCI(vp));
        }
 
@@ -2741,6 +2742,7 @@ vortex_down(struct net_device *dev, int final_down)
                outl(0, ioaddr + DownListPtr);
 
        if (final_down && VORTEX_PCI(vp)) {
+               vp->pm_state_valid = 1;
                pci_save_state(VORTEX_PCI(vp));
                acpi_set_WOL(dev);
        }
@@ -3243,9 +3245,10 @@ static void acpi_set_WOL(struct net_device *dev)
                outw(RxEnable, ioaddr + EL3_CMD);
 
                pci_enable_wake(VORTEX_PCI(vp), 0, 1);
+
+               /* Change the power state to D3; RxEnable doesn't take effect. */
+               pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
        }
-       /* Change the power state to D3; RxEnable doesn't take effect. */
-       pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
 }
 
 
index 68242bda4b9cd2dabd292dc393078b7fc615d7bf..f08e01b2fd190d729ea48b951a24658a4883a689 100644 (file)
@@ -589,7 +589,7 @@ config EL2
 
 config ELPLUS
        tristate "3c505 \"EtherLink Plus\" support"
-       depends on NET_VENDOR_3COM && ISA
+       depends on NET_VENDOR_3COM && ISA && ISA_DMA_API
        ---help---
          Information about this network (Ethernet) card can be found in
          <file:Documentation/networking/3c505.txt>.  If you have a card of
@@ -630,7 +630,7 @@ config EL3
 
 config 3C515
        tristate "3c515 ISA \"Fast EtherLink\""
-       depends on NET_VENDOR_3COM && (ISA || EISA)
+       depends on NET_VENDOR_3COM && (ISA || EISA) && ISA_DMA_API
        help
          If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
          network card, say Y and read the Ethernet-HOWTO, available from
@@ -708,7 +708,7 @@ config TYPHOON
 
 config LANCE
        tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
-       depends on NET_ETHERNET && ISA
+       depends on NET_ETHERNET && ISA && ISA_DMA_API
        help
          If you have a network (Ethernet) card of this type, say Y and read
          the Ethernet-HOWTO, available from
@@ -864,7 +864,7 @@ config NI52
 
 config NI65
        tristate "NI6510 support"
-       depends on NET_VENDOR_RACAL && ISA
+       depends on NET_VENDOR_RACAL && ISA && ISA_DMA_API
        help
          If you have a network (Ethernet) card of this type, say Y and read
          the Ethernet-HOWTO, available from
@@ -1072,7 +1072,7 @@ config NE2000
 
 config ZNET
        tristate "Zenith Z-Note support (EXPERIMENTAL)"
-       depends on NET_ISA && EXPERIMENTAL
+       depends on NET_ISA && EXPERIMENTAL && ISA_DMA_API
        help
          The Zenith Z-Note notebook computer has a built-in network
          (Ethernet) card, and this is the Linux driver for it. Note that the
@@ -1555,6 +1555,7 @@ config SIS900
        tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
        depends on NET_PCI && PCI
        select CRC32
+       select MII
        ---help---
          This is a driver for the Fast Ethernet PCI network cards based on
          the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in
@@ -2031,6 +2032,15 @@ config TIGON3
          To compile this driver as a module, choose M here: the module
          will be called tg3.  This is recommended.
 
+config BNX2
+       tristate "Broadcom NetXtremeII support"
+       depends on PCI
+       help
+         This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
+
+         To compile this driver as a module, choose M here: the module
+         will be called bnx2.  This is recommended.
+
 config GIANFAR
        tristate "Gianfar Ethernet"
        depends on 85xx || 83xx
index 6202b10dbb4df11c92119b253fc7281fe5bbf41d..30c7567001fec3b4ab26f66374cc943b9365dc86 100644 (file)
@@ -51,6 +51,7 @@ obj-$(CONFIG_NS83820) += ns83820.o
 obj-$(CONFIG_STNIC) += stnic.o 8390.o
 obj-$(CONFIG_FEALNX) += fealnx.o
 obj-$(CONFIG_TIGON3) += tg3.o
+obj-$(CONFIG_BNX2) += bnx2.o
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SK98LIN) += sk98lin/
 obj-$(CONFIG_SKFP) += skfp/
@@ -187,7 +188,7 @@ obj-$(CONFIG_TR) += tokenring/
 obj-$(CONFIG_WAN) += wan/
 obj-$(CONFIG_ARCNET) += arcnet/
 obj-$(CONFIG_NET_PCMCIA) += pcmcia/
-obj-$(CONFIG_NET_WIRELESS) += wireless/
+obj-$(CONFIG_NET_RADIO) += wireless/
 obj-$(CONFIG_NET_TULIP) += tulip/
 obj-$(CONFIG_HAMRADIO) += hamradio/
 obj-$(CONFIG_IRDA) += irda/
index fc519377b5aa91d18f839cc5d2d5a8ba18ede3d6..fb433325aa277e7dec82aa526c233a093b10f145 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)Space.c     1.0.7   08/12/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Donald J. Becker, <becker@scyld.com>
  *
index f2e937abf7b4d8c639675100dd5ffc74c5323ebe..b7dd7260cafbf137656a3f50059a7136b55ec661 100755 (executable)
@@ -738,6 +738,7 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget)
        short vtag;
 #endif
        int rx_pkt_limit = dev->quota;
+       unsigned long flags;
        
        do{   
                /* process receive packets until we use the quota*/
@@ -841,18 +842,19 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget)
        /* Receive descriptor is empty now */
        dev->quota -= num_rx_pkt;
        *budget -= num_rx_pkt;
+
+       spin_lock_irqsave(&lp->lock, flags);
        netif_rx_complete(dev);
-       /* enable receive interrupt */
        writel(VAL0|RINTEN0, mmio + INTEN0);
        writel(VAL2 | RDMD0, mmio + CMD0);
+       spin_unlock_irqrestore(&lp->lock, flags);
        return 0;
+
 rx_not_empty:
        /* Do not call a netif_rx_complete */
        dev->quota -= num_rx_pkt;       
        *budget -= num_rx_pkt;
        return 1;
-
-       
 }
 
 #else
@@ -1261,18 +1263,20 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
        struct net_device * dev = (struct net_device *) dev_id;
        struct amd8111e_priv *lp = netdev_priv(dev);
        void __iomem *mmio = lp->mmio;
-       unsigned int intr0;
+       unsigned int intr0, intren0;
        unsigned int handled = 1;
 
-       if(dev == NULL)
+       if(unlikely(dev == NULL))
                return IRQ_NONE;
 
-       if (regs) spin_lock (&lp->lock);
+       spin_lock(&lp->lock);
+
        /* disabling interrupt */
        writel(INTREN, mmio + CMD0);
 
        /* Read interrupt status */
        intr0 = readl(mmio + INT0);
+       intren0 = readl(mmio + INTEN0);
 
        /* Process all the INT event until INTR bit is clear. */
 
@@ -1293,11 +1297,11 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
                        /* Schedule a polling routine */
                        __netif_rx_schedule(dev);
                }
-               else {
+               else if (intren0 & RINTEN0) {
                        printk("************Driver bug! \
                                interrupt while in poll\n");
-                       /* Fix by disabling interrupts */
-                       writel(RINT0, mmio + INT0);
+                       /* Fix by disable receive interrupts */
+                       writel(RINTEN0, mmio + INTEN0);
                }
        }
 #else
@@ -1321,7 +1325,7 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
 err_no_interrupt:
        writel( VAL0 | INTREN,mmio + CMD0);
        
-       if (regs) spin_unlock(&lp->lock);
+       spin_unlock(&lp->lock);
        
        return IRQ_RETVAL(handled);
 }
index 60b19679ca5c7b8a0db1a73f3e2d342dac43a2f5..69c488d933a2bb799d8e5c9853cb262358a75e9f 100644 (file)
@@ -13,7 +13,7 @@ config DEV_APPLETALK
 
 config LTPC
        tristate "Apple/Farallon LocalTalk PC support"
-       depends on DEV_APPLETALK && (ISA || EISA)
+       depends on DEV_APPLETALK && (ISA || EISA) && ISA_DMA_API
        help
          This allows you to use the AppleTalk PC card to connect to LocalTalk
          networks. The card is also known as the Farallon PhoneNet PC card.
index 2161c2d585f0869e57ebfe101a49686f5ea36b4b..9edaa183227a36afb5f15737055e015631055d12 100644 (file)
@@ -65,7 +65,7 @@ static const char *version =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
-#include <linux/if_ltalk.h>    /* For ltalk_setup() */
+#include <linux/if_ltalk.h>
 #include <linux/delay.h>       /* For udelay() */
 #include <linux/atalk.h>
 #include <linux/spinlock.h>
@@ -223,7 +223,7 @@ struct net_device * __init cops_probe(int unit)
        int base_addr;
        int err = 0;
 
-       dev = alloc_netdev(sizeof(struct cops_local), "lt%d", ltalk_setup);
+       dev = alloc_ltalkdev(sizeof(struct cops_local));
        if (!dev)
                return ERR_PTR(-ENOMEM);
 
index 4131b4a7a65b10bf42360af55535edb007ab7975..31cf8c9c947ff3d15468b6ce81675b795f7d23ff 100644 (file)
@@ -28,7 +28,7 @@
 
 #ifdef CONFIG_COPS_DAYNA
 
-unsigned char ffdrv_code[] = {
+static const unsigned char ffdrv_code[] = {
        58,3,0,50,228,149,33,255,255,34,226,149,
        249,17,40,152,33,202,154,183,237,82,77,68,
        11,107,98,19,54,0,237,176,175,50,80,0,
index 05de66dd9206018ec47b728922669e6a060b8a7b..4afb8e18ba654ed9e523831d5f9f94cdd898f407 100644 (file)
@@ -27,7 +27,7 @@
 
 #ifdef CONFIG_COPS_TANGENT
 
-unsigned char ltdrv_code[] = {
+static const unsigned char ltdrv_code[] = {
        58,3,0,50,148,10,33,143,15,62,85,119,
        190,32,9,62,170,119,190,32,3,35,24,241,
        34,146,10,249,17,150,10,33,143,15,183,237,
index ad8e943231a1c3a93cb769fb3d1fad23baa40ac6..db4f369637b63f435bf04694e5641e9cf535281f 100644 (file)
@@ -1039,7 +1039,7 @@ struct net_device * __init ltpc_probe(void)
        unsigned long f;
        unsigned long timeout;
 
-       dev = alloc_netdev(sizeof(struct ltpc_private), "lt%d", ltalk_setup);
+       dev = alloc_ltalkdev(sizeof(struct ltpc_private));
        if (!dev)
                goto out;
 
index 16e155b041293a4c58d6959f0823260455976e60..66485585ab393a1fc7eb210895cdd896be9d81d6 100644 (file)
@@ -48,7 +48,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 static int ack_tx(struct net_device *dev, int acked);
 
 
-struct ArcProto capmode_proto =
+static struct ArcProto capmode_proto =
 {
        'r',
        XMTU,
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
new file mode 100644 (file)
index 0000000..8acc655
--- /dev/null
@@ -0,0 +1,5530 @@
+/* bnx2.c: Broadcom NX2 network driver.
+ *
+ * Copyright (c) 2004, 2005 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.
+ *
+ * Written by: Michael Chan  (mchan@broadcom.com)
+ */
+
+#include "bnx2.h"
+#include "bnx2_fw.h"
+
+#define DRV_MODULE_NAME                "bnx2"
+#define PFX DRV_MODULE_NAME    ": "
+#define DRV_MODULE_VERSION     "1.2.19"
+#define DRV_MODULE_RELDATE     "May 23, 2005"
+
+#define RUN_AT(x) (jiffies + (x))
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (5*HZ)
+
+static char version[] __devinitdata =
+       "Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+
+MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706 Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_MODULE_VERSION);
+
+static int disable_msi = 0;
+
+module_param(disable_msi, int, 0);
+MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
+
+typedef enum {
+       BCM5706 = 0,
+       NC370T,
+       NC370I,
+       BCM5706S,
+       NC370F,
+} board_t;
+
+/* indexed by board_t, above */
+static struct {
+       char *name;
+} board_info[] __devinitdata = {
+       { "Broadcom NetXtreme II BCM5706 1000Base-T" },
+       { "HP NC370T Multifunction Gigabit Server Adapter" },
+       { "HP NC370i Multifunction Gigabit Server Adapter" },
+       { "Broadcom NetXtreme II BCM5706 1000Base-SX" },
+       { "HP NC370F Multifunction Gigabit Server Adapter" },
+       { 0 },
+       };
+
+static struct pci_device_id bnx2_pci_tbl[] = {
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
+         PCI_VENDOR_ID_HP, 0x3101, 0, 0, NC370T },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
+         PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
+         PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S },
+       { 0, }
+};
+
+static struct flash_spec flash_table[] =
+{
+       /* Slow EEPROM */
+       {0x00000000, 0x40030380, 0x009f0081, 0xa184a053, 0xaf000400,
+        1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
+        SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
+        "EEPROM - slow"},
+       /* Fast EEPROM */
+       {0x02000000, 0x62008380, 0x009f0081, 0xa184a053, 0xaf000400,
+        1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
+        SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
+        "EEPROM - fast"},
+       /* ATMEL AT45DB011B (buffered flash) */
+       {0x02000003, 0x6e008173, 0x00570081, 0x68848353, 0xaf000400,
+        1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+        BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
+        "Buffered flash"},
+       /* Saifun SA25F005 (non-buffered flash) */
+               /* strap, cfg1, & write1 need updates */
+       {0x01000003, 0x5f008081, 0x00050081, 0x03840253, 0xaf020406,
+        0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+        SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
+        "Non-buffered flash (64kB)"},
+       /* Saifun SA25F010 (non-buffered flash) */
+       /* strap, cfg1, & write1 need updates */
+       {0x00000001, 0x47008081, 0x00050081, 0x03840253, 0xaf020406,
+        0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+        SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
+        "Non-buffered flash (128kB)"},
+       /* Saifun SA25F020 (non-buffered flash) */
+       /* strap, cfg1, & write1 need updates */
+       {0x00000003, 0x4f008081, 0x00050081, 0x03840253, 0xaf020406,
+        0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+        SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
+        "Non-buffered flash (256kB)"},
+};
+
+MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
+
+static u32
+bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
+{
+       REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
+       return (REG_RD(bp, BNX2_PCICFG_REG_WINDOW));
+}
+
+static void
+bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
+{
+       REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
+       REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
+}
+
+static void
+bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
+{
+       offset += cid_addr;
+       REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
+       REG_WR(bp, BNX2_CTX_DATA, val);
+}
+
+static int
+bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
+{
+       u32 val1;
+       int i, ret;
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+               val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+               val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
+
+               REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+               REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+
+               udelay(40);
+       }
+
+       val1 = (bp->phy_addr << 21) | (reg << 16) |
+               BNX2_EMAC_MDIO_COMM_COMMAND_READ | BNX2_EMAC_MDIO_COMM_DISEXT |
+               BNX2_EMAC_MDIO_COMM_START_BUSY;
+       REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
+
+       for (i = 0; i < 50; i++) {
+               udelay(10);
+
+               val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
+               if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
+                       udelay(5);
+
+                       val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
+                       val1 &= BNX2_EMAC_MDIO_COMM_DATA;
+
+                       break;
+               }
+       }
+
+       if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) {
+               *val = 0x0;
+               ret = -EBUSY;
+       }
+       else {
+               *val = val1;
+               ret = 0;
+       }
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+               val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+               val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
+
+               REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+               REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+
+               udelay(40);
+       }
+
+       return ret;
+}
+
+static int
+bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
+{
+       u32 val1;
+       int i, ret;
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+               val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+               val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
+
+               REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+               REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+
+               udelay(40);
+       }
+
+       val1 = (bp->phy_addr << 21) | (reg << 16) | val |
+               BNX2_EMAC_MDIO_COMM_COMMAND_WRITE |
+               BNX2_EMAC_MDIO_COMM_START_BUSY | BNX2_EMAC_MDIO_COMM_DISEXT;
+       REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
+    
+       for (i = 0; i < 50; i++) {
+               udelay(10);
+
+               val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
+               if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
+                       udelay(5);
+                       break;
+               }
+       }
+
+       if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)
+               ret = -EBUSY;
+       else
+               ret = 0;
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+               val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+               val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
+
+               REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+               REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+
+               udelay(40);
+       }
+
+       return ret;
+}
+
+static void
+bnx2_disable_int(struct bnx2 *bp)
+{
+       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+              BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
+       REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
+}
+
+static void
+bnx2_enable_int(struct bnx2 *bp)
+{
+       u32 val;
+
+       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+              BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx);
+
+       val = REG_RD(bp, BNX2_HC_COMMAND);
+       REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW);
+}
+
+static void
+bnx2_disable_int_sync(struct bnx2 *bp)
+{
+       atomic_inc(&bp->intr_sem);
+       bnx2_disable_int(bp);
+       synchronize_irq(bp->pdev->irq);
+}
+
+static void
+bnx2_netif_stop(struct bnx2 *bp)
+{
+       bnx2_disable_int_sync(bp);
+       if (netif_running(bp->dev)) {
+               netif_poll_disable(bp->dev);
+               netif_tx_disable(bp->dev);
+               bp->dev->trans_start = jiffies; /* prevent tx timeout */
+       }
+}
+
+static void
+bnx2_netif_start(struct bnx2 *bp)
+{
+       if (atomic_dec_and_test(&bp->intr_sem)) {
+               if (netif_running(bp->dev)) {
+                       netif_wake_queue(bp->dev);
+                       netif_poll_enable(bp->dev);
+                       bnx2_enable_int(bp);
+               }
+       }
+}
+
+static void
+bnx2_free_mem(struct bnx2 *bp)
+{
+       if (bp->stats_blk) {
+               pci_free_consistent(bp->pdev, sizeof(struct statistics_block),
+                                   bp->stats_blk, bp->stats_blk_mapping);
+               bp->stats_blk = NULL;
+       }
+       if (bp->status_blk) {
+               pci_free_consistent(bp->pdev, sizeof(struct status_block),
+                                   bp->status_blk, bp->status_blk_mapping);
+               bp->status_blk = NULL;
+       }
+       if (bp->tx_desc_ring) {
+               pci_free_consistent(bp->pdev,
+                                   sizeof(struct tx_bd) * TX_DESC_CNT,
+                                   bp->tx_desc_ring, bp->tx_desc_mapping);
+               bp->tx_desc_ring = NULL;
+       }
+       if (bp->tx_buf_ring) {
+               kfree(bp->tx_buf_ring);
+               bp->tx_buf_ring = NULL;
+       }
+       if (bp->rx_desc_ring) {
+               pci_free_consistent(bp->pdev,
+                                   sizeof(struct rx_bd) * RX_DESC_CNT,
+                                   bp->rx_desc_ring, bp->rx_desc_mapping);
+               bp->rx_desc_ring = NULL;
+       }
+       if (bp->rx_buf_ring) {
+               kfree(bp->rx_buf_ring);
+               bp->rx_buf_ring = NULL;
+       }
+}
+
+static int
+bnx2_alloc_mem(struct bnx2 *bp)
+{
+       bp->tx_buf_ring = kmalloc(sizeof(struct sw_bd) * TX_DESC_CNT,
+                                    GFP_KERNEL);
+       if (bp->tx_buf_ring == NULL)
+               return -ENOMEM;
+
+       memset(bp->tx_buf_ring, 0, sizeof(struct sw_bd) * TX_DESC_CNT);
+       bp->tx_desc_ring = pci_alloc_consistent(bp->pdev,
+                                               sizeof(struct tx_bd) *
+                                               TX_DESC_CNT,
+                                               &bp->tx_desc_mapping);
+       if (bp->tx_desc_ring == NULL)
+               goto alloc_mem_err;
+
+       bp->rx_buf_ring = kmalloc(sizeof(struct sw_bd) * RX_DESC_CNT,
+                                    GFP_KERNEL);
+       if (bp->rx_buf_ring == NULL)
+               goto alloc_mem_err;
+
+       memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT);
+       bp->rx_desc_ring = pci_alloc_consistent(bp->pdev,
+                                               sizeof(struct rx_bd) *
+                                               RX_DESC_CNT,
+                                               &bp->rx_desc_mapping);
+       if (bp->rx_desc_ring == NULL)
+               goto alloc_mem_err;
+
+       bp->status_blk = pci_alloc_consistent(bp->pdev,
+                                             sizeof(struct status_block),
+                                             &bp->status_blk_mapping);
+       if (bp->status_blk == NULL)
+               goto alloc_mem_err;
+
+       memset(bp->status_blk, 0, sizeof(struct status_block));
+
+       bp->stats_blk = pci_alloc_consistent(bp->pdev,
+                                            sizeof(struct statistics_block),
+                                            &bp->stats_blk_mapping);
+       if (bp->stats_blk == NULL)
+               goto alloc_mem_err;
+
+       memset(bp->stats_blk, 0, sizeof(struct statistics_block));
+
+       return 0;
+
+alloc_mem_err:
+       bnx2_free_mem(bp);
+       return -ENOMEM;
+}
+
+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("%d Mbps ", bp->line_speed);
+
+               if (bp->duplex == DUPLEX_FULL)
+                       printk("full duplex");
+               else
+                       printk("half duplex");
+
+               if (bp->flow_ctrl) {
+                       if (bp->flow_ctrl & FLOW_CTRL_RX) {
+                               printk(", receive ");
+                               if (bp->flow_ctrl & FLOW_CTRL_TX)
+                                       printk("& transmit ");
+                       }
+                       else {
+                               printk(", transmit ");
+                       }
+                       printk("flow control ON");
+               }
+               printk("\n");
+       }
+       else {
+               netif_carrier_off(bp->dev);
+               printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
+       }
+}
+
+static void
+bnx2_resolve_flow_ctrl(struct bnx2 *bp)
+{
+       u32 local_adv, remote_adv;
+
+       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;
+               }
+               return;
+       }
+
+       if (bp->duplex != DUPLEX_FULL) {
+               return;
+       }
+
+       bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
+       bnx2_read_phy(bp, MII_LPA, &remote_adv);
+
+       if (bp->phy_flags & PHY_SERDES_FLAG) {
+               u32 new_local_adv = 0;
+               u32 new_remote_adv = 0;
+
+               if (local_adv & ADVERTISE_1000XPAUSE)
+                       new_local_adv |= ADVERTISE_PAUSE_CAP;
+               if (local_adv & ADVERTISE_1000XPSE_ASYM)
+                       new_local_adv |= ADVERTISE_PAUSE_ASYM;
+               if (remote_adv & ADVERTISE_1000XPAUSE)
+                       new_remote_adv |= ADVERTISE_PAUSE_CAP;
+               if (remote_adv & ADVERTISE_1000XPSE_ASYM)
+                       new_remote_adv |= ADVERTISE_PAUSE_ASYM;
+
+               local_adv = new_local_adv;
+               remote_adv = new_remote_adv;
+       }
+
+       /* See Table 28B-3 of 802.3ab-1999 spec. */
+       if (local_adv & ADVERTISE_PAUSE_CAP) {
+               if(local_adv & ADVERTISE_PAUSE_ASYM) {
+                       if (remote_adv & ADVERTISE_PAUSE_CAP) {
+                               bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
+                       }
+                       else if (remote_adv & ADVERTISE_PAUSE_ASYM) {
+                               bp->flow_ctrl = FLOW_CTRL_RX;
+                       }
+               }
+               else {
+                       if (remote_adv & ADVERTISE_PAUSE_CAP) {
+                               bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
+                       }
+               }
+       }
+       else if (local_adv & ADVERTISE_PAUSE_ASYM) {
+               if ((remote_adv & ADVERTISE_PAUSE_CAP) &&
+                       (remote_adv & ADVERTISE_PAUSE_ASYM)) {
+
+                       bp->flow_ctrl = FLOW_CTRL_TX;
+               }
+       }
+}
+
+static int
+bnx2_serdes_linkup(struct bnx2 *bp)
+{
+       u32 bmcr, local_adv, remote_adv, common;
+
+       bp->link_up = 1;
+       bp->line_speed = SPEED_1000;
+
+       bnx2_read_phy(bp, MII_BMCR, &bmcr);
+       if (bmcr & BMCR_FULLDPLX) {
+               bp->duplex = DUPLEX_FULL;
+       }
+       else {
+               bp->duplex = DUPLEX_HALF;
+       }
+
+       if (!(bmcr & BMCR_ANENABLE)) {
+               return 0;
+       }
+
+       bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
+       bnx2_read_phy(bp, MII_LPA, &remote_adv);
+
+       common = local_adv & remote_adv;
+       if (common & (ADVERTISE_1000XHALF | ADVERTISE_1000XFULL)) {
+
+               if (common & ADVERTISE_1000XFULL) {
+                       bp->duplex = DUPLEX_FULL;
+               }
+               else {
+                       bp->duplex = DUPLEX_HALF;
+               }
+       }
+
+       return 0;
+}
+
+static int
+bnx2_copper_linkup(struct bnx2 *bp)
+{
+       u32 bmcr;
+
+       bnx2_read_phy(bp, MII_BMCR, &bmcr);
+       if (bmcr & BMCR_ANENABLE) {
+               u32 local_adv, remote_adv, common;
+
+               bnx2_read_phy(bp, MII_CTRL1000, &local_adv);
+               bnx2_read_phy(bp, MII_STAT1000, &remote_adv);
+
+               common = local_adv & (remote_adv >> 2);
+               if (common & ADVERTISE_1000FULL) {
+                       bp->line_speed = SPEED_1000;
+                       bp->duplex = DUPLEX_FULL;
+               }
+               else if (common & ADVERTISE_1000HALF) {
+                       bp->line_speed = SPEED_1000;
+                       bp->duplex = DUPLEX_HALF;
+               }
+               else {
+                       bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
+                       bnx2_read_phy(bp, MII_LPA, &remote_adv);
+
+                       common = local_adv & remote_adv;
+                       if (common & ADVERTISE_100FULL) {
+                               bp->line_speed = SPEED_100;
+                               bp->duplex = DUPLEX_FULL;
+                       }
+                       else if (common & ADVERTISE_100HALF) {
+                               bp->line_speed = SPEED_100;
+                               bp->duplex = DUPLEX_HALF;
+                       }
+                       else if (common & ADVERTISE_10FULL) {
+                               bp->line_speed = SPEED_10;
+                               bp->duplex = DUPLEX_FULL;
+                       }
+                       else if (common & ADVERTISE_10HALF) {
+                               bp->line_speed = SPEED_10;
+                               bp->duplex = DUPLEX_HALF;
+                       }
+                       else {
+                               bp->line_speed = 0;
+                               bp->link_up = 0;
+                       }
+               }
+       }
+       else {
+               if (bmcr & BMCR_SPEED100) {
+                       bp->line_speed = SPEED_100;
+               }
+               else {
+                       bp->line_speed = SPEED_10;
+               }
+               if (bmcr & BMCR_FULLDPLX) {
+                       bp->duplex = DUPLEX_FULL;
+               }
+               else {
+                       bp->duplex = DUPLEX_HALF;
+               }
+       }
+
+       return 0;
+}
+
+static int
+bnx2_set_mac_link(struct bnx2 *bp)
+{
+       u32 val;
+
+       REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x2620);
+       if (bp->link_up && (bp->line_speed == SPEED_1000) &&
+               (bp->duplex == DUPLEX_HALF)) {
+               REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x26ff);
+       }
+
+       /* Configure the EMAC mode register. */
+       val = REG_RD(bp, BNX2_EMAC_MODE);
+
+       val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
+               BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK);
+
+       if (bp->link_up) {
+               if (bp->line_speed != SPEED_1000)
+                       val |= BNX2_EMAC_MODE_PORT_MII;
+               else
+                       val |= BNX2_EMAC_MODE_PORT_GMII;
+       }
+       else {
+               val |= BNX2_EMAC_MODE_PORT_GMII;
+       }
+
+       /* Set the MAC to operate in the appropriate duplex mode. */
+       if (bp->duplex == DUPLEX_HALF)
+               val |= BNX2_EMAC_MODE_HALF_DUPLEX;
+       REG_WR(bp, BNX2_EMAC_MODE, val);
+
+       /* Enable/disable rx PAUSE. */
+       bp->rx_mode &= ~BNX2_EMAC_RX_MODE_FLOW_EN;
+
+       if (bp->flow_ctrl & FLOW_CTRL_RX)
+               bp->rx_mode |= BNX2_EMAC_RX_MODE_FLOW_EN;
+       REG_WR(bp, BNX2_EMAC_RX_MODE, bp->rx_mode);
+
+       /* Enable/disable tx PAUSE. */
+       val = REG_RD(bp, BNX2_EMAC_TX_MODE);
+       val &= ~BNX2_EMAC_TX_MODE_FLOW_EN;
+
+       if (bp->flow_ctrl & FLOW_CTRL_TX)
+               val |= BNX2_EMAC_TX_MODE_FLOW_EN;
+       REG_WR(bp, BNX2_EMAC_TX_MODE, val);
+
+       /* Acknowledge the interrupt. */
+       REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
+
+       return 0;
+}
+
+static int
+bnx2_set_link(struct bnx2 *bp)
+{
+       u32 bmsr;
+       u8 link_up;
+
+       if (bp->loopback == MAC_LOOPBACK) {
+               bp->link_up = 1;
+               return 0;
+       }
+
+       link_up = bp->link_up;
+
+       bnx2_read_phy(bp, MII_BMSR, &bmsr);
+       bnx2_read_phy(bp, MII_BMSR, &bmsr);
+
+       if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+           (CHIP_NUM(bp) == CHIP_NUM_5706)) {
+               u32 val;
+
+               val = REG_RD(bp, BNX2_EMAC_STATUS);
+               if (val & BNX2_EMAC_STATUS_LINK)
+                       bmsr |= BMSR_LSTATUS;
+               else
+                       bmsr &= ~BMSR_LSTATUS;
+       }
+
+       if (bmsr & BMSR_LSTATUS) {
+               bp->link_up = 1;
+
+               if (bp->phy_flags & PHY_SERDES_FLAG) {
+                       bnx2_serdes_linkup(bp);
+               }
+               else {
+                       bnx2_copper_linkup(bp);
+               }
+               bnx2_resolve_flow_ctrl(bp);
+       }
+       else {
+               if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+                       (bp->autoneg & AUTONEG_SPEED)) {
+
+                       u32 bmcr;
+
+                       bnx2_read_phy(bp, MII_BMCR, &bmcr);
+                       if (!(bmcr & BMCR_ANENABLE)) {
+                               bnx2_write_phy(bp, MII_BMCR, bmcr |
+                                       BMCR_ANENABLE);
+                       }
+               }
+               bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+               bp->link_up = 0;
+       }
+
+       if (bp->link_up != link_up) {
+               bnx2_report_link(bp);
+       }
+
+       bnx2_set_mac_link(bp);
+
+       return 0;
+}
+
+static int
+bnx2_reset_phy(struct bnx2 *bp)
+{
+       int i;
+       u32 reg;
+
+        bnx2_write_phy(bp, MII_BMCR, BMCR_RESET);
+
+#define PHY_RESET_MAX_WAIT 100
+       for (i = 0; i < PHY_RESET_MAX_WAIT; i++) {
+               udelay(10);
+
+               bnx2_read_phy(bp, MII_BMCR, &reg);
+               if (!(reg & BMCR_RESET)) {
+                       udelay(20);
+                       break;
+               }
+       }
+       if (i == PHY_RESET_MAX_WAIT) {
+               return -EBUSY;
+       }
+       return 0;
+}
+
+static u32
+bnx2_phy_get_pause_adv(struct bnx2 *bp)
+{
+       u32 adv = 0;
+
+       if ((bp->req_flow_ctrl & (FLOW_CTRL_RX | FLOW_CTRL_TX)) ==
+               (FLOW_CTRL_RX | FLOW_CTRL_TX)) {
+
+               if (bp->phy_flags & PHY_SERDES_FLAG) {
+                       adv = ADVERTISE_1000XPAUSE;
+               }
+               else {
+                       adv = ADVERTISE_PAUSE_CAP;
+               }
+       }
+       else if (bp->req_flow_ctrl & FLOW_CTRL_TX) {
+               if (bp->phy_flags & PHY_SERDES_FLAG) {
+                       adv = ADVERTISE_1000XPSE_ASYM;
+               }
+               else {
+                       adv = ADVERTISE_PAUSE_ASYM;
+               }
+       }
+       else if (bp->req_flow_ctrl & FLOW_CTRL_RX) {
+               if (bp->phy_flags & PHY_SERDES_FLAG) {
+                       adv = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
+               }
+               else {
+                       adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+               }
+       }
+       return adv;
+}
+
+static int
+bnx2_setup_serdes_phy(struct bnx2 *bp)
+{
+       u32 adv, bmcr;
+       u32 new_adv = 0;
+
+       if (!(bp->autoneg & AUTONEG_SPEED)) {
+               u32 new_bmcr;
+
+               bnx2_read_phy(bp, MII_BMCR, &bmcr);
+               new_bmcr = bmcr & ~BMCR_ANENABLE;
+               new_bmcr |= BMCR_SPEED1000;
+               if (bp->req_duplex == DUPLEX_FULL) {
+                       new_bmcr |= BMCR_FULLDPLX;
+               }
+               else {
+                       new_bmcr &= ~BMCR_FULLDPLX;
+               }
+               if (new_bmcr != bmcr) {
+                       /* Force a link down visible on the other side */
+                       if (bp->link_up) {
+                               bnx2_read_phy(bp, MII_ADVERTISE, &adv);
+                               adv &= ~(ADVERTISE_1000XFULL |
+                                       ADVERTISE_1000XHALF);
+                               bnx2_write_phy(bp, MII_ADVERTISE, adv);
+                               bnx2_write_phy(bp, MII_BMCR, bmcr |
+                                       BMCR_ANRESTART | BMCR_ANENABLE);
+
+                               bp->link_up = 0;
+                               netif_carrier_off(bp->dev);
+                       }
+                       bnx2_write_phy(bp, MII_BMCR, new_bmcr);
+               }
+               return 0;
+       }
+
+       if (bp->advertising & ADVERTISED_1000baseT_Full)
+               new_adv |= ADVERTISE_1000XFULL;
+
+       new_adv |= bnx2_phy_get_pause_adv(bp);
+
+       bnx2_read_phy(bp, MII_ADVERTISE, &adv);
+       bnx2_read_phy(bp, MII_BMCR, &bmcr);
+
+       bp->serdes_an_pending = 0;
+       if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) {
+               /* Force a link down visible on the other side */
+               if (bp->link_up) {
+                       int i;
+
+                       bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
+                       for (i = 0; i < 110; i++) {
+                               udelay(100);
+                       }
+               }
+
+               bnx2_write_phy(bp, MII_ADVERTISE, new_adv);
+               bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART |
+                       BMCR_ANENABLE);
+               bp->serdes_an_pending = SERDES_AN_TIMEOUT / bp->timer_interval;
+       }
+
+       return 0;
+}
+
+#define ETHTOOL_ALL_FIBRE_SPEED                                                \
+       (ADVERTISED_1000baseT_Full)
+
+#define ETHTOOL_ALL_COPPER_SPEED                                       \
+       (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |            \
+       ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |           \
+       ADVERTISED_1000baseT_Full)
+
+#define PHY_ALL_10_100_SPEED (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+       ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_CSMA)
+       
+#define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL)
+
+static int
+bnx2_setup_copper_phy(struct bnx2 *bp)
+{
+       u32 bmcr;
+       u32 new_bmcr;
+
+       bnx2_read_phy(bp, MII_BMCR, &bmcr);
+
+       if (bp->autoneg & AUTONEG_SPEED) {
+               u32 adv_reg, adv1000_reg;
+               u32 new_adv_reg = 0;
+               u32 new_adv1000_reg = 0;
+
+               bnx2_read_phy(bp, MII_ADVERTISE, &adv_reg);
+               adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP |
+                       ADVERTISE_PAUSE_ASYM);
+
+               bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg);
+               adv1000_reg &= PHY_ALL_1000_SPEED;
+
+               if (bp->advertising & ADVERTISED_10baseT_Half)
+                       new_adv_reg |= ADVERTISE_10HALF;
+               if (bp->advertising & ADVERTISED_10baseT_Full)
+                       new_adv_reg |= ADVERTISE_10FULL;
+               if (bp->advertising & ADVERTISED_100baseT_Half)
+                       new_adv_reg |= ADVERTISE_100HALF;
+               if (bp->advertising & ADVERTISED_100baseT_Full)
+                       new_adv_reg |= ADVERTISE_100FULL;
+               if (bp->advertising & ADVERTISED_1000baseT_Full)
+                       new_adv1000_reg |= ADVERTISE_1000FULL;
+               
+               new_adv_reg |= ADVERTISE_CSMA;
+
+               new_adv_reg |= bnx2_phy_get_pause_adv(bp);
+
+               if ((adv1000_reg != new_adv1000_reg) ||
+                       (adv_reg != new_adv_reg) ||
+                       ((bmcr & BMCR_ANENABLE) == 0)) {
+
+                       bnx2_write_phy(bp, MII_ADVERTISE, new_adv_reg);
+                       bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg);
+                       bnx2_write_phy(bp, MII_BMCR, BMCR_ANRESTART |
+                               BMCR_ANENABLE);
+               }
+               else if (bp->link_up) {
+                       /* Flow ctrl may have changed from auto to forced */
+                       /* or vice-versa. */
+
+                       bnx2_resolve_flow_ctrl(bp);
+                       bnx2_set_mac_link(bp);
+               }
+               return 0;
+       }
+
+       new_bmcr = 0;
+       if (bp->req_line_speed == SPEED_100) {
+               new_bmcr |= BMCR_SPEED100;
+       }
+       if (bp->req_duplex == DUPLEX_FULL) {
+               new_bmcr |= BMCR_FULLDPLX;
+       }
+       if (new_bmcr != bmcr) {
+               u32 bmsr;
+               int i = 0;
+
+               bnx2_read_phy(bp, MII_BMSR, &bmsr);
+               bnx2_read_phy(bp, MII_BMSR, &bmsr);
+               
+               if (bmsr & BMSR_LSTATUS) {
+                       /* Force link down */
+                       bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
+                       do {
+                               udelay(100);
+                               bnx2_read_phy(bp, MII_BMSR, &bmsr);
+                               bnx2_read_phy(bp, MII_BMSR, &bmsr);
+                               i++;
+                       } while ((bmsr & BMSR_LSTATUS) && (i < 620));
+               }
+
+               bnx2_write_phy(bp, MII_BMCR, new_bmcr);
+
+               /* Normally, the new speed is setup after the link has
+                * gone down and up again. In some cases, link will not go
+                * down so we need to set up the new speed here.
+                */
+               if (bmsr & BMSR_LSTATUS) {
+                       bp->line_speed = bp->req_line_speed;
+                       bp->duplex = bp->req_duplex;
+                       bnx2_resolve_flow_ctrl(bp);
+                       bnx2_set_mac_link(bp);
+               }
+       }
+       return 0;
+}
+
+static int
+bnx2_setup_phy(struct bnx2 *bp)
+{
+       if (bp->loopback == MAC_LOOPBACK)
+               return 0;
+
+       if (bp->phy_flags & PHY_SERDES_FLAG) {
+               return (bnx2_setup_serdes_phy(bp));
+       }
+       else {
+               return (bnx2_setup_copper_phy(bp));
+       }
+}
+
+static int
+bnx2_init_serdes_phy(struct bnx2 *bp)
+{
+       bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+
+       if (CHIP_NUM(bp) == CHIP_NUM_5706) {
+               REG_WR(bp, BNX2_MISC_UNUSED0, 0x300);
+       }
+
+       if (bp->dev->mtu > 1500) {
+               u32 val;
+
+               /* Set extended packet length bit */
+               bnx2_write_phy(bp, 0x18, 0x7);
+               bnx2_read_phy(bp, 0x18, &val);
+               bnx2_write_phy(bp, 0x18, (val & 0xfff8) | 0x4000);
+
+               bnx2_write_phy(bp, 0x1c, 0x6c00);
+               bnx2_read_phy(bp, 0x1c, &val);
+               bnx2_write_phy(bp, 0x1c, (val & 0x3ff) | 0xec02);
+       }
+       else {
+               u32 val;
+
+               bnx2_write_phy(bp, 0x18, 0x7);
+               bnx2_read_phy(bp, 0x18, &val);
+               bnx2_write_phy(bp, 0x18, val & ~0x4007);
+
+               bnx2_write_phy(bp, 0x1c, 0x6c00);
+               bnx2_read_phy(bp, 0x1c, &val);
+               bnx2_write_phy(bp, 0x1c, (val & 0x3fd) | 0xec00);
+       }
+
+       return 0;
+}
+
+static int
+bnx2_init_copper_phy(struct bnx2 *bp)
+{
+       bp->phy_flags |= PHY_CRC_FIX_FLAG;
+
+       if (bp->phy_flags & PHY_CRC_FIX_FLAG) {
+               bnx2_write_phy(bp, 0x18, 0x0c00);
+               bnx2_write_phy(bp, 0x17, 0x000a);
+               bnx2_write_phy(bp, 0x15, 0x310b);
+               bnx2_write_phy(bp, 0x17, 0x201f);
+               bnx2_write_phy(bp, 0x15, 0x9506);
+               bnx2_write_phy(bp, 0x17, 0x401f);
+               bnx2_write_phy(bp, 0x15, 0x14e2);
+               bnx2_write_phy(bp, 0x18, 0x0400);
+       }
+
+       if (bp->dev->mtu > 1500) {
+               u32 val;
+
+               /* Set extended packet length bit */
+               bnx2_write_phy(bp, 0x18, 0x7);
+               bnx2_read_phy(bp, 0x18, &val);
+               bnx2_write_phy(bp, 0x18, val | 0x4000);
+
+               bnx2_read_phy(bp, 0x10, &val);
+               bnx2_write_phy(bp, 0x10, val | 0x1);
+       }
+       else {
+               u32 val;
+
+               bnx2_write_phy(bp, 0x18, 0x7);
+               bnx2_read_phy(bp, 0x18, &val);
+               bnx2_write_phy(bp, 0x18, val & ~0x4007);
+
+               bnx2_read_phy(bp, 0x10, &val);
+               bnx2_write_phy(bp, 0x10, val & ~0x1);
+       }
+
+       return 0;
+}
+
+
+static int
+bnx2_init_phy(struct bnx2 *bp)
+{
+       u32 val;
+       int rc = 0;
+
+       bp->phy_flags &= ~PHY_INT_MODE_MASK_FLAG;
+       bp->phy_flags |= PHY_INT_MODE_LINK_READY_FLAG;
+
+        REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
+
+       bnx2_reset_phy(bp);
+
+       bnx2_read_phy(bp, MII_PHYSID1, &val);
+       bp->phy_id = val << 16;
+       bnx2_read_phy(bp, MII_PHYSID2, &val);
+       bp->phy_id |= val & 0xffff;
+
+       if (bp->phy_flags & PHY_SERDES_FLAG) {
+               rc = bnx2_init_serdes_phy(bp);
+       }
+       else {
+               rc = bnx2_init_copper_phy(bp);
+       }
+
+       bnx2_setup_phy(bp);
+
+       return rc;
+}
+
+static int
+bnx2_set_mac_loopback(struct bnx2 *bp)
+{
+       u32 mac_mode;
+
+       mac_mode = REG_RD(bp, BNX2_EMAC_MODE);
+       mac_mode &= ~BNX2_EMAC_MODE_PORT;
+       mac_mode |= BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK;
+       REG_WR(bp, BNX2_EMAC_MODE, mac_mode);
+       bp->link_up = 1;
+       return 0;
+}
+
+static int
+bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
+{
+       int i;
+       u32 val;
+
+       if (bp->fw_timed_out)
+               return -EBUSY;
+
+       bp->fw_wr_seq++;
+       msg_data |= bp->fw_wr_seq;
+
+       REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
+
+       /* wait for an acknowledgement. */
+       for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) {
+               udelay(5);
+
+               val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB);
+
+               if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
+                       break;
+       }
+
+       /* If we timed out, inform the firmware that this is the case. */
+       if (((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) &&
+               ((msg_data & BNX2_DRV_MSG_DATA) != BNX2_DRV_MSG_DATA_WAIT0)) {
+
+               msg_data &= ~BNX2_DRV_MSG_CODE;
+               msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
+
+               REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
+
+               bp->fw_timed_out = 1;
+
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static void
+bnx2_init_context(struct bnx2 *bp)
+{
+       u32 vcid;
+
+       vcid = 96;
+       while (vcid) {
+               u32 vcid_addr, pcid_addr, offset;
+
+               vcid--;
+
+               if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+                       u32 new_vcid;
+
+                       vcid_addr = GET_PCID_ADDR(vcid);
+                       if (vcid & 0x8) {
+                               new_vcid = 0x60 + (vcid & 0xf0) + (vcid & 0x7);
+                       }
+                       else {
+                               new_vcid = vcid;
+                       }
+                       pcid_addr = GET_PCID_ADDR(new_vcid);
+               }
+               else {
+                       vcid_addr = GET_CID_ADDR(vcid);
+                       pcid_addr = vcid_addr;
+               }
+
+               REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
+               REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+
+               /* Zero out the context. */
+               for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
+                       CTX_WR(bp, 0x00, offset, 0);
+               }
+
+               REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
+               REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+       }
+}
+
+static int
+bnx2_alloc_bad_rbuf(struct bnx2 *bp)
+{
+       u16 *good_mbuf;
+       u32 good_mbuf_cnt;
+       u32 val;
+
+       good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL);
+       if (good_mbuf == NULL) {
+               printk(KERN_ERR PFX "Failed to allocate memory in "
+                                   "bnx2_alloc_bad_rbuf\n");
+               return -ENOMEM;
+       }
+
+       REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
+               BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
+
+       good_mbuf_cnt = 0;
+
+       /* Allocate a bunch of mbufs and save the good ones in an array. */
+       val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
+       while (val & BNX2_RBUF_STATUS1_FREE_COUNT) {
+               REG_WR_IND(bp, BNX2_RBUF_COMMAND, BNX2_RBUF_COMMAND_ALLOC_REQ);
+
+               val = REG_RD_IND(bp, BNX2_RBUF_FW_BUF_ALLOC);
+
+               val &= BNX2_RBUF_FW_BUF_ALLOC_VALUE;
+
+               /* The addresses with Bit 9 set are bad memory blocks. */
+               if (!(val & (1 << 9))) {
+                       good_mbuf[good_mbuf_cnt] = (u16) val;
+                       good_mbuf_cnt++;
+               }
+
+               val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
+       }
+
+       /* Free the good ones back to the mbuf pool thus discarding
+        * all the bad ones. */
+       while (good_mbuf_cnt) {
+               good_mbuf_cnt--;
+
+               val = good_mbuf[good_mbuf_cnt];
+               val = (val << 9) | val | 1;
+
+               REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val);
+       }
+       kfree(good_mbuf);
+       return 0;
+}
+
+static void
+bnx2_set_mac_addr(struct bnx2 *bp) 
+{
+       u32 val;
+       u8 *mac_addr = bp->dev->dev_addr;
+
+       val = (mac_addr[0] << 8) | mac_addr[1];
+
+       REG_WR(bp, BNX2_EMAC_MAC_MATCH0, val);
+
+       val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | 
+               (mac_addr[4] << 8) | mac_addr[5];
+
+       REG_WR(bp, BNX2_EMAC_MAC_MATCH1, val);
+}
+
+static inline int
+bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
+{
+       struct sk_buff *skb;
+       struct sw_bd *rx_buf = &bp->rx_buf_ring[index];
+       dma_addr_t mapping;
+       struct rx_bd *rxbd = &bp->rx_desc_ring[index];
+       unsigned long align;
+
+       skb = dev_alloc_skb(bp->rx_buf_size);
+       if (skb == NULL) {
+               return -ENOMEM;
+       }
+
+       if (unlikely((align = (unsigned long) skb->data & 0x7))) {
+               skb_reserve(skb, 8 - align);
+       }
+
+       skb->dev = bp->dev;
+       mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
+               PCI_DMA_FROMDEVICE);
+
+       rx_buf->skb = skb;
+       pci_unmap_addr_set(rx_buf, mapping, mapping);
+
+       rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
+       rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
+
+       bp->rx_prod_bseq += bp->rx_buf_use_size;
+
+       return 0;
+}
+
+static void
+bnx2_phy_int(struct bnx2 *bp)
+{
+       u32 new_link_state, old_link_state;
+
+       new_link_state = bp->status_blk->status_attn_bits &
+               STATUS_ATTN_BITS_LINK_STATE;
+       old_link_state = bp->status_blk->status_attn_bits_ack &
+               STATUS_ATTN_BITS_LINK_STATE;
+       if (new_link_state != old_link_state) {
+               if (new_link_state) {
+                       REG_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD,
+                               STATUS_ATTN_BITS_LINK_STATE);
+               }
+               else {
+                       REG_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD,
+                               STATUS_ATTN_BITS_LINK_STATE);
+               }
+               bnx2_set_link(bp);
+       }
+}
+
+static void
+bnx2_tx_int(struct bnx2 *bp)
+{
+       u16 hw_cons, sw_cons, sw_ring_cons;
+       int tx_free_bd = 0;
+
+       hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
+       if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
+               hw_cons++;
+       }
+       sw_cons = bp->tx_cons;
+
+       while (sw_cons != hw_cons) {
+               struct sw_bd *tx_buf;
+               struct sk_buff *skb;
+               int i, last;
+
+               sw_ring_cons = TX_RING_IDX(sw_cons);
+
+               tx_buf = &bp->tx_buf_ring[sw_ring_cons];
+               skb = tx_buf->skb;
+#ifdef BCM_TSO 
+               /* partial BD completions possible with TSO packets */
+               if (skb_shinfo(skb)->tso_size) {
+                       u16 last_idx, last_ring_idx;
+
+                       last_idx = sw_cons +
+                               skb_shinfo(skb)->nr_frags + 1;
+                       last_ring_idx = sw_ring_cons +
+                               skb_shinfo(skb)->nr_frags + 1;
+                       if (unlikely(last_ring_idx >= MAX_TX_DESC_CNT)) {
+                               last_idx++;
+                       }
+                       if (((s16) ((s16) last_idx - (s16) hw_cons)) > 0) {
+                               break;
+                       }
+               }
+#endif
+               pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping),
+                       skb_headlen(skb), PCI_DMA_TODEVICE);
+
+               tx_buf->skb = NULL;
+               last = skb_shinfo(skb)->nr_frags;
+
+               for (i = 0; i < last; i++) {
+                       sw_cons = NEXT_TX_BD(sw_cons);
+
+                       pci_unmap_page(bp->pdev,
+                               pci_unmap_addr(
+                                       &bp->tx_buf_ring[TX_RING_IDX(sw_cons)],
+                                       mapping),
+                               skb_shinfo(skb)->frags[i].size,
+                               PCI_DMA_TODEVICE);
+               }
+
+               sw_cons = NEXT_TX_BD(sw_cons);
+
+               tx_free_bd += last + 1;
+
+               dev_kfree_skb_irq(skb);
+
+               hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
+               if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
+                       hw_cons++;
+               }
+       }
+
+       atomic_add(tx_free_bd, &bp->tx_avail_bd);
+
+       if (unlikely(netif_queue_stopped(bp->dev))) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&bp->tx_lock, flags);
+               if ((netif_queue_stopped(bp->dev)) &&
+                       (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS)) {
+
+                       netif_wake_queue(bp->dev);
+               }
+               spin_unlock_irqrestore(&bp->tx_lock, flags);
+       }
+
+       bp->tx_cons = sw_cons;
+
+}
+
+static inline void
+bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb,
+       u16 cons, u16 prod)
+{
+       struct sw_bd *cons_rx_buf = &bp->rx_buf_ring[cons];
+       struct sw_bd *prod_rx_buf = &bp->rx_buf_ring[prod];
+       struct rx_bd *cons_bd = &bp->rx_desc_ring[cons];
+       struct rx_bd *prod_bd = &bp->rx_desc_ring[prod];
+
+       pci_dma_sync_single_for_device(bp->pdev,
+               pci_unmap_addr(cons_rx_buf, mapping),
+               bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
+
+       prod_rx_buf->skb = cons_rx_buf->skb;
+       pci_unmap_addr_set(prod_rx_buf, mapping,
+                       pci_unmap_addr(cons_rx_buf, mapping));
+
+       memcpy(prod_bd, cons_bd, 8);
+
+       bp->rx_prod_bseq += bp->rx_buf_use_size;
+
+}
+
+static int
+bnx2_rx_int(struct bnx2 *bp, int budget)
+{
+       u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
+       struct l2_fhdr *rx_hdr;
+       int rx_pkt = 0;
+
+       hw_cons = bp->status_blk->status_rx_quick_consumer_index0;
+       if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) {
+               hw_cons++;
+       }
+       sw_cons = bp->rx_cons;
+       sw_prod = bp->rx_prod;
+
+       /* Memory barrier necessary as speculative reads of the rx
+        * buffer can be ahead of the index in the status block
+        */
+       rmb();
+       while (sw_cons != hw_cons) {
+               unsigned int len;
+               u16 status;
+               struct sw_bd *rx_buf;
+               struct sk_buff *skb;
+
+               sw_ring_cons = RX_RING_IDX(sw_cons);
+               sw_ring_prod = RX_RING_IDX(sw_prod);
+
+               rx_buf = &bp->rx_buf_ring[sw_ring_cons];
+               skb = rx_buf->skb;
+               pci_dma_sync_single_for_cpu(bp->pdev,
+                       pci_unmap_addr(rx_buf, mapping),
+                       bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
+
+               rx_hdr = (struct l2_fhdr *) skb->data;
+               len = rx_hdr->l2_fhdr_pkt_len - 4;
+
+               if (rx_hdr->l2_fhdr_errors &
+                       (L2_FHDR_ERRORS_BAD_CRC |
+                       L2_FHDR_ERRORS_PHY_DECODE |
+                       L2_FHDR_ERRORS_ALIGNMENT |
+                       L2_FHDR_ERRORS_TOO_SHORT |
+                       L2_FHDR_ERRORS_GIANT_FRAME)) {
+
+                       goto reuse_rx;
+               }
+
+               /* Since we don't have a jumbo ring, copy small packets
+                * if mtu > 1500
+                */
+               if ((bp->dev->mtu > 1500) && (len <= RX_COPY_THRESH)) {
+                       struct sk_buff *new_skb;
+
+                       new_skb = dev_alloc_skb(len + 2);
+                       if (new_skb == NULL)
+                               goto reuse_rx;
+
+                       /* aligned copy */
+                       memcpy(new_skb->data,
+                               skb->data + bp->rx_offset - 2,
+                               len + 2);
+
+                       skb_reserve(new_skb, 2);
+                       skb_put(new_skb, len);
+                       new_skb->dev = bp->dev;
+
+                       bnx2_reuse_rx_skb(bp, skb,
+                               sw_ring_cons, sw_ring_prod);
+
+                       skb = new_skb;
+               }
+               else if (bnx2_alloc_rx_skb(bp, sw_ring_prod) == 0) {
+                       pci_unmap_single(bp->pdev,
+                               pci_unmap_addr(rx_buf, mapping),
+                               bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
+
+                       skb_reserve(skb, bp->rx_offset);
+                       skb_put(skb, len);
+               }
+               else {
+reuse_rx:
+                       bnx2_reuse_rx_skb(bp, skb,
+                               sw_ring_cons, sw_ring_prod);
+                       goto next_rx;
+               }
+
+               skb->protocol = eth_type_trans(skb, bp->dev);
+
+               if ((len > (bp->dev->mtu + ETH_HLEN)) &&
+                       (htons(skb->protocol) != 0x8100)) {
+
+                       dev_kfree_skb_irq(skb);
+                       goto next_rx;
+
+               }
+
+               status = rx_hdr->l2_fhdr_status;
+               skb->ip_summed = CHECKSUM_NONE;
+               if (bp->rx_csum &&
+                       (status & (L2_FHDR_STATUS_TCP_SEGMENT |
+                       L2_FHDR_STATUS_UDP_DATAGRAM))) {
+
+                       u16 cksum = rx_hdr->l2_fhdr_tcp_udp_xsum;
+
+                       if (cksum == 0xffff)
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
+               }
+
+#ifdef BCM_VLAN
+               if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && (bp->vlgrp != 0)) {
+                       vlan_hwaccel_receive_skb(skb, bp->vlgrp,
+                               rx_hdr->l2_fhdr_vlan_tag);
+               }
+               else
+#endif
+                       netif_receive_skb(skb);
+
+               bp->dev->last_rx = jiffies;
+               rx_pkt++;
+
+next_rx:
+               rx_buf->skb = NULL;
+
+               sw_cons = NEXT_RX_BD(sw_cons);
+               sw_prod = NEXT_RX_BD(sw_prod);
+
+               if ((rx_pkt == budget))
+                       break;
+       }
+       bp->rx_cons = sw_cons;
+       bp->rx_prod = sw_prod;
+
+       REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, sw_prod);
+
+       REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
+
+       mmiowb();
+
+       return rx_pkt;
+
+}
+
+/* MSI ISR - The only difference between this and the INTx ISR
+ * is that the MSI interrupt is always serviced.
+ */
+static irqreturn_t
+bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs)
+{
+       struct net_device *dev = dev_instance;
+       struct bnx2 *bp = dev->priv;
+
+       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+               BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
+               BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
+
+       /* Return here if interrupt is disabled. */
+       if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
+               return IRQ_RETVAL(1);
+       }
+
+       if (netif_rx_schedule_prep(dev)) {
+               __netif_rx_schedule(dev);
+       }
+
+       return IRQ_RETVAL(1);
+}
+
+static irqreturn_t
+bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+       struct net_device *dev = dev_instance;
+       struct bnx2 *bp = dev->priv;
+
+       /* When using INTx, it is possible for the interrupt to arrive
+        * at the CPU before the status block posted prior to the
+        * interrupt. Reading a register will flush the status block.
+        * When using MSI, the MSI message will always complete after
+        * the status block write.
+        */
+       if ((bp->status_blk->status_idx == bp->last_status_idx) ||
+           (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
+            BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
+               return IRQ_RETVAL(0);
+
+       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+               BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
+               BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
+
+       /* Return here if interrupt is shared and is disabled. */
+       if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
+               return IRQ_RETVAL(1);
+       }
+
+       if (netif_rx_schedule_prep(dev)) {
+               __netif_rx_schedule(dev);
+       }
+
+       return IRQ_RETVAL(1);
+}
+
+static int
+bnx2_poll(struct net_device *dev, int *budget)
+{
+       struct bnx2 *bp = dev->priv;
+       int rx_done = 1;
+
+       bp->last_status_idx = bp->status_blk->status_idx;
+
+       rmb();
+       if ((bp->status_blk->status_attn_bits &
+               STATUS_ATTN_BITS_LINK_STATE) !=
+               (bp->status_blk->status_attn_bits_ack &
+               STATUS_ATTN_BITS_LINK_STATE)) {
+
+               unsigned long flags;
+
+               spin_lock_irqsave(&bp->phy_lock, flags);
+               bnx2_phy_int(bp);
+               spin_unlock_irqrestore(&bp->phy_lock, flags);
+       }
+
+       if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) {
+               bnx2_tx_int(bp);
+       }
+
+       if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) {
+               int orig_budget = *budget;
+               int work_done;
+
+               if (orig_budget > dev->quota)
+                       orig_budget = dev->quota;
+               
+               work_done = bnx2_rx_int(bp, orig_budget);
+               *budget -= work_done;
+               dev->quota -= work_done;
+               
+               if (work_done >= orig_budget) {
+                       rx_done = 0;
+               }
+       }
+       
+       if (rx_done) {
+               netif_rx_complete(dev);
+               REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+                       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+                       bp->last_status_idx);
+               return 0;
+       }
+
+       return 1;
+}
+
+/* Called with rtnl_lock from vlan functions and also dev->xmit_lock
+ * from set_multicast.
+ */
+static void
+bnx2_set_rx_mode(struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+       u32 rx_mode, sort_mode;
+       int i;
+       unsigned long flags;
+
+       spin_lock_irqsave(&bp->phy_lock, flags);
+
+       rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS |
+                                 BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
+       sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
+#ifdef BCM_VLAN
+       if (!bp->vlgrp) {
+               rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
+       }
+#else
+       rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
+#endif
+       if (dev->flags & IFF_PROMISC) {
+               /* Promiscuous mode. */
+               rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
+               sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN;
+       }
+       else if (dev->flags & IFF_ALLMULTI) {
+               for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
+                       REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
+                              0xffffffff);
+               }
+               sort_mode |= BNX2_RPM_SORT_USER0_MC_EN;
+       }
+       else {
+               /* Accept one or more multicast(s). */
+               struct dev_mc_list *mclist;
+               u32 mc_filter[NUM_MC_HASH_REGISTERS];
+               u32 regidx;
+               u32 bit;
+               u32 crc;
+
+               memset(mc_filter, 0, 4 * NUM_MC_HASH_REGISTERS);
+
+               for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+                    i++, mclist = mclist->next) {
+
+                       crc = ether_crc_le(ETH_ALEN, mclist->dmi_addr);
+                       bit = crc & 0xff;
+                       regidx = (bit & 0xe0) >> 5;
+                       bit &= 0x1f;
+                       mc_filter[regidx] |= (1 << bit);
+               }
+
+               for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
+                       REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
+                              mc_filter[i]);
+               }
+
+               sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
+       }
+
+       if (rx_mode != bp->rx_mode) {
+               bp->rx_mode = rx_mode;
+               REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode);
+       }
+
+       REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0);
+       REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode);
+       REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA);
+
+       spin_unlock_irqrestore(&bp->phy_lock, flags);
+}
+
+static void
+load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len,
+       u32 rv2p_proc)
+{
+       int i;
+       u32 val;
+
+
+       for (i = 0; i < rv2p_code_len; i += 8) {
+               REG_WR(bp, BNX2_RV2P_INSTR_HIGH, *rv2p_code);
+               rv2p_code++;
+               REG_WR(bp, BNX2_RV2P_INSTR_LOW, *rv2p_code);
+               rv2p_code++;
+
+               if (rv2p_proc == RV2P_PROC1) {
+                       val = (i / 8) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR;
+                       REG_WR(bp, BNX2_RV2P_PROC1_ADDR_CMD, val);
+               }
+               else {
+                       val = (i / 8) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR;
+                       REG_WR(bp, BNX2_RV2P_PROC2_ADDR_CMD, val);
+               }
+       }
+
+       /* Reset the processor, un-stall is done later. */
+       if (rv2p_proc == RV2P_PROC1) {
+               REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET);
+       }
+       else {
+               REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET);
+       }
+}
+
+static void
+load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
+{
+       u32 offset;
+       u32 val;
+
+       /* Halt the CPU. */
+       val = REG_RD_IND(bp, cpu_reg->mode);
+       val |= cpu_reg->mode_value_halt;
+       REG_WR_IND(bp, cpu_reg->mode, val);
+       REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
+
+       /* Load the Text area. */
+       offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
+       if (fw->text) {
+               int j;
+
+               for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
+                       REG_WR_IND(bp, offset, fw->text[j]);
+               }
+       }
+
+       /* Load the Data area. */
+       offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
+       if (fw->data) {
+               int j;
+
+               for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
+                       REG_WR_IND(bp, offset, fw->data[j]);
+               }
+       }
+
+       /* Load the SBSS area. */
+       offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
+       if (fw->sbss) {
+               int j;
+
+               for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
+                       REG_WR_IND(bp, offset, fw->sbss[j]);
+               }
+       }
+
+       /* Load the BSS area. */
+       offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
+       if (fw->bss) {
+               int j;
+
+               for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
+                       REG_WR_IND(bp, offset, fw->bss[j]);
+               }
+       }
+
+       /* Load the Read-Only area. */
+       offset = cpu_reg->spad_base +
+               (fw->rodata_addr - cpu_reg->mips_view_base);
+       if (fw->rodata) {
+               int j;
+
+               for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
+                       REG_WR_IND(bp, offset, fw->rodata[j]);
+               }
+       }
+
+       /* Clear the pre-fetch instruction. */
+       REG_WR_IND(bp, cpu_reg->inst, 0);
+       REG_WR_IND(bp, cpu_reg->pc, fw->start_addr);
+
+       /* Start the CPU. */
+       val = REG_RD_IND(bp, cpu_reg->mode);
+       val &= ~cpu_reg->mode_value_halt;
+       REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
+       REG_WR_IND(bp, cpu_reg->mode, val);
+}
+
+static void
+bnx2_init_cpus(struct bnx2 *bp)
+{
+       struct cpu_reg cpu_reg;
+       struct fw_info fw;
+
+       /* Initialize the RV2P processor. */
+       load_rv2p_fw(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), RV2P_PROC1);
+       load_rv2p_fw(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), RV2P_PROC2);
+
+       /* Initialize the RX Processor. */
+       cpu_reg.mode = BNX2_RXP_CPU_MODE;
+       cpu_reg.mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT;
+       cpu_reg.mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA;
+       cpu_reg.state = BNX2_RXP_CPU_STATE;
+       cpu_reg.state_value_clear = 0xffffff;
+       cpu_reg.gpr0 = BNX2_RXP_CPU_REG_FILE;
+       cpu_reg.evmask = BNX2_RXP_CPU_EVENT_MASK;
+       cpu_reg.pc = BNX2_RXP_CPU_PROGRAM_COUNTER;
+       cpu_reg.inst = BNX2_RXP_CPU_INSTRUCTION;
+       cpu_reg.bp = BNX2_RXP_CPU_HW_BREAKPOINT;
+       cpu_reg.spad_base = BNX2_RXP_SCRATCH;
+       cpu_reg.mips_view_base = 0x8000000;
+    
+       fw.ver_major = bnx2_RXP_b06FwReleaseMajor;
+       fw.ver_minor = bnx2_RXP_b06FwReleaseMinor;
+       fw.ver_fix = bnx2_RXP_b06FwReleaseFix;
+       fw.start_addr = bnx2_RXP_b06FwStartAddr;
+
+       fw.text_addr = bnx2_RXP_b06FwTextAddr;
+       fw.text_len = bnx2_RXP_b06FwTextLen;
+       fw.text_index = 0;
+       fw.text = bnx2_RXP_b06FwText;
+
+       fw.data_addr = bnx2_RXP_b06FwDataAddr;
+       fw.data_len = bnx2_RXP_b06FwDataLen;
+       fw.data_index = 0;
+       fw.data = bnx2_RXP_b06FwData;
+
+       fw.sbss_addr = bnx2_RXP_b06FwSbssAddr;
+       fw.sbss_len = bnx2_RXP_b06FwSbssLen;
+       fw.sbss_index = 0;
+       fw.sbss = bnx2_RXP_b06FwSbss;
+
+       fw.bss_addr = bnx2_RXP_b06FwBssAddr;
+       fw.bss_len = bnx2_RXP_b06FwBssLen;
+       fw.bss_index = 0;
+       fw.bss = bnx2_RXP_b06FwBss;
+
+       fw.rodata_addr = bnx2_RXP_b06FwRodataAddr;
+       fw.rodata_len = bnx2_RXP_b06FwRodataLen;
+       fw.rodata_index = 0;
+       fw.rodata = bnx2_RXP_b06FwRodata;
+
+       load_cpu_fw(bp, &cpu_reg, &fw);
+
+       /* Initialize the TX Processor. */
+       cpu_reg.mode = BNX2_TXP_CPU_MODE;
+       cpu_reg.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT;
+       cpu_reg.mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA;
+       cpu_reg.state = BNX2_TXP_CPU_STATE;
+       cpu_reg.state_value_clear = 0xffffff;
+       cpu_reg.gpr0 = BNX2_TXP_CPU_REG_FILE;
+       cpu_reg.evmask = BNX2_TXP_CPU_EVENT_MASK;
+       cpu_reg.pc = BNX2_TXP_CPU_PROGRAM_COUNTER;
+       cpu_reg.inst = BNX2_TXP_CPU_INSTRUCTION;
+       cpu_reg.bp = BNX2_TXP_CPU_HW_BREAKPOINT;
+       cpu_reg.spad_base = BNX2_TXP_SCRATCH;
+       cpu_reg.mips_view_base = 0x8000000;
+    
+       fw.ver_major = bnx2_TXP_b06FwReleaseMajor;
+       fw.ver_minor = bnx2_TXP_b06FwReleaseMinor;
+       fw.ver_fix = bnx2_TXP_b06FwReleaseFix;
+       fw.start_addr = bnx2_TXP_b06FwStartAddr;
+
+       fw.text_addr = bnx2_TXP_b06FwTextAddr;
+       fw.text_len = bnx2_TXP_b06FwTextLen;
+       fw.text_index = 0;
+       fw.text = bnx2_TXP_b06FwText;
+
+       fw.data_addr = bnx2_TXP_b06FwDataAddr;
+       fw.data_len = bnx2_TXP_b06FwDataLen;
+       fw.data_index = 0;
+       fw.data = bnx2_TXP_b06FwData;
+
+       fw.sbss_addr = bnx2_TXP_b06FwSbssAddr;
+       fw.sbss_len = bnx2_TXP_b06FwSbssLen;
+       fw.sbss_index = 0;
+       fw.sbss = bnx2_TXP_b06FwSbss;
+
+       fw.bss_addr = bnx2_TXP_b06FwBssAddr;
+       fw.bss_len = bnx2_TXP_b06FwBssLen;
+       fw.bss_index = 0;
+       fw.bss = bnx2_TXP_b06FwBss;
+
+       fw.rodata_addr = bnx2_TXP_b06FwRodataAddr;
+       fw.rodata_len = bnx2_TXP_b06FwRodataLen;
+       fw.rodata_index = 0;
+       fw.rodata = bnx2_TXP_b06FwRodata;
+
+       load_cpu_fw(bp, &cpu_reg, &fw);
+
+       /* Initialize the TX Patch-up Processor. */
+       cpu_reg.mode = BNX2_TPAT_CPU_MODE;
+       cpu_reg.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT;
+       cpu_reg.mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA;
+       cpu_reg.state = BNX2_TPAT_CPU_STATE;
+       cpu_reg.state_value_clear = 0xffffff;
+       cpu_reg.gpr0 = BNX2_TPAT_CPU_REG_FILE;
+       cpu_reg.evmask = BNX2_TPAT_CPU_EVENT_MASK;
+       cpu_reg.pc = BNX2_TPAT_CPU_PROGRAM_COUNTER;
+       cpu_reg.inst = BNX2_TPAT_CPU_INSTRUCTION;
+       cpu_reg.bp = BNX2_TPAT_CPU_HW_BREAKPOINT;
+       cpu_reg.spad_base = BNX2_TPAT_SCRATCH;
+       cpu_reg.mips_view_base = 0x8000000;
+    
+       fw.ver_major = bnx2_TPAT_b06FwReleaseMajor;
+       fw.ver_minor = bnx2_TPAT_b06FwReleaseMinor;
+       fw.ver_fix = bnx2_TPAT_b06FwReleaseFix;
+       fw.start_addr = bnx2_TPAT_b06FwStartAddr;
+
+       fw.text_addr = bnx2_TPAT_b06FwTextAddr;
+       fw.text_len = bnx2_TPAT_b06FwTextLen;
+       fw.text_index = 0;
+       fw.text = bnx2_TPAT_b06FwText;
+
+       fw.data_addr = bnx2_TPAT_b06FwDataAddr;
+       fw.data_len = bnx2_TPAT_b06FwDataLen;
+       fw.data_index = 0;
+       fw.data = bnx2_TPAT_b06FwData;
+
+       fw.sbss_addr = bnx2_TPAT_b06FwSbssAddr;
+       fw.sbss_len = bnx2_TPAT_b06FwSbssLen;
+       fw.sbss_index = 0;
+       fw.sbss = bnx2_TPAT_b06FwSbss;
+
+       fw.bss_addr = bnx2_TPAT_b06FwBssAddr;
+       fw.bss_len = bnx2_TPAT_b06FwBssLen;
+       fw.bss_index = 0;
+       fw.bss = bnx2_TPAT_b06FwBss;
+
+       fw.rodata_addr = bnx2_TPAT_b06FwRodataAddr;
+       fw.rodata_len = bnx2_TPAT_b06FwRodataLen;
+       fw.rodata_index = 0;
+       fw.rodata = bnx2_TPAT_b06FwRodata;
+
+       load_cpu_fw(bp, &cpu_reg, &fw);
+
+       /* Initialize the Completion Processor. */
+       cpu_reg.mode = BNX2_COM_CPU_MODE;
+       cpu_reg.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT;
+       cpu_reg.mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA;
+       cpu_reg.state = BNX2_COM_CPU_STATE;
+       cpu_reg.state_value_clear = 0xffffff;
+       cpu_reg.gpr0 = BNX2_COM_CPU_REG_FILE;
+       cpu_reg.evmask = BNX2_COM_CPU_EVENT_MASK;
+       cpu_reg.pc = BNX2_COM_CPU_PROGRAM_COUNTER;
+       cpu_reg.inst = BNX2_COM_CPU_INSTRUCTION;
+       cpu_reg.bp = BNX2_COM_CPU_HW_BREAKPOINT;
+       cpu_reg.spad_base = BNX2_COM_SCRATCH;
+       cpu_reg.mips_view_base = 0x8000000;
+    
+       fw.ver_major = bnx2_COM_b06FwReleaseMajor;
+       fw.ver_minor = bnx2_COM_b06FwReleaseMinor;
+       fw.ver_fix = bnx2_COM_b06FwReleaseFix;
+       fw.start_addr = bnx2_COM_b06FwStartAddr;
+
+       fw.text_addr = bnx2_COM_b06FwTextAddr;
+       fw.text_len = bnx2_COM_b06FwTextLen;
+       fw.text_index = 0;
+       fw.text = bnx2_COM_b06FwText;
+
+       fw.data_addr = bnx2_COM_b06FwDataAddr;
+       fw.data_len = bnx2_COM_b06FwDataLen;
+       fw.data_index = 0;
+       fw.data = bnx2_COM_b06FwData;
+
+       fw.sbss_addr = bnx2_COM_b06FwSbssAddr;
+       fw.sbss_len = bnx2_COM_b06FwSbssLen;
+       fw.sbss_index = 0;
+       fw.sbss = bnx2_COM_b06FwSbss;
+
+       fw.bss_addr = bnx2_COM_b06FwBssAddr;
+       fw.bss_len = bnx2_COM_b06FwBssLen;
+       fw.bss_index = 0;
+       fw.bss = bnx2_COM_b06FwBss;
+
+       fw.rodata_addr = bnx2_COM_b06FwRodataAddr;
+       fw.rodata_len = bnx2_COM_b06FwRodataLen;
+       fw.rodata_index = 0;
+       fw.rodata = bnx2_COM_b06FwRodata;
+
+       load_cpu_fw(bp, &cpu_reg, &fw);
+
+}
+
+static int
+bnx2_set_power_state(struct bnx2 *bp, int state)
+{
+       u16 pmcsr;
+
+       pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr);
+
+       switch (state) {
+       case 0: {
+               u32 val;
+
+               pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
+                       (pmcsr & ~PCI_PM_CTRL_STATE_MASK) |
+                       PCI_PM_CTRL_PME_STATUS);
+
+               if (pmcsr & PCI_PM_CTRL_STATE_MASK)
+                       /* delay required during transition out of D3hot */
+                       msleep(20);
+
+               val = REG_RD(bp, BNX2_EMAC_MODE);
+               val |= BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD;
+               val &= ~BNX2_EMAC_MODE_MPKT;
+               REG_WR(bp, BNX2_EMAC_MODE, val);
+
+               val = REG_RD(bp, BNX2_RPM_CONFIG);
+               val &= ~BNX2_RPM_CONFIG_ACPI_ENA;
+               REG_WR(bp, BNX2_RPM_CONFIG, val);
+               break;
+       }
+       case 3: {
+               int i;
+               u32 val, wol_msg;
+
+               if (bp->wol) {
+                       u32 advertising;
+                       u8 autoneg;
+
+                       autoneg = bp->autoneg;
+                       advertising = bp->advertising;
+
+                       bp->autoneg = AUTONEG_SPEED;
+                       bp->advertising = ADVERTISED_10baseT_Half |
+                               ADVERTISED_10baseT_Full |
+                               ADVERTISED_100baseT_Half |
+                               ADVERTISED_100baseT_Full |
+                               ADVERTISED_Autoneg;
+
+                       bnx2_setup_copper_phy(bp);
+
+                       bp->autoneg = autoneg;
+                       bp->advertising = advertising;
+
+                       bnx2_set_mac_addr(bp);
+
+                       val = REG_RD(bp, BNX2_EMAC_MODE);
+
+                       /* Enable port mode. */
+                       val &= ~BNX2_EMAC_MODE_PORT;
+                       val |= BNX2_EMAC_MODE_PORT_MII |
+                              BNX2_EMAC_MODE_MPKT_RCVD |
+                              BNX2_EMAC_MODE_ACPI_RCVD |
+                              BNX2_EMAC_MODE_FORCE_LINK |
+                              BNX2_EMAC_MODE_MPKT;
+
+                       REG_WR(bp, BNX2_EMAC_MODE, val);
+
+                       /* receive all multicast */
+                       for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
+                               REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
+                                      0xffffffff);
+                       }
+                       REG_WR(bp, BNX2_EMAC_RX_MODE,
+                              BNX2_EMAC_RX_MODE_SORT_MODE);
+
+                       val = 1 | BNX2_RPM_SORT_USER0_BC_EN |
+                             BNX2_RPM_SORT_USER0_MC_EN;
+                       REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0);
+                       REG_WR(bp, BNX2_RPM_SORT_USER0, val);
+                       REG_WR(bp, BNX2_RPM_SORT_USER0, val |
+                              BNX2_RPM_SORT_USER0_ENA);
+
+                       /* Need to enable EMAC and RPM for WOL. */
+                       REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
+                              BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE |
+                              BNX2_MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE |
+                              BNX2_MISC_ENABLE_SET_BITS_EMAC_ENABLE);
+
+                       val = REG_RD(bp, BNX2_RPM_CONFIG);
+                       val &= ~BNX2_RPM_CONFIG_ACPI_ENA;
+                       REG_WR(bp, BNX2_RPM_CONFIG, val);
+
+                       wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
+               }
+               else {
+                       wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
+               }
+
+               bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg);
+
+               pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+               if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
+                   (CHIP_ID(bp) == CHIP_ID_5706_A1)) {
+
+                       if (bp->wol)
+                               pmcsr |= 3;
+               }
+               else {
+                       pmcsr |= 3;
+               }
+               if (bp->wol) {
+                       pmcsr |= PCI_PM_CTRL_PME_ENABLE;
+               }
+               pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
+                                     pmcsr);
+
+               /* No more memory access after this point until
+                * device is brought back to D0.
+                */
+               udelay(50);
+               break;
+       }
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int
+bnx2_acquire_nvram_lock(struct bnx2 *bp)
+{
+       u32 val;
+       int j;
+
+       /* Request access to the flash interface. */
+       REG_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_SET2);
+       for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
+               val = REG_RD(bp, BNX2_NVM_SW_ARB);
+               if (val & BNX2_NVM_SW_ARB_ARB_ARB2)
+                       break;
+
+               udelay(5);
+       }
+
+       if (j >= NVRAM_TIMEOUT_COUNT)
+               return -EBUSY;
+
+       return 0;
+}
+
+static int
+bnx2_release_nvram_lock(struct bnx2 *bp)
+{
+       int j;
+       u32 val;
+
+       /* Relinquish nvram interface. */
+       REG_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_CLR2);
+
+       for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
+               val = REG_RD(bp, BNX2_NVM_SW_ARB);
+               if (!(val & BNX2_NVM_SW_ARB_ARB_ARB2))
+                       break;
+
+               udelay(5);
+       }
+
+       if (j >= NVRAM_TIMEOUT_COUNT)
+               return -EBUSY;
+
+       return 0;
+}
+
+
+static int
+bnx2_enable_nvram_write(struct bnx2 *bp)
+{
+       u32 val;
+
+       val = REG_RD(bp, BNX2_MISC_CFG);
+       REG_WR(bp, BNX2_MISC_CFG, val | BNX2_MISC_CFG_NVM_WR_EN_PCI);
+
+       if (!bp->flash_info->buffered) {
+               int j;
+
+               REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
+               REG_WR(bp, BNX2_NVM_COMMAND,
+                      BNX2_NVM_COMMAND_WREN | BNX2_NVM_COMMAND_DOIT);
+
+               for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
+                       udelay(5);
+
+                       val = REG_RD(bp, BNX2_NVM_COMMAND);
+                       if (val & BNX2_NVM_COMMAND_DONE)
+                               break;
+               }
+
+               if (j >= NVRAM_TIMEOUT_COUNT)
+                       return -EBUSY;
+       }
+       return 0;
+}
+
+static void
+bnx2_disable_nvram_write(struct bnx2 *bp)
+{
+       u32 val;
+
+       val = REG_RD(bp, BNX2_MISC_CFG);
+       REG_WR(bp, BNX2_MISC_CFG, val & ~BNX2_MISC_CFG_NVM_WR_EN);
+}
+
+
+static void
+bnx2_enable_nvram_access(struct bnx2 *bp)
+{
+       u32 val;
+
+       val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
+       /* Enable both bits, even on read. */
+       REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, 
+              val | BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN);
+}
+
+static void
+bnx2_disable_nvram_access(struct bnx2 *bp)
+{
+       u32 val;
+
+       val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
+       /* Disable both bits, even after read. */
+       REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, 
+               val & ~(BNX2_NVM_ACCESS_ENABLE_EN |
+                       BNX2_NVM_ACCESS_ENABLE_WR_EN));
+}
+
+static int
+bnx2_nvram_erase_page(struct bnx2 *bp, u32 offset)
+{
+       u32 cmd;
+       int j;
+
+       if (bp->flash_info->buffered)
+               /* Buffered flash, no erase needed */
+               return 0;
+
+       /* Build an erase command */
+       cmd = BNX2_NVM_COMMAND_ERASE | BNX2_NVM_COMMAND_WR |
+             BNX2_NVM_COMMAND_DOIT;
+
+       /* Need to clear DONE bit separately. */
+       REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
+
+       /* Address of the NVRAM to read from. */
+       REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
+
+       /* Issue an erase command. */
+       REG_WR(bp, BNX2_NVM_COMMAND, cmd);
+
+       /* Wait for completion. */
+       for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
+               u32 val;
+
+               udelay(5);
+
+               val = REG_RD(bp, BNX2_NVM_COMMAND);
+               if (val & BNX2_NVM_COMMAND_DONE)
+                       break;
+       }
+
+       if (j >= NVRAM_TIMEOUT_COUNT)
+               return -EBUSY;
+
+       return 0;
+}
+
+static int
+bnx2_nvram_read_dword(struct bnx2 *bp, u32 offset, u8 *ret_val, u32 cmd_flags)
+{
+       u32 cmd;
+       int j;
+
+       /* Build the command word. */
+       cmd = BNX2_NVM_COMMAND_DOIT | cmd_flags;
+
+       /* Calculate an offset of a buffered flash. */
+       if (bp->flash_info->buffered) {
+               offset = ((offset / bp->flash_info->page_size) <<
+                          bp->flash_info->page_bits) +
+                         (offset % bp->flash_info->page_size);
+       }
+
+       /* Need to clear DONE bit separately. */
+       REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
+
+       /* Address of the NVRAM to read from. */
+       REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
+
+       /* Issue a read command. */
+       REG_WR(bp, BNX2_NVM_COMMAND, cmd);
+
+       /* Wait for completion. */
+       for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
+               u32 val;
+
+               udelay(5);
+
+               val = REG_RD(bp, BNX2_NVM_COMMAND);
+               if (val & BNX2_NVM_COMMAND_DONE) {
+                       val = REG_RD(bp, BNX2_NVM_READ);
+
+                       val = be32_to_cpu(val);
+                       memcpy(ret_val, &val, 4);
+                       break;
+               }
+       }
+       if (j >= NVRAM_TIMEOUT_COUNT)
+               return -EBUSY;
+
+       return 0;
+}
+
+
+static int
+bnx2_nvram_write_dword(struct bnx2 *bp, u32 offset, u8 *val, u32 cmd_flags)
+{
+       u32 cmd, val32;
+       int j;
+
+       /* Build the command word. */
+       cmd = BNX2_NVM_COMMAND_DOIT | BNX2_NVM_COMMAND_WR | cmd_flags;
+
+       /* Calculate an offset of a buffered flash. */
+       if (bp->flash_info->buffered) {
+               offset = ((offset / bp->flash_info->page_size) <<
+                         bp->flash_info->page_bits) +
+                        (offset % bp->flash_info->page_size);
+       }
+
+       /* Need to clear DONE bit separately. */
+       REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
+
+       memcpy(&val32, val, 4);
+       val32 = cpu_to_be32(val32);
+
+       /* Write the data. */
+       REG_WR(bp, BNX2_NVM_WRITE, val32);
+
+       /* Address of the NVRAM to write to. */
+       REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
+
+       /* Issue the write command. */
+       REG_WR(bp, BNX2_NVM_COMMAND, cmd);
+
+       /* Wait for completion. */
+       for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
+               udelay(5);
+
+               if (REG_RD(bp, BNX2_NVM_COMMAND) & BNX2_NVM_COMMAND_DONE)
+                       break;
+       }
+       if (j >= NVRAM_TIMEOUT_COUNT)
+               return -EBUSY;
+
+       return 0;
+}
+
+static int
+bnx2_init_nvram(struct bnx2 *bp)
+{
+       u32 val;
+       int j, entry_count, rc;
+       struct flash_spec *flash;
+
+       /* Determine the selected interface. */
+       val = REG_RD(bp, BNX2_NVM_CFG1);
+
+       entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
+
+       rc = 0;
+       if (val & 0x40000000) {
+
+               /* Flash interface has been reconfigured */
+               for (j = 0, flash = &flash_table[0]; j < entry_count;
+                       j++, flash++) {
+
+                       if (val == flash->config1) {
+                               bp->flash_info = flash;
+                               break;
+                       }
+               }
+       }
+       else {
+               /* Not yet been reconfigured */
+
+               for (j = 0, flash = &flash_table[0]; j < entry_count;
+                       j++, flash++) {
+
+                       if ((val & FLASH_STRAP_MASK) == flash->strapping) {
+                               bp->flash_info = flash;
+
+                               /* Request access to the flash interface. */
+                               if ((rc = bnx2_acquire_nvram_lock(bp)) != 0)
+                                       return rc;
+
+                               /* Enable access to flash interface */
+                               bnx2_enable_nvram_access(bp);
+
+                               /* Reconfigure the flash interface */
+                               REG_WR(bp, BNX2_NVM_CFG1, flash->config1);
+                               REG_WR(bp, BNX2_NVM_CFG2, flash->config2);
+                               REG_WR(bp, BNX2_NVM_CFG3, flash->config3);
+                               REG_WR(bp, BNX2_NVM_WRITE1, flash->write1);
+
+                               /* Disable access to flash interface */
+                               bnx2_disable_nvram_access(bp);
+                               bnx2_release_nvram_lock(bp);
+
+                               break;
+                       }
+               }
+       } /* if (val & 0x40000000) */
+
+       if (j == entry_count) {
+               bp->flash_info = NULL;
+               printk(KERN_ALERT "Unknown flash/EEPROM type.\n");
+               rc = -ENODEV;
+       }
+
+       return rc;
+}
+
+static int
+bnx2_nvram_read(struct bnx2 *bp, u32 offset, u8 *ret_buf,
+               int buf_size)
+{
+       int rc = 0;
+       u32 cmd_flags, offset32, len32, extra;
+
+       if (buf_size == 0)
+               return 0;
+
+       /* Request access to the flash interface. */
+       if ((rc = bnx2_acquire_nvram_lock(bp)) != 0)
+               return rc;
+
+       /* Enable access to flash interface */
+       bnx2_enable_nvram_access(bp);
+
+       len32 = buf_size;
+       offset32 = offset;
+       extra = 0;
+
+       cmd_flags = 0;
+
+       if (offset32 & 3) {
+               u8 buf[4];
+               u32 pre_len;
+
+               offset32 &= ~3;
+               pre_len = 4 - (offset & 3);
+
+               if (pre_len >= len32) {
+                       pre_len = len32;
+                       cmd_flags = BNX2_NVM_COMMAND_FIRST |
+                                   BNX2_NVM_COMMAND_LAST;
+               }
+               else {
+                       cmd_flags = BNX2_NVM_COMMAND_FIRST;
+               }
+
+               rc = bnx2_nvram_read_dword(bp, offset32, buf, cmd_flags);
+
+               if (rc)
+                       return rc;
+
+               memcpy(ret_buf, buf + (offset & 3), pre_len);
+
+               offset32 += 4;
+               ret_buf += pre_len;
+               len32 -= pre_len;
+       }
+       if (len32 & 3) {
+               extra = 4 - (len32 & 3);
+               len32 = (len32 + 4) & ~3;
+       }
+
+       if (len32 == 4) {
+               u8 buf[4];
+
+               if (cmd_flags)
+                       cmd_flags = BNX2_NVM_COMMAND_LAST;
+               else
+                       cmd_flags = BNX2_NVM_COMMAND_FIRST |
+                                   BNX2_NVM_COMMAND_LAST;
+
+               rc = bnx2_nvram_read_dword(bp, offset32, buf, cmd_flags);
+
+               memcpy(ret_buf, buf, 4 - extra);
+       }
+       else if (len32 > 0) {
+               u8 buf[4];
+
+               /* Read the first word. */
+               if (cmd_flags)
+                       cmd_flags = 0;
+               else
+                       cmd_flags = BNX2_NVM_COMMAND_FIRST;
+
+               rc = bnx2_nvram_read_dword(bp, offset32, ret_buf, cmd_flags);
+
+               /* Advance to the next dword. */
+               offset32 += 4;
+               ret_buf += 4;
+               len32 -= 4;
+
+               while (len32 > 4 && rc == 0) {
+                       rc = bnx2_nvram_read_dword(bp, offset32, ret_buf, 0);
+
+                       /* Advance to the next dword. */
+                       offset32 += 4;
+                       ret_buf += 4;
+                       len32 -= 4;
+               }
+
+               if (rc)
+                       return rc;
+
+               cmd_flags = BNX2_NVM_COMMAND_LAST;
+               rc = bnx2_nvram_read_dword(bp, offset32, buf, cmd_flags);
+
+               memcpy(ret_buf, buf, 4 - extra);
+       }
+
+       /* Disable access to flash interface */
+       bnx2_disable_nvram_access(bp);
+
+       bnx2_release_nvram_lock(bp);
+
+       return rc;
+}
+
+static int
+bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
+               int buf_size)
+{
+       u32 written, offset32, len32;
+       u8 *buf, start[4], end[4];
+       int rc = 0;
+       int align_start, align_end;
+
+       buf = data_buf;
+       offset32 = offset;
+       len32 = buf_size;
+       align_start = align_end = 0;
+
+       if ((align_start = (offset32 & 3))) {
+               offset32 &= ~3;
+               len32 += align_start;
+               if ((rc = bnx2_nvram_read(bp, offset32, start, 4)))
+                       return rc;
+       }
+
+       if (len32 & 3) {
+               if ((len32 > 4) || !align_start) {
+                       align_end = 4 - (len32 & 3);
+                       len32 += align_end;
+                       if ((rc = bnx2_nvram_read(bp, offset32 + len32 - 4,
+                               end, 4))) {
+                               return rc;
+                       }
+               }
+       }
+
+       if (align_start || align_end) {
+               buf = kmalloc(len32, GFP_KERNEL);
+               if (buf == 0)
+                       return -ENOMEM;
+               if (align_start) {
+                       memcpy(buf, start, 4);
+               }
+               if (align_end) {
+                       memcpy(buf + len32 - 4, end, 4);
+               }
+               memcpy(buf + align_start, data_buf, buf_size);
+       }
+
+       written = 0;
+       while ((written < len32) && (rc == 0)) {
+               u32 page_start, page_end, data_start, data_end;
+               u32 addr, cmd_flags;
+               int i;
+               u8 flash_buffer[264];
+
+               /* Find the page_start addr */
+               page_start = offset32 + written;
+               page_start -= (page_start % bp->flash_info->page_size);
+               /* Find the page_end addr */
+               page_end = page_start + bp->flash_info->page_size;
+               /* Find the data_start addr */
+               data_start = (written == 0) ? offset32 : page_start;
+               /* Find the data_end addr */
+               data_end = (page_end > offset32 + len32) ? 
+                       (offset32 + len32) : page_end;
+
+               /* Request access to the flash interface. */
+               if ((rc = bnx2_acquire_nvram_lock(bp)) != 0)
+                       goto nvram_write_end;
+
+               /* Enable access to flash interface */
+               bnx2_enable_nvram_access(bp);
+
+               cmd_flags = BNX2_NVM_COMMAND_FIRST;
+               if (bp->flash_info->buffered == 0) {
+                       int j;
+
+                       /* Read the whole page into the buffer
+                        * (non-buffer flash only) */
+                       for (j = 0; j < bp->flash_info->page_size; j += 4) {
+                               if (j == (bp->flash_info->page_size - 4)) {
+                                       cmd_flags |= BNX2_NVM_COMMAND_LAST;
+                               }
+                               rc = bnx2_nvram_read_dword(bp,
+                                       page_start + j, 
+                                       &flash_buffer[j], 
+                                       cmd_flags);
+
+                               if (rc)
+                                       goto nvram_write_end;
+
+                               cmd_flags = 0;
+                       }
+               }
+
+               /* Enable writes to flash interface (unlock write-protect) */
+               if ((rc = bnx2_enable_nvram_write(bp)) != 0)
+                       goto nvram_write_end;
+
+               /* Erase the page */
+               if ((rc = bnx2_nvram_erase_page(bp, page_start)) != 0)
+                       goto nvram_write_end;
+
+               /* Re-enable the write again for the actual write */
+               bnx2_enable_nvram_write(bp);
+
+               /* Loop to write back the buffer data from page_start to
+                * data_start */
+               i = 0;
+               if (bp->flash_info->buffered == 0) {
+                       for (addr = page_start; addr < data_start;
+                               addr += 4, i += 4) {
+                               
+                               rc = bnx2_nvram_write_dword(bp, addr,
+                                       &flash_buffer[i], cmd_flags);
+
+                               if (rc != 0)
+                                       goto nvram_write_end;
+
+                               cmd_flags = 0;
+                       }
+               }
+
+               /* Loop to write the new data from data_start to data_end */
+               for (addr = data_start; addr < data_end; addr += 4, i++) {
+                       if ((addr == page_end - 4) ||
+                               ((bp->flash_info->buffered) &&
+                                (addr == data_end - 4))) {
+
+                               cmd_flags |= BNX2_NVM_COMMAND_LAST;
+                       }
+                       rc = bnx2_nvram_write_dword(bp, addr, buf,
+                               cmd_flags);
+
+                       if (rc != 0)
+                               goto nvram_write_end;
+
+                       cmd_flags = 0;
+                       buf += 4;
+               }
+
+               /* Loop to write back the buffer data from data_end
+                * to page_end */
+               if (bp->flash_info->buffered == 0) {
+                       for (addr = data_end; addr < page_end;
+                               addr += 4, i += 4) {
+                       
+                               if (addr == page_end-4) {
+                                       cmd_flags = BNX2_NVM_COMMAND_LAST;
+                               }
+                               rc = bnx2_nvram_write_dword(bp, addr,
+                                       &flash_buffer[i], cmd_flags);
+
+                               if (rc != 0)
+                                       goto nvram_write_end;
+
+                               cmd_flags = 0;
+                       }
+               }
+
+               /* Disable writes to flash interface (lock write-protect) */
+               bnx2_disable_nvram_write(bp);
+
+               /* Disable access to flash interface */
+               bnx2_disable_nvram_access(bp);
+               bnx2_release_nvram_lock(bp);
+
+               /* Increment written */
+               written += data_end - data_start;
+       }
+
+nvram_write_end:
+       if (align_start || align_end)
+               kfree(buf);
+       return rc;
+}
+
+static int
+bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
+{
+       u32 val;
+       int i, rc = 0;
+
+       /* Wait for the current PCI transaction to complete before
+        * issuing a reset. */
+       REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
+              BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
+              BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
+              BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
+              BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
+       val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
+       udelay(5);
+
+       /* Deposit a driver reset signature so the firmware knows that
+        * this is a soft reset. */
+       REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE,
+                  BNX2_DRV_RESET_SIGNATURE_MAGIC);
+
+       bp->fw_timed_out = 0;
+
+       /* Wait for the firmware to tell us it is ok to issue a reset. */
+       bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code);
+
+       /* Do a dummy read to force the chip to complete all current transaction
+        * before we issue a reset. */
+       val = REG_RD(bp, BNX2_MISC_ID);
+
+       val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
+             BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+             BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
+
+       /* Chip reset. */
+       REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
+
+       if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
+           (CHIP_ID(bp) == CHIP_ID_5706_A1))
+               msleep(15);
+
+       /* Reset takes approximate 30 usec */
+       for (i = 0; i < 10; i++) {
+               val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG);
+               if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
+                           BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
+                       break;
+               }
+               udelay(10);
+       }
+
+       if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
+                  BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
+               printk(KERN_ERR PFX "Chip reset did not complete\n");
+               return -EBUSY;
+       }
+
+       /* Make sure byte swapping is properly configured. */
+       val = REG_RD(bp, BNX2_PCI_SWAP_DIAG0);
+       if (val != 0x01020304) {
+               printk(KERN_ERR PFX "Chip not in correct endian mode\n");
+               return -ENODEV;
+       }
+
+       bp->fw_timed_out = 0;
+
+       /* Wait for the firmware to finish its initialization. */
+       bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code);
+
+       if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+               /* Adjust the voltage regular to two steps lower.  The default
+                * of this register is 0x0000000e. */
+               REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa);
+
+               /* Remove bad rbuf memory from the free pool. */
+               rc = bnx2_alloc_bad_rbuf(bp);
+       }
+
+       return rc;
+}
+
+static int
+bnx2_init_chip(struct bnx2 *bp)
+{
+       u32 val;
+
+       /* Make sure the interrupt is not active. */
+       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
+
+       val = BNX2_DMA_CONFIG_DATA_BYTE_SWAP |
+             BNX2_DMA_CONFIG_DATA_WORD_SWAP |
+#ifdef __BIG_ENDIAN
+             BNX2_DMA_CONFIG_CNTL_BYTE_SWAP | 
+#endif
+             BNX2_DMA_CONFIG_CNTL_WORD_SWAP | 
+             DMA_READ_CHANS << 12 |
+             DMA_WRITE_CHANS << 16;
+
+       val |= (0x2 << 20) | (1 << 11);
+
+       if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz = 133))
+               val |= (1 << 23);
+
+       if ((CHIP_NUM(bp) == CHIP_NUM_5706) &&
+           (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & PCIX_FLAG))
+               val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA;
+
+       REG_WR(bp, BNX2_DMA_CONFIG, val);
+
+       if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+               val = REG_RD(bp, BNX2_TDMA_CONFIG);
+               val |= BNX2_TDMA_CONFIG_ONE_DMA;
+               REG_WR(bp, BNX2_TDMA_CONFIG, val);
+       }
+
+       if (bp->flags & PCIX_FLAG) {
+               u16 val16;
+
+               pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
+                                    &val16);
+               pci_write_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
+                                     val16 & ~PCI_X_CMD_ERO);
+       }
+
+       REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
+              BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
+              BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
+              BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
+
+       /* Initialize context mapping and zero out the quick contexts.  The
+        * context block must have already been enabled. */
+       bnx2_init_context(bp);
+
+       bnx2_init_cpus(bp);
+       bnx2_init_nvram(bp);
+
+       bnx2_set_mac_addr(bp);
+
+       val = REG_RD(bp, BNX2_MQ_CONFIG);
+       val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE;
+       val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
+       REG_WR(bp, BNX2_MQ_CONFIG, val);
+
+       val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
+       REG_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val);
+       REG_WR(bp, BNX2_MQ_KNL_WIND_END, val);
+
+       val = (BCM_PAGE_BITS - 8) << 24;
+       REG_WR(bp, BNX2_RV2P_CONFIG, val);
+
+       /* Configure page size. */
+       val = REG_RD(bp, BNX2_TBDR_CONFIG);
+       val &= ~BNX2_TBDR_CONFIG_PAGE_SIZE;
+       val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
+       REG_WR(bp, BNX2_TBDR_CONFIG, val);
+
+       val = bp->mac_addr[0] +
+             (bp->mac_addr[1] << 8) +
+             (bp->mac_addr[2] << 16) +
+             bp->mac_addr[3] +
+             (bp->mac_addr[4] << 8) +
+             (bp->mac_addr[5] << 16);
+       REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val);
+
+       /* Program the MTU.  Also include 4 bytes for CRC32. */
+       val = bp->dev->mtu + ETH_HLEN + 4;
+       if (val > (MAX_ETHERNET_PACKET_SIZE + 4))
+               val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA;
+       REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
+
+       bp->last_status_idx = 0;
+       bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
+
+       /* Set up how to generate a link change interrupt. */
+       REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
+
+       REG_WR(bp, BNX2_HC_STATUS_ADDR_L,
+              (u64) bp->status_blk_mapping & 0xffffffff);
+       REG_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32);
+
+       REG_WR(bp, BNX2_HC_STATISTICS_ADDR_L,
+              (u64) bp->stats_blk_mapping & 0xffffffff);
+       REG_WR(bp, BNX2_HC_STATISTICS_ADDR_H,
+              (u64) bp->stats_blk_mapping >> 32);
+
+       REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP, 
+              (bp->tx_quick_cons_trip_int << 16) | bp->tx_quick_cons_trip);
+
+       REG_WR(bp, BNX2_HC_RX_QUICK_CONS_TRIP,
+              (bp->rx_quick_cons_trip_int << 16) | bp->rx_quick_cons_trip);
+
+       REG_WR(bp, BNX2_HC_COMP_PROD_TRIP,
+              (bp->comp_prod_trip_int << 16) | bp->comp_prod_trip);
+
+       REG_WR(bp, BNX2_HC_TX_TICKS, (bp->tx_ticks_int << 16) | bp->tx_ticks);
+
+       REG_WR(bp, BNX2_HC_RX_TICKS, (bp->rx_ticks_int << 16) | bp->rx_ticks);
+
+       REG_WR(bp, BNX2_HC_COM_TICKS,
+              (bp->com_ticks_int << 16) | bp->com_ticks);
+
+       REG_WR(bp, BNX2_HC_CMD_TICKS,
+              (bp->cmd_ticks_int << 16) | bp->cmd_ticks);
+
+       REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
+       REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
+
+       if (CHIP_ID(bp) == CHIP_ID_5706_A1)
+               REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS);
+       else {
+               REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_RX_TMR_MODE |
+                      BNX2_HC_CONFIG_TX_TMR_MODE |
+                      BNX2_HC_CONFIG_COLLECT_STATS);
+       }
+
+       /* Clear internal stats counters. */
+       REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW);
+
+       REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
+
+       /* Initialize the receive filter. */
+       bnx2_set_rx_mode(bp->dev);
+
+       bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET);
+
+       REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff);
+       REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
+
+       udelay(20);
+
+       return 0;
+}
+
+
+static void
+bnx2_init_tx_ring(struct bnx2 *bp)
+{
+       struct tx_bd *txbd;
+       u32 val;
+
+       txbd = &bp->tx_desc_ring[MAX_TX_DESC_CNT];
+               
+       txbd->tx_bd_haddr_hi = (u64) bp->tx_desc_mapping >> 32;
+       txbd->tx_bd_haddr_lo = (u64) bp->tx_desc_mapping & 0xffffffff;
+
+       bp->tx_prod = 0;
+       bp->tx_cons = 0;
+       bp->tx_prod_bseq = 0;
+       atomic_set(&bp->tx_avail_bd, bp->tx_ring_size);
+       
+       val = BNX2_L2CTX_TYPE_TYPE_L2;
+       val |= BNX2_L2CTX_TYPE_SIZE_L2;
+       CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val);
+
+       val = BNX2_L2CTX_CMD_TYPE_TYPE_L2;
+       val |= 8 << 16;
+       CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val);
+
+       val = (u64) bp->tx_desc_mapping >> 32;
+       CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, val);
+
+       val = (u64) bp->tx_desc_mapping & 0xffffffff;
+       CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val);
+}
+
+static void
+bnx2_init_rx_ring(struct bnx2 *bp)
+{
+       struct rx_bd *rxbd;
+       int i;
+       u16 prod, ring_prod; 
+       u32 val;
+
+       /* 8 for CRC and VLAN */
+       bp->rx_buf_use_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8;
+       /* 8 for alignment */
+       bp->rx_buf_size = bp->rx_buf_use_size + 8;
+
+       ring_prod = prod = bp->rx_prod = 0;
+       bp->rx_cons = 0;
+       bp->rx_prod_bseq = 0;
+               
+       rxbd = &bp->rx_desc_ring[0];
+       for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) {
+               rxbd->rx_bd_len = bp->rx_buf_use_size;
+               rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
+       }
+
+       rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping >> 32;
+       rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff;
+
+       val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
+       val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
+       val |= 0x02 << 8;
+       CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val);
+
+       val = (u64) bp->rx_desc_mapping >> 32;
+       CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, val);
+
+       val = (u64) bp->rx_desc_mapping & 0xffffffff;
+       CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val);
+
+       for ( ;ring_prod < bp->rx_ring_size; ) {
+               if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) {
+                       break;
+               }
+               prod = NEXT_RX_BD(prod);
+               ring_prod = RX_RING_IDX(prod);
+       }
+       bp->rx_prod = prod;
+
+       REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, prod);
+
+       REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
+}
+
+static void
+bnx2_free_tx_skbs(struct bnx2 *bp)
+{
+       int i;
+
+       if (bp->tx_buf_ring == NULL)
+               return;
+
+       for (i = 0; i < TX_DESC_CNT; ) {
+               struct sw_bd *tx_buf = &bp->tx_buf_ring[i];
+               struct sk_buff *skb = tx_buf->skb;
+               int j, last;
+
+               if (skb == NULL) {
+                       i++;
+                       continue;
+               }
+
+               pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping),
+                       skb_headlen(skb), PCI_DMA_TODEVICE);
+
+               tx_buf->skb = NULL;
+
+               last = skb_shinfo(skb)->nr_frags;
+               for (j = 0; j < last; j++) {
+                       tx_buf = &bp->tx_buf_ring[i + j + 1];
+                       pci_unmap_page(bp->pdev,
+                               pci_unmap_addr(tx_buf, mapping),
+                               skb_shinfo(skb)->frags[j].size,
+                               PCI_DMA_TODEVICE);
+               }
+               dev_kfree_skb_any(skb);
+               i += j + 1;
+       }
+
+}
+
+static void
+bnx2_free_rx_skbs(struct bnx2 *bp)
+{
+       int i;
+
+       if (bp->rx_buf_ring == NULL)
+               return;
+
+       for (i = 0; i < RX_DESC_CNT; i++) {
+               struct sw_bd *rx_buf = &bp->rx_buf_ring[i];
+               struct sk_buff *skb = rx_buf->skb;
+
+               if (skb == 0)
+                       continue;
+
+               pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
+                       bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
+
+               rx_buf->skb = NULL;
+
+               dev_kfree_skb_any(skb);
+       }
+}
+
+static void
+bnx2_free_skbs(struct bnx2 *bp)
+{
+       bnx2_free_tx_skbs(bp);
+       bnx2_free_rx_skbs(bp);
+}
+
+static int
+bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
+{
+       int rc;
+
+       rc = bnx2_reset_chip(bp, reset_code);
+       bnx2_free_skbs(bp);
+       if (rc)
+               return rc;
+
+       bnx2_init_chip(bp);
+       bnx2_init_tx_ring(bp);
+       bnx2_init_rx_ring(bp);
+       return 0;
+}
+
+static int
+bnx2_init_nic(struct bnx2 *bp)
+{
+       int rc;
+
+       if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0)
+               return rc;
+
+       bnx2_init_phy(bp);
+       bnx2_set_link(bp);
+       return 0;
+}
+
+static int
+bnx2_test_registers(struct bnx2 *bp)
+{
+       int ret;
+       int i;
+       static struct {
+               u16   offset;
+               u16   flags;
+               u32   rw_mask;
+               u32   ro_mask;
+       } reg_tbl[] = {
+               { 0x006c, 0, 0x00000000, 0x0000003f },
+               { 0x0090, 0, 0xffffffff, 0x00000000 },
+               { 0x0094, 0, 0x00000000, 0x00000000 },
+
+               { 0x0404, 0, 0x00003f00, 0x00000000 },
+               { 0x0418, 0, 0x00000000, 0xffffffff },
+               { 0x041c, 0, 0x00000000, 0xffffffff },
+               { 0x0420, 0, 0x00000000, 0x80ffffff },
+               { 0x0424, 0, 0x00000000, 0x00000000 },
+               { 0x0428, 0, 0x00000000, 0x00000001 },
+               { 0x0450, 0, 0x00000000, 0x0000ffff },
+               { 0x0454, 0, 0x00000000, 0xffffffff },
+               { 0x0458, 0, 0x00000000, 0xffffffff },
+
+               { 0x0808, 0, 0x00000000, 0xffffffff },
+               { 0x0854, 0, 0x00000000, 0xffffffff },
+               { 0x0868, 0, 0x00000000, 0x77777777 },
+               { 0x086c, 0, 0x00000000, 0x77777777 },
+               { 0x0870, 0, 0x00000000, 0x77777777 },
+               { 0x0874, 0, 0x00000000, 0x77777777 },
+
+               { 0x0c00, 0, 0x00000000, 0x00000001 },
+               { 0x0c04, 0, 0x00000000, 0x03ff0001 },
+               { 0x0c08, 0, 0x0f0ff073, 0x00000000 },
+               { 0x0c0c, 0, 0x00ffffff, 0x00000000 },
+               { 0x0c30, 0, 0x00000000, 0xffffffff },
+               { 0x0c34, 0, 0x00000000, 0xffffffff },
+               { 0x0c38, 0, 0x00000000, 0xffffffff },
+               { 0x0c3c, 0, 0x00000000, 0xffffffff },
+               { 0x0c40, 0, 0x00000000, 0xffffffff },
+               { 0x0c44, 0, 0x00000000, 0xffffffff },
+               { 0x0c48, 0, 0x00000000, 0x0007ffff },
+               { 0x0c4c, 0, 0x00000000, 0xffffffff },
+               { 0x0c50, 0, 0x00000000, 0xffffffff },
+               { 0x0c54, 0, 0x00000000, 0xffffffff },
+               { 0x0c58, 0, 0x00000000, 0xffffffff },
+               { 0x0c5c, 0, 0x00000000, 0xffffffff },
+               { 0x0c60, 0, 0x00000000, 0xffffffff },
+               { 0x0c64, 0, 0x00000000, 0xffffffff },
+               { 0x0c68, 0, 0x00000000, 0xffffffff },
+               { 0x0c6c, 0, 0x00000000, 0xffffffff },
+               { 0x0c70, 0, 0x00000000, 0xffffffff },
+               { 0x0c74, 0, 0x00000000, 0xffffffff },
+               { 0x0c78, 0, 0x00000000, 0xffffffff },
+               { 0x0c7c, 0, 0x00000000, 0xffffffff },
+               { 0x0c80, 0, 0x00000000, 0xffffffff },
+               { 0x0c84, 0, 0x00000000, 0xffffffff },
+               { 0x0c88, 0, 0x00000000, 0xffffffff },
+               { 0x0c8c, 0, 0x00000000, 0xffffffff },
+               { 0x0c90, 0, 0x00000000, 0xffffffff },
+               { 0x0c94, 0, 0x00000000, 0xffffffff },
+               { 0x0c98, 0, 0x00000000, 0xffffffff },
+               { 0x0c9c, 0, 0x00000000, 0xffffffff },
+               { 0x0ca0, 0, 0x00000000, 0xffffffff },
+               { 0x0ca4, 0, 0x00000000, 0xffffffff },
+               { 0x0ca8, 0, 0x00000000, 0x0007ffff },
+               { 0x0cac, 0, 0x00000000, 0xffffffff },
+               { 0x0cb0, 0, 0x00000000, 0xffffffff },
+               { 0x0cb4, 0, 0x00000000, 0xffffffff },
+               { 0x0cb8, 0, 0x00000000, 0xffffffff },
+               { 0x0cbc, 0, 0x00000000, 0xffffffff },
+               { 0x0cc0, 0, 0x00000000, 0xffffffff },
+               { 0x0cc4, 0, 0x00000000, 0xffffffff },
+               { 0x0cc8, 0, 0x00000000, 0xffffffff },
+               { 0x0ccc, 0, 0x00000000, 0xffffffff },
+               { 0x0cd0, 0, 0x00000000, 0xffffffff },
+               { 0x0cd4, 0, 0x00000000, 0xffffffff },
+               { 0x0cd8, 0, 0x00000000, 0xffffffff },
+               { 0x0cdc, 0, 0x00000000, 0xffffffff },
+               { 0x0ce0, 0, 0x00000000, 0xffffffff },
+               { 0x0ce4, 0, 0x00000000, 0xffffffff },
+               { 0x0ce8, 0, 0x00000000, 0xffffffff },
+               { 0x0cec, 0, 0x00000000, 0xffffffff },
+               { 0x0cf0, 0, 0x00000000, 0xffffffff },
+               { 0x0cf4, 0, 0x00000000, 0xffffffff },
+               { 0x0cf8, 0, 0x00000000, 0xffffffff },
+               { 0x0cfc, 0, 0x00000000, 0xffffffff },
+               { 0x0d00, 0, 0x00000000, 0xffffffff },
+               { 0x0d04, 0, 0x00000000, 0xffffffff },
+
+               { 0x1000, 0, 0x00000000, 0x00000001 },
+               { 0x1004, 0, 0x00000000, 0x000f0001 },
+               { 0x1044, 0, 0x00000000, 0xffc003ff },
+               { 0x1080, 0, 0x00000000, 0x0001ffff },
+               { 0x1084, 0, 0x00000000, 0xffffffff },
+               { 0x1088, 0, 0x00000000, 0xffffffff },
+               { 0x108c, 0, 0x00000000, 0xffffffff },
+               { 0x1090, 0, 0x00000000, 0xffffffff },
+               { 0x1094, 0, 0x00000000, 0xffffffff },
+               { 0x1098, 0, 0x00000000, 0xffffffff },
+               { 0x109c, 0, 0x00000000, 0xffffffff },
+               { 0x10a0, 0, 0x00000000, 0xffffffff },
+
+               { 0x1408, 0, 0x01c00800, 0x00000000 },
+               { 0x149c, 0, 0x8000ffff, 0x00000000 },
+               { 0x14a8, 0, 0x00000000, 0x000001ff },
+               { 0x14ac, 0, 0x4fffffff, 0x10000000 },
+               { 0x14b0, 0, 0x00000002, 0x00000001 },
+               { 0x14b8, 0, 0x00000000, 0x00000000 },
+               { 0x14c0, 0, 0x00000000, 0x00000009 },
+               { 0x14c4, 0, 0x00003fff, 0x00000000 },
+               { 0x14cc, 0, 0x00000000, 0x00000001 },
+               { 0x14d0, 0, 0xffffffff, 0x00000000 },
+               { 0x1500, 0, 0x00000000, 0xffffffff },
+               { 0x1504, 0, 0x00000000, 0xffffffff },
+               { 0x1508, 0, 0x00000000, 0xffffffff },
+               { 0x150c, 0, 0x00000000, 0xffffffff },
+               { 0x1510, 0, 0x00000000, 0xffffffff },
+               { 0x1514, 0, 0x00000000, 0xffffffff },
+               { 0x1518, 0, 0x00000000, 0xffffffff },
+               { 0x151c, 0, 0x00000000, 0xffffffff },
+               { 0x1520, 0, 0x00000000, 0xffffffff },
+               { 0x1524, 0, 0x00000000, 0xffffffff },
+               { 0x1528, 0, 0x00000000, 0xffffffff },
+               { 0x152c, 0, 0x00000000, 0xffffffff },
+               { 0x1530, 0, 0x00000000, 0xffffffff },
+               { 0x1534, 0, 0x00000000, 0xffffffff },
+               { 0x1538, 0, 0x00000000, 0xffffffff },
+               { 0x153c, 0, 0x00000000, 0xffffffff },
+               { 0x1540, 0, 0x00000000, 0xffffffff },
+               { 0x1544, 0, 0x00000000, 0xffffffff },
+               { 0x1548, 0, 0x00000000, 0xffffffff },
+               { 0x154c, 0, 0x00000000, 0xffffffff },
+               { 0x1550, 0, 0x00000000, 0xffffffff },
+               { 0x1554, 0, 0x00000000, 0xffffffff },
+               { 0x1558, 0, 0x00000000, 0xffffffff },
+               { 0x1600, 0, 0x00000000, 0xffffffff },
+               { 0x1604, 0, 0x00000000, 0xffffffff },
+               { 0x1608, 0, 0x00000000, 0xffffffff },
+               { 0x160c, 0, 0x00000000, 0xffffffff },
+               { 0x1610, 0, 0x00000000, 0xffffffff },
+               { 0x1614, 0, 0x00000000, 0xffffffff },
+               { 0x1618, 0, 0x00000000, 0xffffffff },
+               { 0x161c, 0, 0x00000000, 0xffffffff },
+               { 0x1620, 0, 0x00000000, 0xffffffff },
+               { 0x1624, 0, 0x00000000, 0xffffffff },
+               { 0x1628, 0, 0x00000000, 0xffffffff },
+               { 0x162c, 0, 0x00000000, 0xffffffff },
+               { 0x1630, 0, 0x00000000, 0xffffffff },
+               { 0x1634, 0, 0x00000000, 0xffffffff },
+               { 0x1638, 0, 0x00000000, 0xffffffff },
+               { 0x163c, 0, 0x00000000, 0xffffffff },
+               { 0x1640, 0, 0x00000000, 0xffffffff },
+               { 0x1644, 0, 0x00000000, 0xffffffff },
+               { 0x1648, 0, 0x00000000, 0xffffffff },
+               { 0x164c, 0, 0x00000000, 0xffffffff },
+               { 0x1650, 0, 0x00000000, 0xffffffff },
+               { 0x1654, 0, 0x00000000, 0xffffffff },
+
+               { 0x1800, 0, 0x00000000, 0x00000001 },
+               { 0x1804, 0, 0x00000000, 0x00000003 },
+               { 0x1840, 0, 0x00000000, 0xffffffff },
+               { 0x1844, 0, 0x00000000, 0xffffffff },
+               { 0x1848, 0, 0x00000000, 0xffffffff },
+               { 0x184c, 0, 0x00000000, 0xffffffff },
+               { 0x1850, 0, 0x00000000, 0xffffffff },
+               { 0x1900, 0, 0x7ffbffff, 0x00000000 },
+               { 0x1904, 0, 0xffffffff, 0x00000000 },
+               { 0x190c, 0, 0xffffffff, 0x00000000 },
+               { 0x1914, 0, 0xffffffff, 0x00000000 },
+               { 0x191c, 0, 0xffffffff, 0x00000000 },
+               { 0x1924, 0, 0xffffffff, 0x00000000 },
+               { 0x192c, 0, 0xffffffff, 0x00000000 },
+               { 0x1934, 0, 0xffffffff, 0x00000000 },
+               { 0x193c, 0, 0xffffffff, 0x00000000 },
+               { 0x1944, 0, 0xffffffff, 0x00000000 },
+               { 0x194c, 0, 0xffffffff, 0x00000000 },
+               { 0x1954, 0, 0xffffffff, 0x00000000 },
+               { 0x195c, 0, 0xffffffff, 0x00000000 },
+               { 0x1964, 0, 0xffffffff, 0x00000000 },
+               { 0x196c, 0, 0xffffffff, 0x00000000 },
+               { 0x1974, 0, 0xffffffff, 0x00000000 },
+               { 0x197c, 0, 0xffffffff, 0x00000000 },
+               { 0x1980, 0, 0x0700ffff, 0x00000000 },
+
+               { 0x1c00, 0, 0x00000000, 0x00000001 },
+               { 0x1c04, 0, 0x00000000, 0x00000003 },
+               { 0x1c08, 0, 0x0000000f, 0x00000000 },
+               { 0x1c40, 0, 0x00000000, 0xffffffff },
+               { 0x1c44, 0, 0x00000000, 0xffffffff },
+               { 0x1c48, 0, 0x00000000, 0xffffffff },
+               { 0x1c4c, 0, 0x00000000, 0xffffffff },
+               { 0x1c50, 0, 0x00000000, 0xffffffff },
+               { 0x1d00, 0, 0x7ffbffff, 0x00000000 },
+               { 0x1d04, 0, 0xffffffff, 0x00000000 },
+               { 0x1d0c, 0, 0xffffffff, 0x00000000 },
+               { 0x1d14, 0, 0xffffffff, 0x00000000 },
+               { 0x1d1c, 0, 0xffffffff, 0x00000000 },
+               { 0x1d24, 0, 0xffffffff, 0x00000000 },
+               { 0x1d2c, 0, 0xffffffff, 0x00000000 },
+               { 0x1d34, 0, 0xffffffff, 0x00000000 },
+               { 0x1d3c, 0, 0xffffffff, 0x00000000 },
+               { 0x1d44, 0, 0xffffffff, 0x00000000 },
+               { 0x1d4c, 0, 0xffffffff, 0x00000000 },
+               { 0x1d54, 0, 0xffffffff, 0x00000000 },
+               { 0x1d5c, 0, 0xffffffff, 0x00000000 },
+               { 0x1d64, 0, 0xffffffff, 0x00000000 },
+               { 0x1d6c, 0, 0xffffffff, 0x00000000 },
+               { 0x1d74, 0, 0xffffffff, 0x00000000 },
+               { 0x1d7c, 0, 0xffffffff, 0x00000000 },
+               { 0x1d80, 0, 0x0700ffff, 0x00000000 },
+
+               { 0x2004, 0, 0x00000000, 0x0337000f },
+               { 0x2008, 0, 0xffffffff, 0x00000000 },
+               { 0x200c, 0, 0xffffffff, 0x00000000 },
+               { 0x2010, 0, 0xffffffff, 0x00000000 },
+               { 0x2014, 0, 0x801fff80, 0x00000000 },
+               { 0x2018, 0, 0x000003ff, 0x00000000 },
+
+               { 0x2800, 0, 0x00000000, 0x00000001 },
+               { 0x2804, 0, 0x00000000, 0x00003f01 },
+               { 0x2808, 0, 0x0f3f3f03, 0x00000000 },
+               { 0x2810, 0, 0xffff0000, 0x00000000 },
+               { 0x2814, 0, 0xffff0000, 0x00000000 },
+               { 0x2818, 0, 0xffff0000, 0x00000000 },
+               { 0x281c, 0, 0xffff0000, 0x00000000 },
+               { 0x2834, 0, 0xffffffff, 0x00000000 },
+               { 0x2840, 0, 0x00000000, 0xffffffff },
+               { 0x2844, 0, 0x00000000, 0xffffffff },
+               { 0x2848, 0, 0xffffffff, 0x00000000 },
+               { 0x284c, 0, 0xf800f800, 0x07ff07ff },
+
+               { 0x2c00, 0, 0x00000000, 0x00000011 },
+               { 0x2c04, 0, 0x00000000, 0x00030007 },
+
+               { 0x3000, 0, 0x00000000, 0x00000001 },
+               { 0x3004, 0, 0x00000000, 0x007007ff },
+               { 0x3008, 0, 0x00000003, 0x00000000 },
+               { 0x300c, 0, 0xffffffff, 0x00000000 },
+               { 0x3010, 0, 0xffffffff, 0x00000000 },
+               { 0x3014, 0, 0xffffffff, 0x00000000 },
+               { 0x3034, 0, 0xffffffff, 0x00000000 },
+               { 0x3038, 0, 0xffffffff, 0x00000000 },
+               { 0x3050, 0, 0x00000001, 0x00000000 },
+
+               { 0x3c00, 0, 0x00000000, 0x00000001 },
+               { 0x3c04, 0, 0x00000000, 0x00070000 },
+               { 0x3c08, 0, 0x00007f71, 0x07f00000 },
+               { 0x3c0c, 0, 0x1f3ffffc, 0x00000000 },
+               { 0x3c10, 0, 0xffffffff, 0x00000000 },
+               { 0x3c14, 0, 0x00000000, 0xffffffff },
+               { 0x3c18, 0, 0x00000000, 0xffffffff },
+               { 0x3c1c, 0, 0xfffff000, 0x00000000 },
+               { 0x3c20, 0, 0xffffff00, 0x00000000 },
+               { 0x3c24, 0, 0xffffffff, 0x00000000 },
+               { 0x3c28, 0, 0xffffffff, 0x00000000 },
+               { 0x3c2c, 0, 0xffffffff, 0x00000000 },
+               { 0x3c30, 0, 0xffffffff, 0x00000000 },
+               { 0x3c34, 0, 0xffffffff, 0x00000000 },
+               { 0x3c38, 0, 0xffffffff, 0x00000000 },
+               { 0x3c3c, 0, 0xffffffff, 0x00000000 },
+               { 0x3c40, 0, 0xffffffff, 0x00000000 },
+               { 0x3c44, 0, 0xffffffff, 0x00000000 },
+               { 0x3c48, 0, 0xffffffff, 0x00000000 },
+               { 0x3c4c, 0, 0xffffffff, 0x00000000 },
+               { 0x3c50, 0, 0xffffffff, 0x00000000 },
+               { 0x3c54, 0, 0xffffffff, 0x00000000 },
+               { 0x3c58, 0, 0xffffffff, 0x00000000 },
+               { 0x3c5c, 0, 0xffffffff, 0x00000000 },
+               { 0x3c60, 0, 0xffffffff, 0x00000000 },
+               { 0x3c64, 0, 0xffffffff, 0x00000000 },
+               { 0x3c68, 0, 0xffffffff, 0x00000000 },
+               { 0x3c6c, 0, 0xffffffff, 0x00000000 },
+               { 0x3c70, 0, 0xffffffff, 0x00000000 },
+               { 0x3c74, 0, 0x0000003f, 0x00000000 },
+               { 0x3c78, 0, 0x00000000, 0x00000000 },
+               { 0x3c7c, 0, 0x00000000, 0x00000000 },
+               { 0x3c80, 0, 0x3fffffff, 0x00000000 },
+               { 0x3c84, 0, 0x0000003f, 0x00000000 },
+               { 0x3c88, 0, 0x00000000, 0xffffffff },
+               { 0x3c8c, 0, 0x00000000, 0xffffffff },
+
+               { 0x4000, 0, 0x00000000, 0x00000001 },
+               { 0x4004, 0, 0x00000000, 0x00030000 },
+               { 0x4008, 0, 0x00000ff0, 0x00000000 },
+               { 0x400c, 0, 0xffffffff, 0x00000000 },
+               { 0x4088, 0, 0x00000000, 0x00070303 },
+
+               { 0x4400, 0, 0x00000000, 0x00000001 },
+               { 0x4404, 0, 0x00000000, 0x00003f01 },
+               { 0x4408, 0, 0x7fff00ff, 0x00000000 },
+               { 0x440c, 0, 0xffffffff, 0x00000000 },
+               { 0x4410, 0, 0xffff,     0x0000 },
+               { 0x4414, 0, 0xffff,     0x0000 },
+               { 0x4418, 0, 0xffff,     0x0000 },
+               { 0x441c, 0, 0xffff,     0x0000 },
+               { 0x4428, 0, 0xffffffff, 0x00000000 },
+               { 0x442c, 0, 0xffffffff, 0x00000000 },
+               { 0x4430, 0, 0xffffffff, 0x00000000 },
+               { 0x4434, 0, 0xffffffff, 0x00000000 },
+               { 0x4438, 0, 0xffffffff, 0x00000000 },
+               { 0x443c, 0, 0xffffffff, 0x00000000 },
+               { 0x4440, 0, 0xffffffff, 0x00000000 },
+               { 0x4444, 0, 0xffffffff, 0x00000000 },
+
+               { 0x4c00, 0, 0x00000000, 0x00000001 },
+               { 0x4c04, 0, 0x00000000, 0x0000003f },
+               { 0x4c08, 0, 0xffffffff, 0x00000000 },
+               { 0x4c0c, 0, 0x0007fc00, 0x00000000 },
+               { 0x4c10, 0, 0x80003fe0, 0x00000000 },
+               { 0x4c14, 0, 0xffffffff, 0x00000000 },
+               { 0x4c44, 0, 0x00000000, 0x9fff9fff },
+               { 0x4c48, 0, 0x00000000, 0xb3009fff },
+               { 0x4c4c, 0, 0x00000000, 0x77f33b30 },
+               { 0x4c50, 0, 0x00000000, 0xffffffff },
+
+               { 0x5004, 0, 0x00000000, 0x0000007f },
+               { 0x5008, 0, 0x0f0007ff, 0x00000000 },
+               { 0x500c, 0, 0xf800f800, 0x07ff07ff },
+
+               { 0x5400, 0, 0x00000008, 0x00000001 },
+               { 0x5404, 0, 0x00000000, 0x0000003f },
+               { 0x5408, 0, 0x0000001f, 0x00000000 },
+               { 0x540c, 0, 0xffffffff, 0x00000000 },
+               { 0x5410, 0, 0xffffffff, 0x00000000 },
+               { 0x5414, 0, 0x0000ffff, 0x00000000 },
+               { 0x5418, 0, 0x0000ffff, 0x00000000 },
+               { 0x541c, 0, 0x0000ffff, 0x00000000 },
+               { 0x5420, 0, 0x0000ffff, 0x00000000 },
+               { 0x5428, 0, 0x000000ff, 0x00000000 },
+               { 0x542c, 0, 0xff00ffff, 0x00000000 },
+               { 0x5430, 0, 0x001fff80, 0x00000000 },
+               { 0x5438, 0, 0xffffffff, 0x00000000 },
+               { 0x543c, 0, 0xffffffff, 0x00000000 },
+               { 0x5440, 0, 0xf800f800, 0x07ff07ff },
+
+               { 0x5c00, 0, 0x00000000, 0x00000001 },
+               { 0x5c04, 0, 0x00000000, 0x0003000f },
+               { 0x5c08, 0, 0x00000003, 0x00000000 },
+               { 0x5c0c, 0, 0x0000fff8, 0x00000000 },
+               { 0x5c10, 0, 0x00000000, 0xffffffff },
+               { 0x5c80, 0, 0x00000000, 0x0f7113f1 },
+               { 0x5c84, 0, 0x00000000, 0x0000f333 },
+               { 0x5c88, 0, 0x00000000, 0x00077373 },
+               { 0x5c8c, 0, 0x00000000, 0x0007f737 },
+
+               { 0x6808, 0, 0x0000ff7f, 0x00000000 },
+               { 0x680c, 0, 0xffffffff, 0x00000000 },
+               { 0x6810, 0, 0xffffffff, 0x00000000 },
+               { 0x6814, 0, 0xffffffff, 0x00000000 },
+               { 0x6818, 0, 0xffffffff, 0x00000000 },
+               { 0x681c, 0, 0xffffffff, 0x00000000 },
+               { 0x6820, 0, 0x00ff00ff, 0x00000000 },
+               { 0x6824, 0, 0x00ff00ff, 0x00000000 },
+               { 0x6828, 0, 0x00ff00ff, 0x00000000 },
+               { 0x682c, 0, 0x03ff03ff, 0x00000000 },
+               { 0x6830, 0, 0x03ff03ff, 0x00000000 },
+               { 0x6834, 0, 0x03ff03ff, 0x00000000 },
+               { 0x6838, 0, 0x03ff03ff, 0x00000000 },
+               { 0x683c, 0, 0x0000ffff, 0x00000000 },
+               { 0x6840, 0, 0x00000ff0, 0x00000000 },
+               { 0x6844, 0, 0x00ffff00, 0x00000000 },
+               { 0x684c, 0, 0xffffffff, 0x00000000 },
+               { 0x6850, 0, 0x7f7f7f7f, 0x00000000 },
+               { 0x6854, 0, 0x7f7f7f7f, 0x00000000 },
+               { 0x6858, 0, 0x7f7f7f7f, 0x00000000 },
+               { 0x685c, 0, 0x7f7f7f7f, 0x00000000 },
+               { 0x6908, 0, 0x00000000, 0x0001ff0f },
+               { 0x690c, 0, 0x00000000, 0x0ffe00f0 },
+
+               { 0xffff, 0, 0x00000000, 0x00000000 },
+       };
+
+       ret = 0;
+       for (i = 0; reg_tbl[i].offset != 0xffff; i++) {
+               u32 offset, rw_mask, ro_mask, save_val, val;
+
+               offset = (u32) reg_tbl[i].offset;
+               rw_mask = reg_tbl[i].rw_mask;
+               ro_mask = reg_tbl[i].ro_mask;
+
+               save_val = readl((u8 *) bp->regview + offset);
+
+               writel(0, (u8 *) bp->regview + offset);
+
+               val = readl((u8 *) bp->regview + offset);
+               if ((val & rw_mask) != 0) {
+                       goto reg_test_err;
+               }
+
+               if ((val & ro_mask) != (save_val & ro_mask)) {
+                       goto reg_test_err;
+               }
+
+               writel(0xffffffff, (u8 *) bp->regview + offset);
+
+               val = readl((u8 *) bp->regview + offset);
+               if ((val & rw_mask) != rw_mask) {
+                       goto reg_test_err;
+               }
+
+               if ((val & ro_mask) != (save_val & ro_mask)) {
+                       goto reg_test_err;
+               }
+
+               writel(save_val, (u8 *) bp->regview + offset);
+               continue;
+
+reg_test_err:
+               writel(save_val, (u8 *) bp->regview + offset);
+               ret = -ENODEV;
+               break;
+       }
+       return ret;
+}
+
+static int
+bnx2_do_mem_test(struct bnx2 *bp, u32 start, u32 size)
+{
+       static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0x55555555,
+               0xaaaaaaaa , 0xaa55aa55, 0x55aa55aa };
+       int i;
+
+       for (i = 0; i < sizeof(test_pattern) / 4; i++) {
+               u32 offset;
+
+               for (offset = 0; offset < size; offset += 4) {
+
+                       REG_WR_IND(bp, start + offset, test_pattern[i]);
+
+                       if (REG_RD_IND(bp, start + offset) !=
+                               test_pattern[i]) {
+                               return -ENODEV;
+                       }
+               }
+       }
+       return 0;
+}
+
+static int
+bnx2_test_memory(struct bnx2 *bp)
+{
+       int ret = 0;
+       int i;
+       static struct {
+               u32   offset;
+               u32   len;
+       } mem_tbl[] = {
+               { 0x60000,  0x4000 },
+               { 0xa0000,  0x4000 },
+               { 0xe0000,  0x4000 },
+               { 0x120000, 0x4000 },
+               { 0x1a0000, 0x4000 },
+               { 0x160000, 0x4000 },
+               { 0xffffffff, 0    },
+       };
+
+       for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
+               if ((ret = bnx2_do_mem_test(bp, mem_tbl[i].offset,
+                       mem_tbl[i].len)) != 0) {
+                       return ret;
+               }
+       }
+       
+       return ret;
+}
+
+static int
+bnx2_test_loopback(struct bnx2 *bp)
+{
+       unsigned int pkt_size, num_pkts, i;
+       struct sk_buff *skb, *rx_skb;
+       unsigned char *packet;
+       u16 rx_start_idx, rx_idx, send_idx;
+       u32 send_bseq, val;
+       dma_addr_t map;
+       struct tx_bd *txbd;
+       struct sw_bd *rx_buf;
+       struct l2_fhdr *rx_hdr;
+       int ret = -ENODEV;
+
+       if (!netif_running(bp->dev))
+               return -ENODEV;
+
+       bp->loopback = MAC_LOOPBACK;
+       bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_DIAG);
+       bnx2_set_mac_loopback(bp);
+
+       pkt_size = 1514;
+       skb = dev_alloc_skb(pkt_size);
+       packet = skb_put(skb, pkt_size);
+       memcpy(packet, bp->mac_addr, 6);
+       memset(packet + 6, 0x0, 8);
+       for (i = 14; i < pkt_size; i++)
+               packet[i] = (unsigned char) (i & 0xff);
+
+       map = pci_map_single(bp->pdev, skb->data, pkt_size,
+               PCI_DMA_TODEVICE);
+
+       val = REG_RD(bp, BNX2_HC_COMMAND);
+       REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
+       REG_RD(bp, BNX2_HC_COMMAND);
+
+       udelay(5);
+       rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0;
+
+       send_idx = 0;
+       send_bseq = 0;
+       num_pkts = 0;
+
+       txbd = &bp->tx_desc_ring[send_idx];
+
+       txbd->tx_bd_haddr_hi = (u64) map >> 32;
+       txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff;
+       txbd->tx_bd_mss_nbytes = pkt_size;
+       txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END;
+
+       num_pkts++;
+       send_idx = NEXT_TX_BD(send_idx);
+
+       send_bseq += pkt_size;
+
+       REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, send_idx);
+       REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, send_bseq);
+
+
+       udelay(100);
+
+       val = REG_RD(bp, BNX2_HC_COMMAND);
+       REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
+       REG_RD(bp, BNX2_HC_COMMAND);
+
+       udelay(5);
+
+       pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
+       dev_kfree_skb_irq(skb);
+
+       if (bp->status_blk->status_tx_quick_consumer_index0 != send_idx) {
+               goto loopback_test_done;
+       }
+
+       rx_idx = bp->status_blk->status_rx_quick_consumer_index0;
+       if (rx_idx != rx_start_idx + num_pkts) {
+               goto loopback_test_done;
+       }
+
+       rx_buf = &bp->rx_buf_ring[rx_start_idx];
+       rx_skb = rx_buf->skb;
+
+       rx_hdr = (struct l2_fhdr *) rx_skb->data;
+       skb_reserve(rx_skb, bp->rx_offset);
+
+       pci_dma_sync_single_for_cpu(bp->pdev,
+               pci_unmap_addr(rx_buf, mapping),
+               bp->rx_buf_size, PCI_DMA_FROMDEVICE);
+
+       if (rx_hdr->l2_fhdr_errors &
+               (L2_FHDR_ERRORS_BAD_CRC |
+               L2_FHDR_ERRORS_PHY_DECODE |
+               L2_FHDR_ERRORS_ALIGNMENT |
+               L2_FHDR_ERRORS_TOO_SHORT |
+               L2_FHDR_ERRORS_GIANT_FRAME)) {
+
+               goto loopback_test_done;
+       }
+
+       if ((rx_hdr->l2_fhdr_pkt_len - 4) != pkt_size) {
+               goto loopback_test_done;
+       }
+
+       for (i = 14; i < pkt_size; i++) {
+               if (*(rx_skb->data + i) != (unsigned char) (i & 0xff)) {
+                       goto loopback_test_done;
+               }
+       }
+
+       ret = 0;
+
+loopback_test_done:
+       bp->loopback = 0;
+       return ret;
+}
+
+#define NVRAM_SIZE 0x200
+#define CRC32_RESIDUAL 0xdebb20e3
+
+static int
+bnx2_test_nvram(struct bnx2 *bp)
+{
+       u32 buf[NVRAM_SIZE / 4];
+       u8 *data = (u8 *) buf;
+       int rc = 0;
+       u32 magic, csum;
+
+       if ((rc = bnx2_nvram_read(bp, 0, data, 4)) != 0)
+               goto test_nvram_done;
+
+        magic = be32_to_cpu(buf[0]);
+       if (magic != 0x669955aa) {
+               rc = -ENODEV;
+               goto test_nvram_done;
+       }
+
+       if ((rc = bnx2_nvram_read(bp, 0x100, data, NVRAM_SIZE)) != 0)
+               goto test_nvram_done;
+
+       csum = ether_crc_le(0x100, data);
+       if (csum != CRC32_RESIDUAL) {
+               rc = -ENODEV;
+               goto test_nvram_done;
+       }
+
+       csum = ether_crc_le(0x100, data + 0x100);
+       if (csum != CRC32_RESIDUAL) {
+               rc = -ENODEV;
+       }
+
+test_nvram_done:
+       return rc;
+}
+
+static int
+bnx2_test_link(struct bnx2 *bp)
+{
+       u32 bmsr;
+
+       spin_lock_irq(&bp->phy_lock);
+       bnx2_read_phy(bp, MII_BMSR, &bmsr);
+       bnx2_read_phy(bp, MII_BMSR, &bmsr);
+       spin_unlock_irq(&bp->phy_lock);
+               
+       if (bmsr & BMSR_LSTATUS) {
+               return 0;
+       }
+       return -ENODEV;
+}
+
+static int
+bnx2_test_intr(struct bnx2 *bp)
+{
+       int i;
+       u32 val;
+       u16 status_idx;
+
+       if (!netif_running(bp->dev))
+               return -ENODEV;
+
+       status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff;
+
+       /* This register is not touched during run-time. */
+       val = REG_RD(bp, BNX2_HC_COMMAND);
+       REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW);
+       REG_RD(bp, BNX2_HC_COMMAND);
+
+       for (i = 0; i < 10; i++) {
+               if ((REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff) !=
+                       status_idx) {
+
+                       break;
+               }
+
+               msleep_interruptible(10);
+       }
+       if (i < 10)
+               return 0;
+
+       return -ENODEV;
+}
+
+static void
+bnx2_timer(unsigned long data)
+{
+       struct bnx2 *bp = (struct bnx2 *) data;
+       u32 msg;
+
+       if (atomic_read(&bp->intr_sem) != 0)
+               goto bnx2_restart_timer;
+
+       msg = (u32) ++bp->fw_drv_pulse_wr_seq;
+       REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg);
+
+       if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+           (CHIP_NUM(bp) == CHIP_NUM_5706)) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&bp->phy_lock, flags);
+               if (bp->serdes_an_pending) {
+                       bp->serdes_an_pending--;
+               }
+               else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
+                       u32 bmcr;
+
+                       bnx2_read_phy(bp, MII_BMCR, &bmcr);
+
+                       if (bmcr & BMCR_ANENABLE) {
+                               u32 phy1, phy2;
+
+                               bnx2_write_phy(bp, 0x1c, 0x7c00);
+                               bnx2_read_phy(bp, 0x1c, &phy1);
+
+                               bnx2_write_phy(bp, 0x17, 0x0f01);
+                               bnx2_read_phy(bp, 0x15, &phy2);
+                               bnx2_write_phy(bp, 0x17, 0x0f01);
+                               bnx2_read_phy(bp, 0x15, &phy2);
+
+                               if ((phy1 & 0x10) &&    /* SIGNAL DETECT */
+                                       !(phy2 & 0x20)) {       /* no CONFIG */
+
+                                       bmcr &= ~BMCR_ANENABLE;
+                                       bmcr |= BMCR_SPEED1000 |
+                                               BMCR_FULLDPLX;
+                                       bnx2_write_phy(bp, MII_BMCR, bmcr);
+                                       bp->phy_flags |=
+                                               PHY_PARALLEL_DETECT_FLAG;
+                               }
+                       }
+               }
+               else if ((bp->link_up) && (bp->autoneg & AUTONEG_SPEED) &&
+                       (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) {
+                       u32 phy2;
+
+                       bnx2_write_phy(bp, 0x17, 0x0f01);
+                       bnx2_read_phy(bp, 0x15, &phy2);
+                       if (phy2 & 0x20) {
+                               u32 bmcr;
+
+                               bnx2_read_phy(bp, MII_BMCR, &bmcr);
+                               bmcr |= BMCR_ANENABLE;
+                               bnx2_write_phy(bp, MII_BMCR, bmcr);
+
+                               bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+
+                       }
+               }
+
+               spin_unlock_irqrestore(&bp->phy_lock, flags);
+       }
+
+bnx2_restart_timer:
+       bp->timer.expires = RUN_AT(bp->timer_interval);
+
+       add_timer(&bp->timer);
+}
+
+/* Called with rtnl_lock */
+static int
+bnx2_open(struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+       int rc;
+
+       bnx2_set_power_state(bp, 0);
+       bnx2_disable_int(bp);
+
+       rc = bnx2_alloc_mem(bp);
+       if (rc)
+               return rc;
+
+       if ((CHIP_ID(bp) != CHIP_ID_5706_A0) &&
+               (CHIP_ID(bp) != CHIP_ID_5706_A1) &&
+               !disable_msi) {
+
+               if (pci_enable_msi(bp->pdev) == 0) {
+                       bp->flags |= USING_MSI_FLAG;
+                       rc = request_irq(bp->pdev->irq, bnx2_msi, 0, dev->name,
+                                       dev);
+               }
+               else {
+                       rc = request_irq(bp->pdev->irq, bnx2_interrupt,
+                                       SA_SHIRQ, dev->name, dev);
+               }
+       }
+       else {
+               rc = request_irq(bp->pdev->irq, bnx2_interrupt, SA_SHIRQ,
+                               dev->name, dev);
+       }
+       if (rc) {
+               bnx2_free_mem(bp);
+               return rc;
+       }
+
+       rc = bnx2_init_nic(bp);
+
+       if (rc) {
+               free_irq(bp->pdev->irq, dev);
+               if (bp->flags & USING_MSI_FLAG) {
+                       pci_disable_msi(bp->pdev);
+                       bp->flags &= ~USING_MSI_FLAG;
+               }
+               bnx2_free_skbs(bp);
+               bnx2_free_mem(bp);
+               return rc;
+       }
+       
+       init_timer(&bp->timer);
+
+       bp->timer.expires = RUN_AT(bp->timer_interval);
+       bp->timer.data = (unsigned long) bp;
+       bp->timer.function = bnx2_timer;
+       add_timer(&bp->timer);
+
+       atomic_set(&bp->intr_sem, 0);
+
+       bnx2_enable_int(bp);
+
+       if (bp->flags & USING_MSI_FLAG) {
+               /* Test MSI to make sure it is working
+                * If MSI test fails, go back to INTx mode
+                */
+               if (bnx2_test_intr(bp) != 0) {
+                       printk(KERN_WARNING PFX "%s: No interrupt was generated"
+                              " using MSI, switching to INTx mode. Please"
+                              " report this failure to the PCI maintainer"
+                              " and include system chipset information.\n",
+                              bp->dev->name);
+
+                       bnx2_disable_int(bp);
+                       free_irq(bp->pdev->irq, dev);
+                       pci_disable_msi(bp->pdev);
+                       bp->flags &= ~USING_MSI_FLAG;
+
+                       rc = bnx2_init_nic(bp);
+
+                       if (!rc) {
+                               rc = request_irq(bp->pdev->irq, bnx2_interrupt,
+                                       SA_SHIRQ, dev->name, dev);
+                       }
+                       if (rc) {
+                               bnx2_free_skbs(bp);
+                               bnx2_free_mem(bp);
+                               del_timer_sync(&bp->timer);
+                               return rc;
+                       }
+                       bnx2_enable_int(bp);
+               }
+       }
+       if (bp->flags & USING_MSI_FLAG) {
+               printk(KERN_INFO PFX "%s: using MSI\n", dev->name);
+       }
+
+       netif_start_queue(dev);
+
+       return 0;
+}
+
+static void
+bnx2_reset_task(void *data)
+{
+       struct bnx2 *bp = data;
+
+       bnx2_netif_stop(bp);
+
+       bnx2_init_nic(bp);
+
+       atomic_set(&bp->intr_sem, 1);
+       bnx2_netif_start(bp);
+}
+
+static void
+bnx2_tx_timeout(struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+
+       /* This allows the netif to be shutdown gracefully before resetting */
+       schedule_work(&bp->reset_task);
+}
+
+#ifdef BCM_VLAN
+/* Called with rtnl_lock */
+static void
+bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
+{
+       struct bnx2 *bp = dev->priv;
+
+       bnx2_netif_stop(bp);
+
+       bp->vlgrp = vlgrp;
+       bnx2_set_rx_mode(dev);
+
+       bnx2_netif_start(bp);
+}
+
+/* Called with rtnl_lock */
+static void
+bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
+{
+       struct bnx2 *bp = dev->priv;
+
+       bnx2_netif_stop(bp);
+
+       if (bp->vlgrp)
+               bp->vlgrp->vlan_devices[vid] = NULL;
+       bnx2_set_rx_mode(dev);
+
+       bnx2_netif_start(bp);
+}
+#endif
+
+/* Called with dev->xmit_lock.
+ * hard_start_xmit is pseudo-lockless - a lock is only required when
+ * the tx queue is full. This way, we get the benefit of lockless
+ * operations most of the time without the complexities to handle
+ * netif_stop_queue/wake_queue race conditions.
+ */
+static int
+bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+       dma_addr_t mapping;
+       struct tx_bd *txbd;
+       struct sw_bd *tx_buf;
+       u32 len, vlan_tag_flags, last_frag, mss;
+       u16 prod, ring_prod;
+       int i;
+
+       if (unlikely(atomic_read(&bp->tx_avail_bd) <
+               (skb_shinfo(skb)->nr_frags + 1))) {
+
+               netif_stop_queue(dev);
+               printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n",
+                       dev->name);
+
+               return NETDEV_TX_BUSY;
+       }
+       len = skb_headlen(skb);
+       prod = bp->tx_prod;
+       ring_prod = TX_RING_IDX(prod);
+
+       vlan_tag_flags = 0;
+       if (skb->ip_summed == CHECKSUM_HW) {
+               vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
+       }
+
+       if (bp->vlgrp != 0 && vlan_tx_tag_present(skb)) {
+               vlan_tag_flags |=
+                       (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
+       }
+#ifdef BCM_TSO 
+       if ((mss = skb_shinfo(skb)->tso_size) &&
+               (skb->len > (bp->dev->mtu + ETH_HLEN))) {
+               u32 tcp_opt_len, ip_tcp_len;
+
+               if (skb_header_cloned(skb) &&
+                   pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
+                       dev_kfree_skb(skb);
+                       return NETDEV_TX_OK;
+               }
+
+               tcp_opt_len = ((skb->h.th->doff - 5) * 4);
+               vlan_tag_flags |= TX_BD_FLAGS_SW_LSO;
+
+               tcp_opt_len = 0;
+               if (skb->h.th->doff > 5) {
+                       tcp_opt_len = (skb->h.th->doff - 5) << 2;
+               }
+               ip_tcp_len = (skb->nh.iph->ihl << 2) + sizeof(struct tcphdr);
+
+               skb->nh.iph->check = 0;
+               skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len);
+               skb->h.th->check =
+                       ~csum_tcpudp_magic(skb->nh.iph->saddr,
+                                           skb->nh.iph->daddr,
+                                           0, IPPROTO_TCP, 0);
+
+               if (tcp_opt_len || (skb->nh.iph->ihl > 5)) {
+                       vlan_tag_flags |= ((skb->nh.iph->ihl - 5) +
+                               (tcp_opt_len >> 2)) << 8;
+               }
+       }
+       else
+#endif
+       {
+               mss = 0;
+       }
+
+       mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+       
+       tx_buf = &bp->tx_buf_ring[ring_prod];
+       tx_buf->skb = skb;
+       pci_unmap_addr_set(tx_buf, mapping, mapping);
+
+       txbd = &bp->tx_desc_ring[ring_prod];
+
+       txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
+       txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
+       txbd->tx_bd_mss_nbytes = len | (mss << 16);
+       txbd->tx_bd_vlan_tag_flags = vlan_tag_flags | TX_BD_FLAGS_START;
+
+       last_frag = skb_shinfo(skb)->nr_frags;
+
+       for (i = 0; i < last_frag; i++) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+               prod = NEXT_TX_BD(prod);
+               ring_prod = TX_RING_IDX(prod);
+               txbd = &bp->tx_desc_ring[ring_prod];
+
+               len = frag->size;
+               mapping = pci_map_page(bp->pdev, frag->page, frag->page_offset,
+                       len, PCI_DMA_TODEVICE);
+               pci_unmap_addr_set(&bp->tx_buf_ring[ring_prod],
+                               mapping, mapping);
+
+               txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
+               txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
+               txbd->tx_bd_mss_nbytes = len | (mss << 16);
+               txbd->tx_bd_vlan_tag_flags = vlan_tag_flags;
+
+       }
+       txbd->tx_bd_vlan_tag_flags |= TX_BD_FLAGS_END;
+
+       prod = NEXT_TX_BD(prod);
+       bp->tx_prod_bseq += skb->len;
+
+       atomic_sub(last_frag + 1, &bp->tx_avail_bd);
+
+       REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod);
+       REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
+
+       mmiowb();
+
+       bp->tx_prod = prod;
+       dev->trans_start = jiffies;
+
+       if (unlikely(atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS)) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&bp->tx_lock, flags);
+               if (atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS) {
+                       netif_stop_queue(dev);
+
+                       if (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS)
+                               netif_wake_queue(dev);
+               }
+               spin_unlock_irqrestore(&bp->tx_lock, flags);
+       }
+
+       return NETDEV_TX_OK;
+}
+
+/* Called with rtnl_lock */
+static int
+bnx2_close(struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+       u32 reset_code;
+
+       flush_scheduled_work();
+       bnx2_netif_stop(bp);
+       del_timer_sync(&bp->timer);
+       if (bp->wol)
+               reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
+       else
+               reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
+       bnx2_reset_chip(bp, reset_code);
+       free_irq(bp->pdev->irq, dev);
+       if (bp->flags & USING_MSI_FLAG) {
+               pci_disable_msi(bp->pdev);
+               bp->flags &= ~USING_MSI_FLAG;
+       }
+       bnx2_free_skbs(bp);
+       bnx2_free_mem(bp);
+       bp->link_up = 0;
+       netif_carrier_off(bp->dev);
+       bnx2_set_power_state(bp, 3);
+       return 0;
+}
+
+#define GET_NET_STATS64(ctr)                                   \
+       (unsigned long) ((unsigned long) (ctr##_hi) << 32) +    \
+       (unsigned long) (ctr##_lo)
+
+#define GET_NET_STATS32(ctr)           \
+       (ctr##_lo)
+
+#if (BITS_PER_LONG == 64)
+#define GET_NET_STATS  GET_NET_STATS64
+#else
+#define GET_NET_STATS  GET_NET_STATS32
+#endif
+
+static struct net_device_stats *
+bnx2_get_stats(struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+       struct statistics_block *stats_blk = bp->stats_blk;
+       struct net_device_stats *net_stats = &bp->net_stats;
+
+       if (bp->stats_blk == NULL) {
+               return net_stats;
+       }
+       net_stats->rx_packets =
+               GET_NET_STATS(stats_blk->stat_IfHCInUcastPkts) +
+               GET_NET_STATS(stats_blk->stat_IfHCInMulticastPkts) +
+               GET_NET_STATS(stats_blk->stat_IfHCInBroadcastPkts);
+
+       net_stats->tx_packets =
+               GET_NET_STATS(stats_blk->stat_IfHCOutUcastPkts) +
+               GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts) +
+               GET_NET_STATS(stats_blk->stat_IfHCOutBroadcastPkts);
+
+       net_stats->rx_bytes =
+               GET_NET_STATS(stats_blk->stat_IfHCInOctets);
+
+       net_stats->tx_bytes =
+               GET_NET_STATS(stats_blk->stat_IfHCOutOctets);
+
+       net_stats->multicast = 
+               GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts);
+
+       net_stats->collisions = 
+               (unsigned long) stats_blk->stat_EtherStatsCollisions;
+
+       net_stats->rx_length_errors = 
+               (unsigned long) (stats_blk->stat_EtherStatsUndersizePkts +
+               stats_blk->stat_EtherStatsOverrsizePkts);
+
+       net_stats->rx_over_errors = 
+               (unsigned long) stats_blk->stat_IfInMBUFDiscards;
+
+       net_stats->rx_frame_errors = 
+               (unsigned long) stats_blk->stat_Dot3StatsAlignmentErrors;
+
+       net_stats->rx_crc_errors = 
+               (unsigned long) stats_blk->stat_Dot3StatsFCSErrors;
+
+       net_stats->rx_errors = net_stats->rx_length_errors +
+               net_stats->rx_over_errors + net_stats->rx_frame_errors +
+               net_stats->rx_crc_errors;
+
+       net_stats->tx_aborted_errors =
+               (unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions +
+               stats_blk->stat_Dot3StatsLateCollisions);
+
+       if (CHIP_NUM(bp) == CHIP_NUM_5706)
+               net_stats->tx_carrier_errors = 0;
+       else {
+               net_stats->tx_carrier_errors =
+                       (unsigned long)
+                       stats_blk->stat_Dot3StatsCarrierSenseErrors;
+       }
+
+       net_stats->tx_errors =
+               (unsigned long) 
+               stats_blk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors
+               +
+               net_stats->tx_aborted_errors +
+               net_stats->tx_carrier_errors;
+
+       return net_stats;
+}
+
+/* All ethtool functions called with rtnl_lock */
+
+static int
+bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct bnx2 *bp = dev->priv;
+
+       cmd->supported = SUPPORTED_Autoneg;
+       if (bp->phy_flags & PHY_SERDES_FLAG) {
+               cmd->supported |= SUPPORTED_1000baseT_Full |
+                       SUPPORTED_FIBRE;
+
+               cmd->port = PORT_FIBRE;
+       }
+       else {
+               cmd->supported |= SUPPORTED_10baseT_Half |
+                       SUPPORTED_10baseT_Full |
+                       SUPPORTED_100baseT_Half |
+                       SUPPORTED_100baseT_Full |
+                       SUPPORTED_1000baseT_Full |
+                       SUPPORTED_TP;
+
+               cmd->port = PORT_TP;
+       }
+
+       cmd->advertising = bp->advertising;
+
+       if (bp->autoneg & AUTONEG_SPEED) {
+               cmd->autoneg = AUTONEG_ENABLE;
+       }
+       else {
+               cmd->autoneg = AUTONEG_DISABLE;
+       }
+
+       if (netif_carrier_ok(dev)) {
+               cmd->speed = bp->line_speed;
+               cmd->duplex = bp->duplex;
+       }
+       else {
+               cmd->speed = -1;
+               cmd->duplex = -1;
+       }
+
+       cmd->transceiver = XCVR_INTERNAL;
+       cmd->phy_address = bp->phy_addr;
+
+       return 0;
+}
+  
+static int
+bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct bnx2 *bp = dev->priv;
+       u8 autoneg = bp->autoneg;
+       u8 req_duplex = bp->req_duplex;
+       u16 req_line_speed = bp->req_line_speed;
+       u32 advertising = bp->advertising;
+
+       if (cmd->autoneg == AUTONEG_ENABLE) {
+               autoneg |= AUTONEG_SPEED;
+
+               cmd->advertising &= ETHTOOL_ALL_COPPER_SPEED; 
+
+               /* allow advertising 1 speed */
+               if ((cmd->advertising == ADVERTISED_10baseT_Half) ||
+                       (cmd->advertising == ADVERTISED_10baseT_Full) ||
+                       (cmd->advertising == ADVERTISED_100baseT_Half) ||
+                       (cmd->advertising == ADVERTISED_100baseT_Full)) {
+
+                       if (bp->phy_flags & PHY_SERDES_FLAG)
+                               return -EINVAL;
+
+                       advertising = cmd->advertising;
+
+               }
+               else if (cmd->advertising == ADVERTISED_1000baseT_Full) {
+                       advertising = cmd->advertising;
+               }
+               else if (cmd->advertising == ADVERTISED_1000baseT_Half) {
+                       return -EINVAL;
+               }
+               else {
+                       if (bp->phy_flags & PHY_SERDES_FLAG) {
+                               advertising = ETHTOOL_ALL_FIBRE_SPEED;
+                       }
+                       else {
+                               advertising = ETHTOOL_ALL_COPPER_SPEED;
+                       }
+               }
+               advertising |= ADVERTISED_Autoneg;
+       }
+       else {
+               if (bp->phy_flags & PHY_SERDES_FLAG) {
+                       if ((cmd->speed != SPEED_1000) ||
+                               (cmd->duplex != DUPLEX_FULL)) {
+                               return -EINVAL;
+                       }
+               }
+               else if (cmd->speed == SPEED_1000) {
+                       return -EINVAL;
+               }
+               autoneg &= ~AUTONEG_SPEED;
+               req_line_speed = cmd->speed;
+               req_duplex = cmd->duplex;
+               advertising = 0;
+       }
+
+       bp->autoneg = autoneg;
+       bp->advertising = advertising;
+       bp->req_line_speed = req_line_speed;
+       bp->req_duplex = req_duplex;
+
+       spin_lock_irq(&bp->phy_lock);
+
+       bnx2_setup_phy(bp);
+
+       spin_unlock_irq(&bp->phy_lock);
+
+       return 0;
+}
+
+static void
+bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       struct bnx2 *bp = dev->priv;
+
+       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[6] = (bp->fw_ver & 0xff) + '0';
+       info->fw_version[1] = info->fw_version[3] = info->fw_version[5] = '.';
+       info->fw_version[7] = 0;
+}
+
+static void
+bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct bnx2 *bp = dev->priv;
+
+       if (bp->flags & NO_WOL_FLAG) {
+               wol->supported = 0;
+               wol->wolopts = 0;
+       }
+       else {
+               wol->supported = WAKE_MAGIC;
+               if (bp->wol)
+                       wol->wolopts = WAKE_MAGIC;
+               else
+                       wol->wolopts = 0;
+       }
+       memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+static int
+bnx2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct bnx2 *bp = dev->priv;
+
+       if (wol->wolopts & ~WAKE_MAGIC)
+               return -EINVAL;
+
+       if (wol->wolopts & WAKE_MAGIC) {
+               if (bp->flags & NO_WOL_FLAG)
+                       return -EINVAL;
+
+               bp->wol = 1;
+       }
+       else {
+               bp->wol = 0;
+       }
+       return 0;
+}
+
+static int
+bnx2_nway_reset(struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+       u32 bmcr;
+
+       if (!(bp->autoneg & AUTONEG_SPEED)) {
+               return -EINVAL;
+       }
+
+       spin_lock_irq(&bp->phy_lock);
+
+       /* Force a link down visible on the other side */
+       if (bp->phy_flags & PHY_SERDES_FLAG) {
+               bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
+               spin_unlock_irq(&bp->phy_lock);
+
+               msleep(20);
+
+               spin_lock_irq(&bp->phy_lock);
+               if (CHIP_NUM(bp) == CHIP_NUM_5706) {
+                       bp->serdes_an_pending = SERDES_AN_TIMEOUT /
+                               bp->timer_interval;
+               }
+       }
+
+       bnx2_read_phy(bp, MII_BMCR, &bmcr);
+       bmcr &= ~BMCR_LOOPBACK;
+       bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE);
+
+       spin_unlock_irq(&bp->phy_lock);
+
+       return 0;
+}
+
+static int
+bnx2_get_eeprom_len(struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+
+       if (bp->flash_info == 0)
+               return 0;
+
+       return (int) bp->flash_info->total_size;
+}
+
+static int
+bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+               u8 *eebuf)
+{
+       struct bnx2 *bp = dev->priv;
+       int rc;
+
+       if (eeprom->offset > bp->flash_info->total_size)
+               return -EINVAL;
+
+       if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
+               eeprom->len = bp->flash_info->total_size - eeprom->offset;
+
+       rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
+
+       return rc;
+}
+
+static int
+bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+               u8 *eebuf)
+{
+       struct bnx2 *bp = dev->priv;
+       int rc;
+
+       if (eeprom->offset > bp->flash_info->total_size)
+               return -EINVAL;
+
+       if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
+               eeprom->len = bp->flash_info->total_size - eeprom->offset;
+
+       rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
+
+       return rc;
+}
+
+static int
+bnx2_get_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
+{
+       struct bnx2 *bp = dev->priv;
+
+       memset(coal, 0, sizeof(struct ethtool_coalesce));
+
+       coal->rx_coalesce_usecs = bp->rx_ticks;
+       coal->rx_max_coalesced_frames = bp->rx_quick_cons_trip;
+       coal->rx_coalesce_usecs_irq = bp->rx_ticks_int;
+       coal->rx_max_coalesced_frames_irq = bp->rx_quick_cons_trip_int;
+
+       coal->tx_coalesce_usecs = bp->tx_ticks;
+       coal->tx_max_coalesced_frames = bp->tx_quick_cons_trip;
+       coal->tx_coalesce_usecs_irq = bp->tx_ticks_int;
+       coal->tx_max_coalesced_frames_irq = bp->tx_quick_cons_trip_int;
+
+       coal->stats_block_coalesce_usecs = bp->stats_ticks;
+
+       return 0;
+}
+
+static int
+bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
+{
+       struct bnx2 *bp = dev->priv;
+
+       bp->rx_ticks = (u16) coal->rx_coalesce_usecs;
+       if (bp->rx_ticks > 0x3ff) bp->rx_ticks = 0x3ff;
+
+       bp->rx_quick_cons_trip = (u16) coal->rx_max_coalesced_frames; 
+       if (bp->rx_quick_cons_trip > 0xff) bp->rx_quick_cons_trip = 0xff;
+
+       bp->rx_ticks_int = (u16) coal->rx_coalesce_usecs_irq;
+       if (bp->rx_ticks_int > 0x3ff) bp->rx_ticks_int = 0x3ff;
+
+       bp->rx_quick_cons_trip_int = (u16) coal->rx_max_coalesced_frames_irq;
+       if (bp->rx_quick_cons_trip_int > 0xff)
+               bp->rx_quick_cons_trip_int = 0xff;
+
+       bp->tx_ticks = (u16) coal->tx_coalesce_usecs;
+       if (bp->tx_ticks > 0x3ff) bp->tx_ticks = 0x3ff;
+
+       bp->tx_quick_cons_trip = (u16) coal->tx_max_coalesced_frames;
+       if (bp->tx_quick_cons_trip > 0xff) bp->tx_quick_cons_trip = 0xff;
+
+       bp->tx_ticks_int = (u16) coal->tx_coalesce_usecs_irq;
+       if (bp->tx_ticks_int > 0x3ff) bp->tx_ticks_int = 0x3ff;
+
+       bp->tx_quick_cons_trip_int = (u16) coal->tx_max_coalesced_frames_irq;
+       if (bp->tx_quick_cons_trip_int > 0xff) bp->tx_quick_cons_trip_int =
+               0xff;
+
+       bp->stats_ticks = coal->stats_block_coalesce_usecs;
+       if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00;
+       bp->stats_ticks &= 0xffff00;
+
+       if (netif_running(bp->dev)) {
+               bnx2_netif_stop(bp);
+               bnx2_init_nic(bp);
+               bnx2_netif_start(bp);
+       }
+
+       return 0;
+}
+
+static void
+bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
+{
+       struct bnx2 *bp = dev->priv;
+
+       ering->rx_max_pending = MAX_RX_DESC_CNT;
+       ering->rx_mini_max_pending = 0;
+       ering->rx_jumbo_max_pending = 0;
+
+       ering->rx_pending = bp->rx_ring_size;
+       ering->rx_mini_pending = 0;
+       ering->rx_jumbo_pending = 0;
+
+       ering->tx_max_pending = MAX_TX_DESC_CNT;
+       ering->tx_pending = bp->tx_ring_size;
+}
+
+static int
+bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
+{
+       struct bnx2 *bp = dev->priv;
+
+       if ((ering->rx_pending > MAX_RX_DESC_CNT) ||
+               (ering->tx_pending > MAX_TX_DESC_CNT) ||
+               (ering->tx_pending <= MAX_SKB_FRAGS)) {
+
+               return -EINVAL;
+       }
+       bp->rx_ring_size = ering->rx_pending;
+       bp->tx_ring_size = ering->tx_pending;
+
+       if (netif_running(bp->dev)) {
+               bnx2_netif_stop(bp);
+               bnx2_init_nic(bp);
+               bnx2_netif_start(bp);
+       }
+
+       return 0;
+}
+
+static void
+bnx2_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
+{
+       struct bnx2 *bp = dev->priv;
+
+       epause->autoneg = ((bp->autoneg & AUTONEG_FLOW_CTRL) != 0);
+       epause->rx_pause = ((bp->flow_ctrl & FLOW_CTRL_RX) != 0);
+       epause->tx_pause = ((bp->flow_ctrl & FLOW_CTRL_TX) != 0);
+}
+
+static int
+bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
+{
+       struct bnx2 *bp = dev->priv;
+
+       bp->req_flow_ctrl = 0;
+       if (epause->rx_pause)
+               bp->req_flow_ctrl |= FLOW_CTRL_RX;
+       if (epause->tx_pause)
+               bp->req_flow_ctrl |= FLOW_CTRL_TX;
+
+       if (epause->autoneg) {
+               bp->autoneg |= AUTONEG_FLOW_CTRL;
+       }
+       else {
+               bp->autoneg &= ~AUTONEG_FLOW_CTRL;
+       }
+
+       spin_lock_irq(&bp->phy_lock);
+
+       bnx2_setup_phy(bp);
+
+       spin_unlock_irq(&bp->phy_lock);
+
+       return 0;
+}
+
+static u32
+bnx2_get_rx_csum(struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+
+       return bp->rx_csum;
+}
+
+static int
+bnx2_set_rx_csum(struct net_device *dev, u32 data)
+{
+       struct bnx2 *bp = dev->priv;
+
+       bp->rx_csum = data;
+       return 0;
+}
+
+#define BNX2_NUM_STATS 45
+
+struct {
+       char string[ETH_GSTRING_LEN];
+} bnx2_stats_str_arr[BNX2_NUM_STATS] = {
+       { "rx_bytes" },
+       { "rx_error_bytes" },
+       { "tx_bytes" },
+       { "tx_error_bytes" },
+       { "rx_ucast_packets" },
+       { "rx_mcast_packets" },
+       { "rx_bcast_packets" },
+       { "tx_ucast_packets" },
+       { "tx_mcast_packets" },
+       { "tx_bcast_packets" },
+       { "tx_mac_errors" },
+       { "tx_carrier_errors" },
+       { "rx_crc_errors" },
+       { "rx_align_errors" },
+       { "tx_single_collisions" },
+       { "tx_multi_collisions" },
+       { "tx_deferred" },
+       { "tx_excess_collisions" },
+       { "tx_late_collisions" },
+       { "tx_total_collisions" },
+       { "rx_fragments" },
+       { "rx_jabbers" },
+       { "rx_undersize_packets" },
+       { "rx_oversize_packets" },
+       { "rx_64_byte_packets" },
+       { "rx_65_to_127_byte_packets" },
+       { "rx_128_to_255_byte_packets" },
+       { "rx_256_to_511_byte_packets" },
+       { "rx_512_to_1023_byte_packets" },
+       { "rx_1024_to_1522_byte_packets" },
+       { "rx_1523_to_9022_byte_packets" },
+       { "tx_64_byte_packets" },
+       { "tx_65_to_127_byte_packets" },
+       { "tx_128_to_255_byte_packets" },
+       { "tx_256_to_511_byte_packets" },
+       { "tx_512_to_1023_byte_packets" },
+       { "tx_1024_to_1522_byte_packets" },
+       { "tx_1523_to_9022_byte_packets" },
+       { "rx_xon_frames" },
+       { "rx_xoff_frames" },
+       { "tx_xon_frames" },
+       { "tx_xoff_frames" },
+       { "rx_mac_ctrl_frames" },
+       { "rx_filtered_packets" },
+       { "rx_discards" },
+};
+
+#define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4)
+
+unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
+    STATS_OFFSET32(stat_IfHCInOctets_hi),
+    STATS_OFFSET32(stat_IfHCInBadOctets_hi),
+    STATS_OFFSET32(stat_IfHCOutOctets_hi),
+    STATS_OFFSET32(stat_IfHCOutBadOctets_hi),
+    STATS_OFFSET32(stat_IfHCInUcastPkts_hi),
+    STATS_OFFSET32(stat_IfHCInMulticastPkts_hi),
+    STATS_OFFSET32(stat_IfHCInBroadcastPkts_hi),
+    STATS_OFFSET32(stat_IfHCOutUcastPkts_hi),
+    STATS_OFFSET32(stat_IfHCOutMulticastPkts_hi),
+    STATS_OFFSET32(stat_IfHCOutBroadcastPkts_hi),
+    STATS_OFFSET32(stat_emac_tx_stat_dot3statsinternalmactransmiterrors),
+    STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors),                 
+    STATS_OFFSET32(stat_Dot3StatsFCSErrors),                          
+    STATS_OFFSET32(stat_Dot3StatsAlignmentErrors),                    
+    STATS_OFFSET32(stat_Dot3StatsSingleCollisionFrames),              
+    STATS_OFFSET32(stat_Dot3StatsMultipleCollisionFrames),            
+    STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions),              
+    STATS_OFFSET32(stat_Dot3StatsExcessiveCollisions),                
+    STATS_OFFSET32(stat_Dot3StatsLateCollisions),                     
+    STATS_OFFSET32(stat_EtherStatsCollisions),                        
+    STATS_OFFSET32(stat_EtherStatsFragments),                         
+    STATS_OFFSET32(stat_EtherStatsJabbers),                           
+    STATS_OFFSET32(stat_EtherStatsUndersizePkts),                     
+    STATS_OFFSET32(stat_EtherStatsOverrsizePkts),                     
+    STATS_OFFSET32(stat_EtherStatsPktsRx64Octets),                    
+    STATS_OFFSET32(stat_EtherStatsPktsRx65Octetsto127Octets),         
+    STATS_OFFSET32(stat_EtherStatsPktsRx128Octetsto255Octets),        
+    STATS_OFFSET32(stat_EtherStatsPktsRx256Octetsto511Octets),        
+    STATS_OFFSET32(stat_EtherStatsPktsRx512Octetsto1023Octets),       
+    STATS_OFFSET32(stat_EtherStatsPktsRx1024Octetsto1522Octets),      
+    STATS_OFFSET32(stat_EtherStatsPktsRx1523Octetsto9022Octets),      
+    STATS_OFFSET32(stat_EtherStatsPktsTx64Octets),                    
+    STATS_OFFSET32(stat_EtherStatsPktsTx65Octetsto127Octets),         
+    STATS_OFFSET32(stat_EtherStatsPktsTx128Octetsto255Octets),        
+    STATS_OFFSET32(stat_EtherStatsPktsTx256Octetsto511Octets),        
+    STATS_OFFSET32(stat_EtherStatsPktsTx512Octetsto1023Octets),       
+    STATS_OFFSET32(stat_EtherStatsPktsTx1024Octetsto1522Octets),      
+    STATS_OFFSET32(stat_EtherStatsPktsTx1523Octetsto9022Octets),      
+    STATS_OFFSET32(stat_XonPauseFramesReceived),                      
+    STATS_OFFSET32(stat_XoffPauseFramesReceived),                     
+    STATS_OFFSET32(stat_OutXonSent),                                  
+    STATS_OFFSET32(stat_OutXoffSent),                                 
+    STATS_OFFSET32(stat_MacControlFramesReceived),                    
+    STATS_OFFSET32(stat_IfInFramesL2FilterDiscards),                  
+    STATS_OFFSET32(stat_IfInMBUFDiscards),                            
+};
+
+/* stat_IfHCInBadOctets and stat_Dot3StatsCarrierSenseErrors are
+ * skipped because of errata.
+ */               
+u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
+       8,0,8,8,8,8,8,8,8,8,
+       4,0,4,4,4,4,4,4,4,4,
+       4,4,4,4,4,4,4,4,4,4,
+       4,4,4,4,4,4,4,4,4,4,
+       4,4,4,4,4,
+};
+
+#define BNX2_NUM_TESTS 6
+
+struct {
+       char string[ETH_GSTRING_LEN];
+} bnx2_tests_str_arr[BNX2_NUM_TESTS] = {
+       { "register_test (offline)" },
+       { "memory_test (offline)" },
+       { "loopback_test (offline)" },
+       { "nvram_test (online)" },
+       { "interrupt_test (online)" },
+       { "link_test (online)" },
+};
+
+static int
+bnx2_self_test_count(struct net_device *dev)
+{
+       return BNX2_NUM_TESTS;
+}
+
+static void
+bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
+{
+       struct bnx2 *bp = dev->priv;
+
+       memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS);
+       if (etest->flags & ETH_TEST_FL_OFFLINE) {
+               bnx2_netif_stop(bp);
+               bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
+               bnx2_free_skbs(bp);
+
+               if (bnx2_test_registers(bp) != 0) {
+                       buf[0] = 1;
+                       etest->flags |= ETH_TEST_FL_FAILED;
+               }
+               if (bnx2_test_memory(bp) != 0) {
+                       buf[1] = 1;
+                       etest->flags |= ETH_TEST_FL_FAILED;
+               }
+               if (bnx2_test_loopback(bp) != 0) {
+                       buf[2] = 1;
+                       etest->flags |= ETH_TEST_FL_FAILED;
+               }
+
+               if (!netif_running(bp->dev)) {
+                       bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
+               }
+               else {
+                       bnx2_init_nic(bp);
+                       bnx2_netif_start(bp);
+               }
+
+               /* wait for link up */
+               msleep_interruptible(3000);
+               if ((!bp->link_up) && !(bp->phy_flags & PHY_SERDES_FLAG))
+                       msleep_interruptible(4000);
+       }
+
+       if (bnx2_test_nvram(bp) != 0) {
+               buf[3] = 1;
+               etest->flags |= ETH_TEST_FL_FAILED;
+       }
+       if (bnx2_test_intr(bp) != 0) {
+               buf[4] = 1;
+               etest->flags |= ETH_TEST_FL_FAILED;
+       }
+
+       if (bnx2_test_link(bp) != 0) {
+               buf[5] = 1;
+               etest->flags |= ETH_TEST_FL_FAILED;
+
+       }
+}
+
+static void
+bnx2_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+       switch (stringset) {
+       case ETH_SS_STATS:
+               memcpy(buf, bnx2_stats_str_arr,
+                       sizeof(bnx2_stats_str_arr));
+               break;
+       case ETH_SS_TEST:
+               memcpy(buf, bnx2_tests_str_arr,
+                       sizeof(bnx2_tests_str_arr));
+               break;
+       }
+}
+
+static int
+bnx2_get_stats_count(struct net_device *dev)
+{
+       return BNX2_NUM_STATS;
+}
+
+static void
+bnx2_get_ethtool_stats(struct net_device *dev,
+               struct ethtool_stats *stats, u64 *buf)
+{
+       struct bnx2 *bp = dev->priv;
+       int i;
+       u32 *hw_stats = (u32 *) bp->stats_blk;
+       u8 *stats_len_arr = 0;
+
+       if (hw_stats == NULL) {
+               memset(buf, 0, sizeof(u64) * BNX2_NUM_STATS);
+               return;
+       }
+
+       if (CHIP_NUM(bp) == CHIP_NUM_5706)
+               stats_len_arr = bnx2_5706_stats_len_arr;
+
+       for (i = 0; i < BNX2_NUM_STATS; i++) {
+               if (stats_len_arr[i] == 0) {
+                       /* skip this counter */
+                       buf[i] = 0;
+                       continue;
+               }
+               if (stats_len_arr[i] == 4) {
+                       /* 4-byte counter */
+                       buf[i] = (u64)
+                               *(hw_stats + bnx2_stats_offset_arr[i]);
+                       continue;
+               }
+               /* 8-byte counter */
+               buf[i] = (((u64) *(hw_stats +
+                                       bnx2_stats_offset_arr[i])) << 32) +
+                               *(hw_stats + bnx2_stats_offset_arr[i] + 1);
+       }
+}
+
+static int
+bnx2_phys_id(struct net_device *dev, u32 data)
+{
+       struct bnx2 *bp = dev->priv;
+       int i;
+       u32 save;
+
+       if (data == 0)
+               data = 2;
+
+       save = REG_RD(bp, BNX2_MISC_CFG);
+       REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC);
+
+       for (i = 0; i < (data * 2); i++) {
+               if ((i % 2) == 0) {
+                       REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE);
+               }
+               else {
+                       REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE |
+                               BNX2_EMAC_LED_1000MB_OVERRIDE |
+                               BNX2_EMAC_LED_100MB_OVERRIDE |
+                               BNX2_EMAC_LED_10MB_OVERRIDE |
+                               BNX2_EMAC_LED_TRAFFIC_OVERRIDE |
+                               BNX2_EMAC_LED_TRAFFIC);
+               }
+               msleep_interruptible(500);
+               if (signal_pending(current))
+                       break;
+       }
+       REG_WR(bp, BNX2_EMAC_LED, 0);
+       REG_WR(bp, BNX2_MISC_CFG, save);
+       return 0;
+}
+
+static struct ethtool_ops bnx2_ethtool_ops = {
+       .get_settings           = bnx2_get_settings,
+       .set_settings           = bnx2_set_settings,
+       .get_drvinfo            = bnx2_get_drvinfo,
+       .get_wol                = bnx2_get_wol,
+       .set_wol                = bnx2_set_wol,
+       .nway_reset             = bnx2_nway_reset,
+       .get_link               = ethtool_op_get_link,
+       .get_eeprom_len         = bnx2_get_eeprom_len,
+       .get_eeprom             = bnx2_get_eeprom,
+       .set_eeprom             = bnx2_set_eeprom,
+       .get_coalesce           = bnx2_get_coalesce,
+       .set_coalesce           = bnx2_set_coalesce,
+       .get_ringparam          = bnx2_get_ringparam,
+       .set_ringparam          = bnx2_set_ringparam,
+       .get_pauseparam         = bnx2_get_pauseparam,
+       .set_pauseparam         = bnx2_set_pauseparam,
+       .get_rx_csum            = bnx2_get_rx_csum,
+       .set_rx_csum            = bnx2_set_rx_csum,
+       .get_tx_csum            = ethtool_op_get_tx_csum,
+       .set_tx_csum            = ethtool_op_set_tx_csum,
+       .get_sg                 = ethtool_op_get_sg,
+       .set_sg                 = ethtool_op_set_sg,
+#ifdef BCM_TSO
+       .get_tso                = ethtool_op_get_tso,
+       .set_tso                = ethtool_op_set_tso,
+#endif
+       .self_test_count        = bnx2_self_test_count,
+       .self_test              = bnx2_self_test,
+       .get_strings            = bnx2_get_strings,
+       .phys_id                = bnx2_phys_id,
+       .get_stats_count        = bnx2_get_stats_count,
+       .get_ethtool_stats      = bnx2_get_ethtool_stats,
+};
+
+/* Called with rtnl_lock */
+static int
+bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+       struct bnx2 *bp = dev->priv;
+       int err;
+
+       switch(cmd) {
+       case SIOCGMIIPHY:
+               data->phy_id = bp->phy_addr;
+
+               /* fallthru */
+       case SIOCGMIIREG: {
+               u32 mii_regval;
+
+               spin_lock_irq(&bp->phy_lock);
+               err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval);
+               spin_unlock_irq(&bp->phy_lock);
+
+               data->val_out = mii_regval;
+
+               return err;
+       }
+
+       case SIOCSMIIREG:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+
+               spin_lock_irq(&bp->phy_lock);
+               err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in);
+               spin_unlock_irq(&bp->phy_lock);
+
+               return err;
+
+       default:
+               /* do nothing */
+               break;
+       }
+       return -EOPNOTSUPP;
+}
+
+/* Called with rtnl_lock */
+static int
+bnx2_change_mac_addr(struct net_device *dev, void *p)
+{
+       struct sockaddr *addr = p;
+       struct bnx2 *bp = dev->priv;
+
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+       if (netif_running(dev))
+               bnx2_set_mac_addr(bp);
+
+       return 0;
+}
+
+/* Called with rtnl_lock */
+static int
+bnx2_change_mtu(struct net_device *dev, int new_mtu)
+{
+       struct bnx2 *bp = dev->priv;
+
+       if (((new_mtu + ETH_HLEN) > MAX_ETHERNET_JUMBO_PACKET_SIZE) ||
+               ((new_mtu + ETH_HLEN) < MIN_ETHERNET_PACKET_SIZE))
+               return -EINVAL;
+
+       dev->mtu = new_mtu;
+       if (netif_running(dev)) {
+               bnx2_netif_stop(bp);
+
+               bnx2_init_nic(bp);
+
+               bnx2_netif_start(bp);
+       }
+       return 0;
+}
+
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+static void
+poll_bnx2(struct net_device *dev)
+{
+       struct bnx2 *bp = dev->priv;
+
+       disable_irq(bp->pdev->irq);
+       bnx2_interrupt(bp->pdev->irq, dev, NULL);
+       enable_irq(bp->pdev->irq);
+}
+#endif
+
+static int __devinit
+bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
+{
+       struct bnx2 *bp;
+       unsigned long mem_len;
+       int rc;
+       u32 reg;
+
+       SET_MODULE_OWNER(dev);
+       SET_NETDEV_DEV(dev, &pdev->dev);
+       bp = dev->priv;
+
+       bp->flags = 0;
+       bp->phy_flags = 0;
+
+       /* enable device (incl. PCI PM wakeup), and bus-mastering */
+       rc = pci_enable_device(pdev);
+       if (rc) {
+               printk(KERN_ERR PFX "Cannot enable PCI device, aborting.");
+               goto err_out;
+       }
+
+       if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+               printk(KERN_ERR PFX "Cannot find PCI device base address, "
+                      "aborting.\n");
+               rc = -ENODEV;
+               goto err_out_disable;
+       }
+
+       rc = pci_request_regions(pdev, DRV_MODULE_NAME);
+       if (rc) {
+               printk(KERN_ERR PFX "Cannot obtain PCI resources, aborting.\n");
+               goto err_out_disable;
+       }
+
+       pci_set_master(pdev);
+
+       bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+       if (bp->pm_cap == 0) {
+               printk(KERN_ERR PFX "Cannot find power management capability, "
+                              "aborting.\n");
+               rc = -EIO;
+               goto err_out_release;
+       }
+
+       bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
+       if (bp->pcix_cap == 0) {
+               printk(KERN_ERR PFX "Cannot find PCIX capability, aborting.\n");
+               rc = -EIO;
+               goto err_out_release;
+       }
+
+       if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
+               bp->flags |= USING_DAC_FLAG;
+               if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
+                       printk(KERN_ERR PFX "pci_set_consistent_dma_mask "
+                              "failed, aborting.\n");
+                       rc = -EIO;
+                       goto err_out_release;
+               }
+       }
+       else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
+               printk(KERN_ERR PFX "System does not support DMA, aborting.\n");
+               rc = -EIO;
+               goto err_out_release;
+       }
+
+       bp->dev = dev;
+       bp->pdev = pdev;
+
+       spin_lock_init(&bp->phy_lock);
+       spin_lock_init(&bp->tx_lock);
+       INIT_WORK(&bp->reset_task, bnx2_reset_task, bp);
+
+       dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
+       mem_len = MB_GET_CID_ADDR(17);
+       dev->mem_end = dev->mem_start + mem_len;
+       dev->irq = pdev->irq;
+
+       bp->regview = ioremap_nocache(dev->base_addr, mem_len);
+
+       if (!bp->regview) {
+               printk(KERN_ERR PFX "Cannot map register space, aborting.\n");
+               rc = -ENOMEM;
+               goto err_out_release;
+       }
+
+       /* Configure byte swap and enable write to the reg_window registers.
+        * Rely on CPU to do target byte swapping on big endian systems
+        * The chip's target access swapping will not swap all accesses
+        */
+       pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG,
+                              BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+                              BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
+
+       bnx2_set_power_state(bp, 0);
+
+       bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
+
+       bp->phy_addr = 1;
+
+       /* Get bus information. */
+       reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
+       if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
+               u32 clkreg;
+
+               bp->flags |= PCIX_FLAG;
+
+               clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS);
+               
+               clkreg &= BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
+               switch (clkreg) {
+               case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
+                       bp->bus_speed_mhz = 133;
+                       break;
+
+               case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
+                       bp->bus_speed_mhz = 100;
+                       break;
+
+               case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
+               case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
+                       bp->bus_speed_mhz = 66;
+                       break;
+
+               case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
+               case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
+                       bp->bus_speed_mhz = 50;
+                       break;
+
+               case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
+               case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
+               case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
+                       bp->bus_speed_mhz = 33;
+                       break;
+               }
+       }
+       else {
+               if (reg & BNX2_PCICFG_MISC_STATUS_M66EN)
+                       bp->bus_speed_mhz = 66;
+               else
+                       bp->bus_speed_mhz = 33;
+       }
+
+       if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET)
+               bp->flags |= PCI_32BIT_FLAG;
+
+       /* 5706A0 may falsely detect SERR and PERR. */
+       if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+               reg = REG_RD(bp, PCI_COMMAND);
+               reg &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+               REG_WR(bp, PCI_COMMAND, reg);
+       }
+       else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) &&
+               !(bp->flags & PCIX_FLAG)) {
+
+               printk(KERN_ERR PFX "5706 A1 can only be used in a PCIX bus, "
+                      "aborting.\n");
+               goto err_out_unmap;
+       }
+
+       bnx2_init_nvram(bp);
+
+       /* Get the permanent MAC address.  First we need to make sure the
+        * firmware is actually running.
+        */
+       reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE);
+
+       if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
+           BNX2_DEV_INFO_SIGNATURE_MAGIC) {
+               printk(KERN_ERR PFX "Firmware not running, aborting.\n");
+               rc = -ENODEV;
+               goto err_out_unmap;
+       }
+
+       bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
+                               BNX2_DEV_INFO_BC_REV);
+
+       reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER);
+       bp->mac_addr[0] = (u8) (reg >> 8);
+       bp->mac_addr[1] = (u8) reg;
+
+       reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER);
+       bp->mac_addr[2] = (u8) (reg >> 24);
+       bp->mac_addr[3] = (u8) (reg >> 16);
+       bp->mac_addr[4] = (u8) (reg >> 8);
+       bp->mac_addr[5] = (u8) reg;
+
+       bp->tx_ring_size = MAX_TX_DESC_CNT;
+       bp->rx_ring_size = 100;
+
+       bp->rx_csum = 1;
+
+       bp->rx_offset = sizeof(struct l2_fhdr) + 2;
+
+       bp->tx_quick_cons_trip_int = 20;
+       bp->tx_quick_cons_trip = 20;
+       bp->tx_ticks_int = 80;
+       bp->tx_ticks = 80;
+               
+       bp->rx_quick_cons_trip_int = 6;
+       bp->rx_quick_cons_trip = 6;
+       bp->rx_ticks_int = 18;
+       bp->rx_ticks = 18;
+
+       bp->stats_ticks = 1000000 & 0xffff00;
+
+       bp->timer_interval =  HZ;
+
+       /* Disable WOL support if we are running on a SERDES chip. */
+       if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
+               bp->phy_flags |= PHY_SERDES_FLAG;
+               bp->flags |= NO_WOL_FLAG;
+       }
+
+       if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+               bp->tx_quick_cons_trip_int =
+                       bp->tx_quick_cons_trip;
+               bp->tx_ticks_int = bp->tx_ticks;
+               bp->rx_quick_cons_trip_int =
+                       bp->rx_quick_cons_trip;
+               bp->rx_ticks_int = bp->rx_ticks;
+               bp->comp_prod_trip_int = bp->comp_prod_trip;
+               bp->com_ticks_int = bp->com_ticks;
+               bp->cmd_ticks_int = bp->cmd_ticks;
+       }
+
+       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;
+       }
+       else {
+               bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
+       }
+
+       bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
+
+       return 0;
+
+err_out_unmap:
+       if (bp->regview) {
+               iounmap(bp->regview);
+       }
+
+err_out_release:
+       pci_release_regions(pdev);
+
+err_out_disable:
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+
+err_out:
+       return rc;
+}
+
+static int __devinit
+bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+       static int version_printed = 0;
+       struct net_device *dev = NULL;
+       struct bnx2 *bp;
+       int rc, i;
+
+       if (version_printed++ == 0)
+               printk(KERN_INFO "%s", version);
+
+       /* dev zeroed in init_etherdev */
+       dev = alloc_etherdev(sizeof(*bp));
+
+       if (!dev)
+               return -ENOMEM;
+
+       rc = bnx2_init_board(pdev, dev);
+       if (rc < 0) {
+               free_netdev(dev);
+               return rc;
+       }
+
+       dev->open = bnx2_open;
+       dev->hard_start_xmit = bnx2_start_xmit;
+       dev->stop = bnx2_close;
+       dev->get_stats = bnx2_get_stats;
+       dev->set_multicast_list = bnx2_set_rx_mode;
+       dev->do_ioctl = bnx2_ioctl;
+       dev->set_mac_address = bnx2_change_mac_addr;
+       dev->change_mtu = bnx2_change_mtu;
+       dev->tx_timeout = bnx2_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef BCM_VLAN
+       dev->vlan_rx_register = bnx2_vlan_rx_register;
+       dev->vlan_rx_kill_vid = bnx2_vlan_rx_kill_vid;
+#endif
+       dev->poll = bnx2_poll;
+       dev->ethtool_ops = &bnx2_ethtool_ops;
+       dev->weight = 64;
+
+       bp = dev->priv;
+
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+       dev->poll_controller = poll_bnx2;
+#endif
+
+       if ((rc = register_netdev(dev))) {
+               printk(KERN_ERR PFX "Cannot register net device\n");
+               if (bp->regview)
+                       iounmap(bp->regview);
+               pci_release_regions(pdev);
+               pci_disable_device(pdev);
+               pci_set_drvdata(pdev, NULL);
+               free_netdev(dev);
+               return rc;
+       }
+
+       pci_set_drvdata(pdev, dev);
+
+       memcpy(dev->dev_addr, bp->mac_addr, 6);
+       bp->name = board_info[ent->driver_data].name,
+       printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz found at mem %lx, "
+               "IRQ %d, ",
+               dev->name,
+               bp->name,
+               ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
+               ((CHIP_ID(bp) & 0x0ff0) >> 4),
+               ((bp->flags & PCIX_FLAG) ? "-X" : ""),
+               ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
+               bp->bus_speed_mhz,
+               dev->base_addr,
+               bp->pdev->irq);
+
+       printk("node addr ");
+       for (i = 0; i < 6; i++)
+               printk("%2.2x", dev->dev_addr[i]);
+       printk("\n");
+
+       dev->features |= NETIF_F_SG;
+       if (bp->flags & USING_DAC_FLAG)
+               dev->features |= NETIF_F_HIGHDMA;
+       dev->features |= NETIF_F_IP_CSUM;
+#ifdef BCM_VLAN
+       dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+#endif
+#ifdef BCM_TSO
+       dev->features |= NETIF_F_TSO;
+#endif
+
+       netif_carrier_off(bp->dev);
+
+       return 0;
+}
+
+static void __devexit
+bnx2_remove_one(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct bnx2 *bp = dev->priv;
+
+       unregister_netdev(dev);
+
+       if (bp->regview)
+               iounmap(bp->regview);
+
+       free_netdev(dev);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+}
+
+static int
+bnx2_suspend(struct pci_dev *pdev, u32 state)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct bnx2 *bp = dev->priv;
+       u32 reset_code;
+
+       if (!netif_running(dev))
+               return 0;
+
+       bnx2_netif_stop(bp);
+       netif_device_detach(dev);
+       del_timer_sync(&bp->timer);
+       if (bp->wol)
+               reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
+       else
+               reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
+       bnx2_reset_chip(bp, reset_code);
+       bnx2_free_skbs(bp);
+       bnx2_set_power_state(bp, state);
+       return 0;
+}
+
+static int
+bnx2_resume(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct bnx2 *bp = dev->priv;
+
+       if (!netif_running(dev))
+               return 0;
+
+       bnx2_set_power_state(bp, 0);
+       netif_device_attach(dev);
+       bnx2_init_nic(bp);
+       bnx2_netif_start(bp);
+       return 0;
+}
+
+static struct pci_driver bnx2_pci_driver = {
+       name:           DRV_MODULE_NAME,
+       id_table:       bnx2_pci_tbl,
+       probe:          bnx2_init_one,
+       remove:         __devexit_p(bnx2_remove_one),
+       suspend:        bnx2_suspend,
+       resume:         bnx2_resume,
+};
+
+static int __init bnx2_init(void)
+{
+       return pci_module_init(&bnx2_pci_driver);
+}
+
+static void __exit bnx2_cleanup(void)
+{
+       pci_unregister_driver(&bnx2_pci_driver);
+}
+
+module_init(bnx2_init);
+module_exit(bnx2_cleanup);
+
+
+
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
new file mode 100644 (file)
index 0000000..8214a28
--- /dev/null
@@ -0,0 +1,4352 @@
+/* bnx2.h: Broadcom NX2 network driver.
+ *
+ * Copyright (c) 2004, 2005 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.
+ *
+ * Written by: Michael Chan  (mchan@broadcom.com)
+ */
+
+
+#ifndef BNX2_H
+#define BNX2_H
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/dma-mapping.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <linux/time.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#ifdef NETIF_F_HW_VLAN_TX
+#include <linux/if_vlan.h>
+#define BCM_VLAN 1
+#endif
+#ifdef NETIF_F_TSO
+#include <net/ip.h>
+#include <net/tcp.h>
+#include <net/checksum.h>
+#define BCM_TSO 1
+#endif
+#include <linux/workqueue.h>
+#include <linux/crc32.h>
+
+/* Hardware data structures and register definitions automatically
+ * generated from RTL code. Do not modify.
+ */
+
+/*
+ *  tx_bd definition
+ */
+struct tx_bd {
+       u32 tx_bd_haddr_hi;
+       u32 tx_bd_haddr_lo;                                   
+       u32 tx_bd_mss_nbytes;                                     
+       u32 tx_bd_vlan_tag_flags;                                      
+               #define TX_BD_FLAGS_CONN_FAULT          (1<<0)
+               #define TX_BD_FLAGS_TCP_UDP_CKSUM       (1<<1)
+               #define TX_BD_FLAGS_IP_CKSUM            (1<<2)
+               #define TX_BD_FLAGS_VLAN_TAG            (1<<3)
+               #define TX_BD_FLAGS_COAL_NOW            (1<<4)
+               #define TX_BD_FLAGS_DONT_GEN_CRC        (1<<5)
+               #define TX_BD_FLAGS_END                 (1<<6)
+               #define TX_BD_FLAGS_START               (1<<7)
+               #define TX_BD_FLAGS_SW_OPTION_WORD      (0x1f<<8)
+               #define TX_BD_FLAGS_SW_FLAGS            (1<<13)
+               #define TX_BD_FLAGS_SW_SNAP             (1<<14)
+               #define TX_BD_FLAGS_SW_LSO              (1<<15)
+
+};
+
+
+/*
+ *  rx_bd definition
+ */
+struct rx_bd {
+       u32 rx_bd_haddr_hi;
+       u32 rx_bd_haddr_lo;
+       u32 rx_bd_len;
+       u32 rx_bd_flags;
+               #define RX_BD_FLAGS_NOPUSH              (1<<0)
+               #define RX_BD_FLAGS_DUMMY               (1<<1)
+               #define RX_BD_FLAGS_END                 (1<<2)
+               #define RX_BD_FLAGS_START               (1<<3)
+
+};
+
+
+/*
+ *  status_block definition
+ */
+struct status_block {
+       u32 status_attn_bits;
+               #define STATUS_ATTN_BITS_LINK_STATE             (1L<<0)
+               #define STATUS_ATTN_BITS_TX_SCHEDULER_ABORT     (1L<<1)
+               #define STATUS_ATTN_BITS_TX_BD_READ_ABORT       (1L<<2)
+               #define STATUS_ATTN_BITS_TX_BD_CACHE_ABORT      (1L<<3)
+               #define STATUS_ATTN_BITS_TX_PROCESSOR_ABORT     (1L<<4)
+               #define STATUS_ATTN_BITS_TX_DMA_ABORT           (1L<<5)
+               #define STATUS_ATTN_BITS_TX_PATCHUP_ABORT       (1L<<6)
+               #define STATUS_ATTN_BITS_TX_ASSEMBLER_ABORT     (1L<<7)
+               #define STATUS_ATTN_BITS_RX_PARSER_MAC_ABORT    (1L<<8)
+               #define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT        (1L<<9)
+               #define STATUS_ATTN_BITS_RX_MBUF_ABORT          (1L<<10)
+               #define STATUS_ATTN_BITS_RX_LOOKUP_ABORT        (1L<<11)
+               #define STATUS_ATTN_BITS_RX_PROCESSOR_ABORT     (1L<<12)
+               #define STATUS_ATTN_BITS_RX_V2P_ABORT           (1L<<13)
+               #define STATUS_ATTN_BITS_RX_BD_CACHE_ABORT      (1L<<14)
+               #define STATUS_ATTN_BITS_RX_DMA_ABORT           (1L<<15)
+               #define STATUS_ATTN_BITS_COMPLETION_ABORT       (1L<<16)
+               #define STATUS_ATTN_BITS_HOST_COALESCE_ABORT    (1L<<17)
+               #define STATUS_ATTN_BITS_MAILBOX_QUEUE_ABORT    (1L<<18)
+               #define STATUS_ATTN_BITS_CONTEXT_ABORT          (1L<<19)
+               #define STATUS_ATTN_BITS_CMD_SCHEDULER_ABORT    (1L<<20)
+               #define STATUS_ATTN_BITS_CMD_PROCESSOR_ABORT    (1L<<21)
+               #define STATUS_ATTN_BITS_MGMT_PROCESSOR_ABORT   (1L<<22)
+               #define STATUS_ATTN_BITS_MAC_ABORT              (1L<<23)
+               #define STATUS_ATTN_BITS_TIMER_ABORT            (1L<<24)
+               #define STATUS_ATTN_BITS_DMAE_ABORT             (1L<<25)
+               #define STATUS_ATTN_BITS_FLSH_ABORT             (1L<<26)
+               #define STATUS_ATTN_BITS_GRC_ABORT              (1L<<27)
+               #define STATUS_ATTN_BITS_PARITY_ERROR           (1L<<31)
+
+       u32 status_attn_bits_ack;
+#if defined(__BIG_ENDIAN)
+       u16 status_tx_quick_consumer_index0;
+       u16 status_tx_quick_consumer_index1;
+       u16 status_tx_quick_consumer_index2;
+       u16 status_tx_quick_consumer_index3;
+       u16 status_rx_quick_consumer_index0;
+       u16 status_rx_quick_consumer_index1;
+       u16 status_rx_quick_consumer_index2;
+       u16 status_rx_quick_consumer_index3;
+       u16 status_rx_quick_consumer_index4;
+       u16 status_rx_quick_consumer_index5;
+       u16 status_rx_quick_consumer_index6;
+       u16 status_rx_quick_consumer_index7;
+       u16 status_rx_quick_consumer_index8;
+       u16 status_rx_quick_consumer_index9;
+       u16 status_rx_quick_consumer_index10;
+       u16 status_rx_quick_consumer_index11;
+       u16 status_rx_quick_consumer_index12;
+       u16 status_rx_quick_consumer_index13;
+       u16 status_rx_quick_consumer_index14;
+       u16 status_rx_quick_consumer_index15;
+       u16 status_completion_producer_index;
+       u16 status_cmd_consumer_index;
+       u16 status_idx;
+       u16 status_unused;
+#elif defined(__LITTLE_ENDIAN)
+       u16 status_tx_quick_consumer_index1;
+       u16 status_tx_quick_consumer_index0;
+       u16 status_tx_quick_consumer_index3;
+       u16 status_tx_quick_consumer_index2;
+       u16 status_rx_quick_consumer_index1;
+       u16 status_rx_quick_consumer_index0;
+       u16 status_rx_quick_consumer_index3;
+       u16 status_rx_quick_consumer_index2;
+       u16 status_rx_quick_consumer_index5;
+       u16 status_rx_quick_consumer_index4;
+       u16 status_rx_quick_consumer_index7;
+       u16 status_rx_quick_consumer_index6;
+       u16 status_rx_quick_consumer_index9;
+       u16 status_rx_quick_consumer_index8;
+       u16 status_rx_quick_consumer_index11;
+       u16 status_rx_quick_consumer_index10;
+       u16 status_rx_quick_consumer_index13;
+       u16 status_rx_quick_consumer_index12;
+       u16 status_rx_quick_consumer_index15;
+       u16 status_rx_quick_consumer_index14;
+       u16 status_cmd_consumer_index;
+       u16 status_completion_producer_index;
+       u16 status_unused;
+       u16 status_idx;
+#endif
+};
+
+
+/*
+ *  statistics_block definition
+ */
+struct statistics_block {
+       u32 stat_IfHCInOctets_hi;
+       u32 stat_IfHCInOctets_lo;
+       u32 stat_IfHCInBadOctets_hi;
+       u32 stat_IfHCInBadOctets_lo;
+       u32 stat_IfHCOutOctets_hi;
+       u32 stat_IfHCOutOctets_lo;
+       u32 stat_IfHCOutBadOctets_hi;
+       u32 stat_IfHCOutBadOctets_lo;
+       u32 stat_IfHCInUcastPkts_hi;
+       u32 stat_IfHCInUcastPkts_lo;
+       u32 stat_IfHCInMulticastPkts_hi;
+       u32 stat_IfHCInMulticastPkts_lo;
+       u32 stat_IfHCInBroadcastPkts_hi;
+       u32 stat_IfHCInBroadcastPkts_lo;
+       u32 stat_IfHCOutUcastPkts_hi;
+       u32 stat_IfHCOutUcastPkts_lo;
+       u32 stat_IfHCOutMulticastPkts_hi;
+       u32 stat_IfHCOutMulticastPkts_lo;
+       u32 stat_IfHCOutBroadcastPkts_hi;
+       u32 stat_IfHCOutBroadcastPkts_lo;
+       u32 stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
+       u32 stat_Dot3StatsCarrierSenseErrors;
+       u32 stat_Dot3StatsFCSErrors;
+       u32 stat_Dot3StatsAlignmentErrors;
+       u32 stat_Dot3StatsSingleCollisionFrames;
+       u32 stat_Dot3StatsMultipleCollisionFrames;
+       u32 stat_Dot3StatsDeferredTransmissions;
+       u32 stat_Dot3StatsExcessiveCollisions;
+       u32 stat_Dot3StatsLateCollisions;
+       u32 stat_EtherStatsCollisions;
+       u32 stat_EtherStatsFragments;
+       u32 stat_EtherStatsJabbers;
+       u32 stat_EtherStatsUndersizePkts;
+       u32 stat_EtherStatsOverrsizePkts;
+       u32 stat_EtherStatsPktsRx64Octets;
+       u32 stat_EtherStatsPktsRx65Octetsto127Octets;
+       u32 stat_EtherStatsPktsRx128Octetsto255Octets;
+       u32 stat_EtherStatsPktsRx256Octetsto511Octets;
+       u32 stat_EtherStatsPktsRx512Octetsto1023Octets;
+       u32 stat_EtherStatsPktsRx1024Octetsto1522Octets;
+       u32 stat_EtherStatsPktsRx1523Octetsto9022Octets;
+       u32 stat_EtherStatsPktsTx64Octets;
+       u32 stat_EtherStatsPktsTx65Octetsto127Octets;
+       u32 stat_EtherStatsPktsTx128Octetsto255Octets;
+       u32 stat_EtherStatsPktsTx256Octetsto511Octets;
+       u32 stat_EtherStatsPktsTx512Octetsto1023Octets;
+       u32 stat_EtherStatsPktsTx1024Octetsto1522Octets;
+       u32 stat_EtherStatsPktsTx1523Octetsto9022Octets;
+       u32 stat_XonPauseFramesReceived;
+       u32 stat_XoffPauseFramesReceived;
+       u32 stat_OutXonSent;
+       u32 stat_OutXoffSent;
+       u32 stat_FlowControlDone;
+       u32 stat_MacControlFramesReceived;
+       u32 stat_XoffStateEntered;
+       u32 stat_IfInFramesL2FilterDiscards;
+       u32 stat_IfInRuleCheckerDiscards;
+       u32 stat_IfInFTQDiscards;
+       u32 stat_IfInMBUFDiscards;
+       u32 stat_IfInRuleCheckerP4Hit;
+       u32 stat_CatchupInRuleCheckerDiscards;
+       u32 stat_CatchupInFTQDiscards;
+       u32 stat_CatchupInMBUFDiscards;
+       u32 stat_CatchupInRuleCheckerP4Hit;
+       u32 stat_GenStat00;
+       u32 stat_GenStat01;
+       u32 stat_GenStat02;
+       u32 stat_GenStat03;
+       u32 stat_GenStat04;
+       u32 stat_GenStat05;
+       u32 stat_GenStat06;
+       u32 stat_GenStat07;
+       u32 stat_GenStat08;
+       u32 stat_GenStat09;
+       u32 stat_GenStat10;
+       u32 stat_GenStat11;
+       u32 stat_GenStat12;
+       u32 stat_GenStat13;
+       u32 stat_GenStat14;
+       u32 stat_GenStat15;
+};
+
+
+/*
+ *  l2_fhdr definition
+ */
+struct l2_fhdr {
+#if defined(__BIG_ENDIAN)
+       u16 l2_fhdr_errors;
+       u16 l2_fhdr_status;
+#elif defined(__LITTLE_ENDIAN)
+       u16 l2_fhdr_status;
+       u16 l2_fhdr_errors;
+#endif
+               #define L2_FHDR_ERRORS_BAD_CRC          (1<<1)
+               #define L2_FHDR_ERRORS_PHY_DECODE       (1<<2)
+               #define L2_FHDR_ERRORS_ALIGNMENT        (1<<3)
+               #define L2_FHDR_ERRORS_TOO_SHORT        (1<<4)
+               #define L2_FHDR_ERRORS_GIANT_FRAME      (1<<5)
+
+               #define L2_FHDR_STATUS_RULE_CLASS       (0x7<<0)
+               #define L2_FHDR_STATUS_RULE_P2          (1<<3)
+               #define L2_FHDR_STATUS_RULE_P3          (1<<4)
+               #define L2_FHDR_STATUS_RULE_P4          (1<<5)
+               #define L2_FHDR_STATUS_L2_VLAN_TAG      (1<<6)
+               #define L2_FHDR_STATUS_L2_LLC_SNAP      (1<<7)
+               #define L2_FHDR_STATUS_RSS_HASH         (1<<8)
+               #define L2_FHDR_STATUS_IP_DATAGRAM      (1<<13)
+               #define L2_FHDR_STATUS_TCP_SEGMENT      (1<<14)
+               #define L2_FHDR_STATUS_UDP_DATAGRAM     (1<<15)
+
+       u32 l2_fhdr_hash;
+#if defined(__BIG_ENDIAN)
+       u16 l2_fhdr_pkt_len;
+       u16 l2_fhdr_vlan_tag;
+       u16 l2_fhdr_ip_xsum;
+       u16 l2_fhdr_tcp_udp_xsum;
+#elif defined(__LITTLE_ENDIAN)
+       u16 l2_fhdr_vlan_tag;
+       u16 l2_fhdr_pkt_len;
+       u16 l2_fhdr_tcp_udp_xsum;
+       u16 l2_fhdr_ip_xsum;
+#endif
+};
+
+
+/*
+ *  l2_context definition
+ */
+#define BNX2_L2CTX_TYPE                                        0x00000000
+#define BNX2_L2CTX_TYPE_SIZE_L2                                 ((0xc0/0x20)<<16)
+#define BNX2_L2CTX_TYPE_TYPE                            (0xf<<28)
+#define BNX2_L2CTX_TYPE_TYPE_EMPTY                      (0<<28)
+#define BNX2_L2CTX_TYPE_TYPE_L2                                 (1<<28)
+
+#define BNX2_L2CTX_TX_HOST_BIDX                                0x00000088
+#define BNX2_L2CTX_EST_NBD                             0x00000088
+#define BNX2_L2CTX_CMD_TYPE                            0x00000088
+#define BNX2_L2CTX_CMD_TYPE_TYPE                        (0xf<<24)
+#define BNX2_L2CTX_CMD_TYPE_TYPE_L2                     (0<<24)
+#define BNX2_L2CTX_CMD_TYPE_TYPE_TCP                    (1<<24)
+
+#define BNX2_L2CTX_TX_HOST_BSEQ                                0x00000090
+#define BNX2_L2CTX_TSCH_BSEQ                           0x00000094
+#define BNX2_L2CTX_TBDR_BSEQ                           0x00000098
+#define BNX2_L2CTX_TBDR_BOFF                           0x0000009c
+#define BNX2_L2CTX_TBDR_BIDX                           0x0000009c
+#define BNX2_L2CTX_TBDR_BHADDR_HI                      0x000000a0
+#define BNX2_L2CTX_TBDR_BHADDR_LO                      0x000000a4
+#define BNX2_L2CTX_TXP_BOFF                            0x000000a8
+#define BNX2_L2CTX_TXP_BIDX                            0x000000a8
+#define BNX2_L2CTX_TXP_BSEQ                            0x000000ac
+
+
+/*
+ *  l2_bd_chain_context definition
+ */
+#define BNX2_L2CTX_BD_PRE_READ                         0x00000000
+#define BNX2_L2CTX_CTX_SIZE                            0x00000000
+#define BNX2_L2CTX_CTX_TYPE                            0x00000000
+#define BNX2_L2CTX_CTX_TYPE_SIZE_L2                     ((0x20/20)<<16)
+#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE             (0xf<<28)
+#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED   (0<<28)
+#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE       (1<<28)
+
+#define BNX2_L2CTX_HOST_BDIDX                          0x00000004
+#define BNX2_L2CTX_HOST_BSEQ                           0x00000008
+#define BNX2_L2CTX_NX_BSEQ                             0x0000000c
+#define BNX2_L2CTX_NX_BDHADDR_HI                       0x00000010
+#define BNX2_L2CTX_NX_BDHADDR_LO                       0x00000014
+#define BNX2_L2CTX_NX_BDIDX                            0x00000018
+
+
+/*
+ *  pci_config_l definition
+ *  offset: 0000
+ */
+#define BNX2_PCICFG_MISC_CONFIG                                0x00000068
+#define BNX2_PCICFG_MISC_CONFIG_TARGET_BYTE_SWAP        (1L<<2)
+#define BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP     (1L<<3)
+#define BNX2_PCICFG_MISC_CONFIG_CLOCK_CTL_ENA           (1L<<5)
+#define BNX2_PCICFG_MISC_CONFIG_TARGET_GRC_WORD_SWAP    (1L<<6)
+#define BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA          (1L<<7)
+#define BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ            (1L<<8)
+#define BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY            (1L<<9)
+#define BNX2_PCICFG_MISC_CONFIG_ASIC_METAL_REV          (0xffL<<16)
+#define BNX2_PCICFG_MISC_CONFIG_ASIC_BASE_REV           (0xfL<<24)
+#define BNX2_PCICFG_MISC_CONFIG_ASIC_ID                         (0xfL<<28)
+
+#define BNX2_PCICFG_MISC_STATUS                                0x0000006c
+#define BNX2_PCICFG_MISC_STATUS_INTA_VALUE              (1L<<0)
+#define BNX2_PCICFG_MISC_STATUS_32BIT_DET               (1L<<1)
+#define BNX2_PCICFG_MISC_STATUS_M66EN                   (1L<<2)
+#define BNX2_PCICFG_MISC_STATUS_PCIX_DET                (1L<<3)
+#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED              (0x3L<<4)
+#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_66           (0L<<4)
+#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_100          (1L<<4)
+#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_133          (2L<<4)
+#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_PCI_MODE     (3L<<4)
+
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS             0x00000070
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET      (0xfL<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ        (0L<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ        (1L<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ        (2L<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ        (3L<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ        (4L<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ        (5L<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ        (6L<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ       (7L<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW  (0xfL<<0)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE     (1L<<6)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT         (1L<<7)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC     (0x7L<<8)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_UNDEF       (0L<<8)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12  (1L<<8)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6   (2L<<8)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62  (4L<<8)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PLAY_DEAD    (1L<<11)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED   (0xfL<<12)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100       (0L<<12)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80        (1L<<12)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_50        (2L<<12)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40        (4L<<12)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25        (8L<<12)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP    (1L<<16)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_PLL_STOP         (1L<<17)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED_18  (1L<<18)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_USE_SPD_DET  (1L<<19)
+#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED     (0xfffL<<20)
+
+#define BNX2_PCICFG_REG_WINDOW_ADDRESS                 0x00000078
+#define BNX2_PCICFG_REG_WINDOW                         0x00000080
+#define BNX2_PCICFG_INT_ACK_CMD                                0x00000084
+#define BNX2_PCICFG_INT_ACK_CMD_INDEX                   (0xffffL<<0)
+#define BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID             (1L<<16)
+#define BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM        (1L<<17)
+#define BNX2_PCICFG_INT_ACK_CMD_MASK_INT                (1L<<18)
+
+#define BNX2_PCICFG_STATUS_BIT_SET_CMD                 0x00000088
+#define BNX2_PCICFG_STATUS_BIT_CLEAR_CMD               0x0000008c
+#define BNX2_PCICFG_MAILBOX_QUEUE_ADDR                 0x00000090
+#define BNX2_PCICFG_MAILBOX_QUEUE_DATA                 0x00000094
+
+
+/*
+ *  pci_reg definition
+ *  offset: 0x400
+ */
+#define BNX2_PCI_GRC_WINDOW_ADDR                       0x00000400
+#define BNX2_PCI_GRC_WINDOW_ADDR_PCI_GRC_WINDOW_ADDR_VALUE      (0x3ffffL<<8)
+
+#define BNX2_PCI_CONFIG_1                              0x00000404
+#define BNX2_PCI_CONFIG_1_READ_BOUNDARY                         (0x7L<<8)
+#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_OFF             (0L<<8)
+#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_16              (1L<<8)
+#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_32              (2L<<8)
+#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_64              (3L<<8)
+#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_128             (4L<<8)
+#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_256             (5L<<8)
+#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_512             (6L<<8)
+#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_1024            (7L<<8)
+#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY                (0x7L<<11)
+#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_OFF            (0L<<11)
+#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_16             (1L<<11)
+#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_32             (2L<<11)
+#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_64             (3L<<11)
+#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_128            (4L<<11)
+#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_256            (5L<<11)
+#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_512            (6L<<11)
+#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_1024           (7L<<11)
+
+#define BNX2_PCI_CONFIG_2                              0x00000408
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE                     (0xfL<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_DISABLED            (0L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_64K                         (1L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_128K                (2L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_256K                (3L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_512K                (4L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_1M                  (5L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_2M                  (6L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_4M                  (7L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_8M                  (8L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_16M                         (9L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_32M                         (10L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_64M                         (11L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_128M                (12L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_256M                (13L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_512M                (14L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_SIZE_1G                  (15L<<0)
+#define BNX2_PCI_CONFIG_2_BAR1_64ENA                    (1L<<4)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_RETRY                         (1L<<5)
+#define BNX2_PCI_CONFIG_2_CFG_CYCLE_RETRY               (1L<<6)
+#define BNX2_PCI_CONFIG_2_FIRST_CFG_DONE                (1L<<7)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE                  (0xffL<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_DISABLED                 (0L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_1K               (1L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_2K               (2L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_4K               (3L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_8K               (4L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_16K              (5L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_32K              (6L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_64K              (7L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_128K             (8L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_256K             (9L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_512K             (10L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_1M               (11L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_2M               (12L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_4M               (13L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_8M               (14L<<8)
+#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_16M              (15L<<8)
+#define BNX2_PCI_CONFIG_2_MAX_SPLIT_LIMIT               (0x1fL<<16)
+#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT                (0x3L<<21)
+#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_512            (0L<<21)
+#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_1K             (1L<<21)
+#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_2K             (2L<<21)
+#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_4K             (3L<<21)
+#define BNX2_PCI_CONFIG_2_FORCE_32_BIT_MSTR             (1L<<23)
+#define BNX2_PCI_CONFIG_2_FORCE_32_BIT_TGT              (1L<<24)
+#define BNX2_PCI_CONFIG_2_KEEP_REQ_ASSERT               (1L<<25)
+
+#define BNX2_PCI_CONFIG_3                              0x0000040c
+#define BNX2_PCI_CONFIG_3_STICKY_BYTE                   (0xffL<<0)
+#define BNX2_PCI_CONFIG_3_FORCE_PME                     (1L<<24)
+#define BNX2_PCI_CONFIG_3_PME_STATUS                    (1L<<25)
+#define BNX2_PCI_CONFIG_3_PME_ENABLE                    (1L<<26)
+#define BNX2_PCI_CONFIG_3_PM_STATE                      (0x3L<<27)
+#define BNX2_PCI_CONFIG_3_VAUX_PRESET                   (1L<<30)
+#define BNX2_PCI_CONFIG_3_PCI_POWER                     (1L<<31)
+
+#define BNX2_PCI_PM_DATA_A                             0x00000410
+#define BNX2_PCI_PM_DATA_A_PM_DATA_0_PRG                (0xffL<<0)
+#define BNX2_PCI_PM_DATA_A_PM_DATA_1_PRG                (0xffL<<8)
+#define BNX2_PCI_PM_DATA_A_PM_DATA_2_PRG                (0xffL<<16)
+#define BNX2_PCI_PM_DATA_A_PM_DATA_3_PRG                (0xffL<<24)
+
+#define BNX2_PCI_PM_DATA_B                             0x00000414
+#define BNX2_PCI_PM_DATA_B_PM_DATA_4_PRG                (0xffL<<0)
+#define BNX2_PCI_PM_DATA_B_PM_DATA_5_PRG                (0xffL<<8)
+#define BNX2_PCI_PM_DATA_B_PM_DATA_6_PRG                (0xffL<<16)
+#define BNX2_PCI_PM_DATA_B_PM_DATA_7_PRG                (0xffL<<24)
+
+#define BNX2_PCI_SWAP_DIAG0                            0x00000418
+#define BNX2_PCI_SWAP_DIAG1                            0x0000041c
+#define BNX2_PCI_EXP_ROM_ADDR                          0x00000420
+#define BNX2_PCI_EXP_ROM_ADDR_ADDRESS                   (0x3fffffL<<2)
+#define BNX2_PCI_EXP_ROM_ADDR_REQ                       (1L<<31)
+
+#define BNX2_PCI_EXP_ROM_DATA                          0x00000424
+#define BNX2_PCI_VPD_INTF                              0x00000428
+#define BNX2_PCI_VPD_INTF_INTF_REQ                      (1L<<0)
+
+#define BNX2_PCI_VPD_ADDR_FLAG                         0x0000042c
+#define BNX2_PCI_VPD_ADDR_FLAG_ADDRESS                  (0x1fff<<2)
+#define BNX2_PCI_VPD_ADDR_FLAG_WR                       (1<<15)
+
+#define BNX2_PCI_VPD_DATA                              0x00000430
+#define BNX2_PCI_ID_VAL1                               0x00000434
+#define BNX2_PCI_ID_VAL1_DEVICE_ID                      (0xffffL<<0)
+#define BNX2_PCI_ID_VAL1_VENDOR_ID                      (0xffffL<<16)
+
+#define BNX2_PCI_ID_VAL2                               0x00000438
+#define BNX2_PCI_ID_VAL2_SUBSYSTEM_VENDOR_ID            (0xffffL<<0)
+#define BNX2_PCI_ID_VAL2_SUBSYSTEM_ID                   (0xffffL<<16)
+
+#define BNX2_PCI_ID_VAL3                               0x0000043c
+#define BNX2_PCI_ID_VAL3_CLASS_CODE                     (0xffffffL<<0)
+#define BNX2_PCI_ID_VAL3_REVISION_ID                    (0xffL<<24)
+
+#define BNX2_PCI_ID_VAL4                               0x00000440
+#define BNX2_PCI_ID_VAL4_CAP_ENA                        (0xfL<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_0                      (0L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_1                      (1L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_2                      (2L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_3                      (3L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_4                      (4L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_5                      (5L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_6                      (6L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_7                      (7L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_8                      (8L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_9                      (9L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_10                     (10L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_11                     (11L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_12                     (12L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_13                     (13L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_14                     (14L<<0)
+#define BNX2_PCI_ID_VAL4_CAP_ENA_15                     (15L<<0)
+#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG                   (0x3L<<6)
+#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_0                         (0L<<6)
+#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_1                         (1L<<6)
+#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_2                         (2L<<6)
+#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_3                         (3L<<6)
+#define BNX2_PCI_ID_VAL4_MSI_LIMIT                      (0x7L<<9)
+#define BNX2_PCI_ID_VAL4_MSI_ADVERTIZE                  (0x7L<<12)
+#define BNX2_PCI_ID_VAL4_MSI_ENABLE                     (1L<<15)
+#define BNX2_PCI_ID_VAL4_MAX_64_ADVERTIZE               (1L<<16)
+#define BNX2_PCI_ID_VAL4_MAX_133_ADVERTIZE              (1L<<17)
+#define BNX2_PCI_ID_VAL4_MAX_MEM_READ_SIZE              (0x3L<<21)
+#define BNX2_PCI_ID_VAL4_MAX_SPLIT_SIZE                         (0x7L<<23)
+#define BNX2_PCI_ID_VAL4_MAX_CUMULATIVE_SIZE            (0x7L<<26)
+
+#define BNX2_PCI_ID_VAL5                               0x00000444
+#define BNX2_PCI_ID_VAL5_D1_SUPPORT                     (1L<<0)
+#define BNX2_PCI_ID_VAL5_D2_SUPPORT                     (1L<<1)
+#define BNX2_PCI_ID_VAL5_PME_IN_D0                      (1L<<2)
+#define BNX2_PCI_ID_VAL5_PME_IN_D1                      (1L<<3)
+#define BNX2_PCI_ID_VAL5_PME_IN_D2                      (1L<<4)
+#define BNX2_PCI_ID_VAL5_PME_IN_D3_HOT                  (1L<<5)
+
+#define BNX2_PCI_PCIX_EXTENDED_STATUS                  0x00000448
+#define BNX2_PCI_PCIX_EXTENDED_STATUS_NO_SNOOP          (1L<<8)
+#define BNX2_PCI_PCIX_EXTENDED_STATUS_LONG_BURST        (1L<<9)
+#define BNX2_PCI_PCIX_EXTENDED_STATUS_SPLIT_COMP_MSG_CLASS      (0xfL<<16)
+#define BNX2_PCI_PCIX_EXTENDED_STATUS_SPLIT_COMP_MSG_IDX        (0xffL<<24)
+
+#define BNX2_PCI_ID_VAL6                               0x0000044c
+#define BNX2_PCI_ID_VAL6_MAX_LAT                        (0xffL<<0)
+#define BNX2_PCI_ID_VAL6_MIN_GNT                        (0xffL<<8)
+#define BNX2_PCI_ID_VAL6_BIST                           (0xffL<<16)
+
+#define BNX2_PCI_MSI_DATA                              0x00000450
+#define BNX2_PCI_MSI_DATA_PCI_MSI_DATA                  (0xffffL<<0)
+
+#define BNX2_PCI_MSI_ADDR_H                            0x00000454
+#define BNX2_PCI_MSI_ADDR_L                            0x00000458
+
+
+/*
+ *  misc_reg definition
+ *  offset: 0x800
+ */
+#define BNX2_MISC_COMMAND                              0x00000800
+#define BNX2_MISC_COMMAND_ENABLE_ALL                    (1L<<0)
+#define BNX2_MISC_COMMAND_DISABLE_ALL                   (1L<<1)
+#define BNX2_MISC_COMMAND_CORE_RESET                    (1L<<4)
+#define BNX2_MISC_COMMAND_HARD_RESET                    (1L<<5)
+#define BNX2_MISC_COMMAND_PAR_ERROR                     (1L<<8)
+#define BNX2_MISC_COMMAND_PAR_ERR_RAM                   (0x7fL<<16)
+
+#define BNX2_MISC_CFG                                  0x00000804
+#define BNX2_MISC_CFG_PCI_GRC_TMOUT                     (1L<<0)
+#define BNX2_MISC_CFG_NVM_WR_EN                                 (0x3L<<1)
+#define BNX2_MISC_CFG_NVM_WR_EN_PROTECT                         (0L<<1)
+#define BNX2_MISC_CFG_NVM_WR_EN_PCI                     (1L<<1)
+#define BNX2_MISC_CFG_NVM_WR_EN_ALLOW                   (2L<<1)
+#define BNX2_MISC_CFG_NVM_WR_EN_ALLOW2                  (3L<<1)
+#define BNX2_MISC_CFG_BIST_EN                           (1L<<3)
+#define BNX2_MISC_CFG_CK25_OUT_ALT_SRC                  (1L<<4)
+#define BNX2_MISC_CFG_BYPASS_BSCAN                      (1L<<5)
+#define BNX2_MISC_CFG_BYPASS_EJTAG                      (1L<<6)
+#define BNX2_MISC_CFG_CLK_CTL_OVERRIDE                  (1L<<7)
+#define BNX2_MISC_CFG_LEDMODE                           (0x3L<<8)
+#define BNX2_MISC_CFG_LEDMODE_MAC                       (0L<<8)
+#define BNX2_MISC_CFG_LEDMODE_GPHY1                     (1L<<8)
+#define BNX2_MISC_CFG_LEDMODE_GPHY2                     (2L<<8)
+
+#define BNX2_MISC_ID                                   0x00000808
+#define BNX2_MISC_ID_BOND_ID                            (0xfL<<0)
+#define BNX2_MISC_ID_CHIP_METAL                                 (0xffL<<4)
+#define BNX2_MISC_ID_CHIP_REV                           (0xfL<<12)
+#define BNX2_MISC_ID_CHIP_NUM                           (0xffffL<<16)
+
+#define BNX2_MISC_ENABLE_STATUS_BITS                   0x0000080c
+#define BNX2_MISC_ENABLE_STATUS_BITS_TX_SCHEDULER_ENABLE        (1L<<0)
+#define BNX2_MISC_ENABLE_STATUS_BITS_TX_BD_READ_ENABLE  (1L<<1)
+#define BNX2_MISC_ENABLE_STATUS_BITS_TX_BD_CACHE_ENABLE         (1L<<2)
+#define BNX2_MISC_ENABLE_STATUS_BITS_TX_PROCESSOR_ENABLE        (1L<<3)
+#define BNX2_MISC_ENABLE_STATUS_BITS_TX_DMA_ENABLE      (1L<<4)
+#define BNX2_MISC_ENABLE_STATUS_BITS_TX_PATCHUP_ENABLE  (1L<<5)
+#define BNX2_MISC_ENABLE_STATUS_BITS_TX_PAYLOAD_Q_ENABLE        (1L<<6)
+#define BNX2_MISC_ENABLE_STATUS_BITS_TX_HEADER_Q_ENABLE         (1L<<7)
+#define BNX2_MISC_ENABLE_STATUS_BITS_TX_ASSEMBLER_ENABLE        (1L<<8)
+#define BNX2_MISC_ENABLE_STATUS_BITS_EMAC_ENABLE        (1L<<9)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RX_PARSER_MAC_ENABLE       (1L<<10)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RX_PARSER_CATCHUP_ENABLE   (1L<<11)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RX_MBUF_ENABLE     (1L<<12)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RX_LOOKUP_ENABLE   (1L<<13)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RX_PROCESSOR_ENABLE        (1L<<14)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE      (1L<<15)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RX_BD_CACHE_ENABLE         (1L<<16)
+#define BNX2_MISC_ENABLE_STATUS_BITS_RX_DMA_ENABLE      (1L<<17)
+#define BNX2_MISC_ENABLE_STATUS_BITS_COMPLETION_ENABLE  (1L<<18)
+#define BNX2_MISC_ENABLE_STATUS_BITS_HOST_COALESCE_ENABLE       (1L<<19)
+#define BNX2_MISC_ENABLE_STATUS_BITS_MAILBOX_QUEUE_ENABLE       (1L<<20)
+#define BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE     (1L<<21)
+#define BNX2_MISC_ENABLE_STATUS_BITS_CMD_SCHEDULER_ENABLE       (1L<<22)
+#define BNX2_MISC_ENABLE_STATUS_BITS_CMD_PROCESSOR_ENABLE       (1L<<23)
+#define BNX2_MISC_ENABLE_STATUS_BITS_MGMT_PROCESSOR_ENABLE      (1L<<24)
+#define BNX2_MISC_ENABLE_STATUS_BITS_TIMER_ENABLE       (1L<<25)
+#define BNX2_MISC_ENABLE_STATUS_BITS_DMA_ENGINE_ENABLE  (1L<<26)
+#define BNX2_MISC_ENABLE_STATUS_BITS_UMP_ENABLE                 (1L<<27)
+
+#define BNX2_MISC_ENABLE_SET_BITS                      0x00000810
+#define BNX2_MISC_ENABLE_SET_BITS_TX_SCHEDULER_ENABLE   (1L<<0)
+#define BNX2_MISC_ENABLE_SET_BITS_TX_BD_READ_ENABLE     (1L<<1)
+#define BNX2_MISC_ENABLE_SET_BITS_TX_BD_CACHE_ENABLE    (1L<<2)
+#define BNX2_MISC_ENABLE_SET_BITS_TX_PROCESSOR_ENABLE   (1L<<3)
+#define BNX2_MISC_ENABLE_SET_BITS_TX_DMA_ENABLE                 (1L<<4)
+#define BNX2_MISC_ENABLE_SET_BITS_TX_PATCHUP_ENABLE     (1L<<5)
+#define BNX2_MISC_ENABLE_SET_BITS_TX_PAYLOAD_Q_ENABLE   (1L<<6)
+#define BNX2_MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE    (1L<<7)
+#define BNX2_MISC_ENABLE_SET_BITS_TX_ASSEMBLER_ENABLE   (1L<<8)
+#define BNX2_MISC_ENABLE_SET_BITS_EMAC_ENABLE           (1L<<9)
+#define BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE  (1L<<10)
+#define BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_CATCHUP_ENABLE      (1L<<11)
+#define BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE        (1L<<12)
+#define BNX2_MISC_ENABLE_SET_BITS_RX_LOOKUP_ENABLE      (1L<<13)
+#define BNX2_MISC_ENABLE_SET_BITS_RX_PROCESSOR_ENABLE   (1L<<14)
+#define BNX2_MISC_ENABLE_SET_BITS_RX_V2P_ENABLE                 (1L<<15)
+#define BNX2_MISC_ENABLE_SET_BITS_RX_BD_CACHE_ENABLE    (1L<<16)
+#define BNX2_MISC_ENABLE_SET_BITS_RX_DMA_ENABLE                 (1L<<17)
+#define BNX2_MISC_ENABLE_SET_BITS_COMPLETION_ENABLE     (1L<<18)
+#define BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE  (1L<<19)
+#define BNX2_MISC_ENABLE_SET_BITS_MAILBOX_QUEUE_ENABLE  (1L<<20)
+#define BNX2_MISC_ENABLE_SET_BITS_CONTEXT_ENABLE        (1L<<21)
+#define BNX2_MISC_ENABLE_SET_BITS_CMD_SCHEDULER_ENABLE  (1L<<22)
+#define BNX2_MISC_ENABLE_SET_BITS_CMD_PROCESSOR_ENABLE  (1L<<23)
+#define BNX2_MISC_ENABLE_SET_BITS_MGMT_PROCESSOR_ENABLE         (1L<<24)
+#define BNX2_MISC_ENABLE_SET_BITS_TIMER_ENABLE          (1L<<25)
+#define BNX2_MISC_ENABLE_SET_BITS_DMA_ENGINE_ENABLE     (1L<<26)
+#define BNX2_MISC_ENABLE_SET_BITS_UMP_ENABLE            (1L<<27)
+
+#define BNX2_MISC_ENABLE_CLR_BITS                      0x00000814
+#define BNX2_MISC_ENABLE_CLR_BITS_TX_SCHEDULER_ENABLE   (1L<<0)
+#define BNX2_MISC_ENABLE_CLR_BITS_TX_BD_READ_ENABLE     (1L<<1)
+#define BNX2_MISC_ENABLE_CLR_BITS_TX_BD_CACHE_ENABLE    (1L<<2)
+#define BNX2_MISC_ENABLE_CLR_BITS_TX_PROCESSOR_ENABLE   (1L<<3)
+#define BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE                 (1L<<4)
+#define BNX2_MISC_ENABLE_CLR_BITS_TX_PATCHUP_ENABLE     (1L<<5)
+#define BNX2_MISC_ENABLE_CLR_BITS_TX_PAYLOAD_Q_ENABLE   (1L<<6)
+#define BNX2_MISC_ENABLE_CLR_BITS_TX_HEADER_Q_ENABLE    (1L<<7)
+#define BNX2_MISC_ENABLE_CLR_BITS_TX_ASSEMBLER_ENABLE   (1L<<8)
+#define BNX2_MISC_ENABLE_CLR_BITS_EMAC_ENABLE           (1L<<9)
+#define BNX2_MISC_ENABLE_CLR_BITS_RX_PARSER_MAC_ENABLE  (1L<<10)
+#define BNX2_MISC_ENABLE_CLR_BITS_RX_PARSER_CATCHUP_ENABLE      (1L<<11)
+#define BNX2_MISC_ENABLE_CLR_BITS_RX_MBUF_ENABLE        (1L<<12)
+#define BNX2_MISC_ENABLE_CLR_BITS_RX_LOOKUP_ENABLE      (1L<<13)
+#define BNX2_MISC_ENABLE_CLR_BITS_RX_PROCESSOR_ENABLE   (1L<<14)
+#define BNX2_MISC_ENABLE_CLR_BITS_RX_V2P_ENABLE                 (1L<<15)
+#define BNX2_MISC_ENABLE_CLR_BITS_RX_BD_CACHE_ENABLE    (1L<<16)
+#define BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE                 (1L<<17)
+#define BNX2_MISC_ENABLE_CLR_BITS_COMPLETION_ENABLE     (1L<<18)
+#define BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE  (1L<<19)
+#define BNX2_MISC_ENABLE_CLR_BITS_MAILBOX_QUEUE_ENABLE  (1L<<20)
+#define BNX2_MISC_ENABLE_CLR_BITS_CONTEXT_ENABLE        (1L<<21)
+#define BNX2_MISC_ENABLE_CLR_BITS_CMD_SCHEDULER_ENABLE  (1L<<22)
+#define BNX2_MISC_ENABLE_CLR_BITS_CMD_PROCESSOR_ENABLE  (1L<<23)
+#define BNX2_MISC_ENABLE_CLR_BITS_MGMT_PROCESSOR_ENABLE         (1L<<24)
+#define BNX2_MISC_ENABLE_CLR_BITS_TIMER_ENABLE          (1L<<25)
+#define BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE     (1L<<26)
+#define BNX2_MISC_ENABLE_CLR_BITS_UMP_ENABLE            (1L<<27)
+
+#define BNX2_MISC_CLOCK_CONTROL_BITS                   0x00000818
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET    (0xfL<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ      (0L<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ      (1L<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ      (2L<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ      (3L<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ      (4L<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ      (5L<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ      (6L<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ     (7L<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW        (0xfL<<0)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE   (1L<<6)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT       (1L<<7)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC   (0x7L<<8)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_UNDEF     (0L<<8)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12        (1L<<8)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6         (2L<<8)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62        (4L<<8)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PLAY_DEAD          (1L<<11)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED         (0xfL<<12)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100     (0L<<12)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80      (1L<<12)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_50      (2L<<12)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40      (4L<<12)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25      (8L<<12)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP  (1L<<16)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_PLL_STOP       (1L<<17)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_18        (1L<<18)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_USE_SPD_DET        (1L<<19)
+#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED           (0xfffL<<20)
+
+#define BNX2_MISC_GPIO                                 0x0000081c
+#define BNX2_MISC_GPIO_VALUE                            (0xffL<<0)
+#define BNX2_MISC_GPIO_SET                              (0xffL<<8)
+#define BNX2_MISC_GPIO_CLR                              (0xffL<<16)
+#define BNX2_MISC_GPIO_FLOAT                            (0xffL<<24)
+
+#define BNX2_MISC_GPIO_INT                             0x00000820
+#define BNX2_MISC_GPIO_INT_INT_STATE                    (0xfL<<0)
+#define BNX2_MISC_GPIO_INT_OLD_VALUE                    (0xfL<<8)
+#define BNX2_MISC_GPIO_INT_OLD_SET                      (0xfL<<16)
+#define BNX2_MISC_GPIO_INT_OLD_CLR                      (0xfL<<24)
+
+#define BNX2_MISC_CONFIG_LFSR                          0x00000824
+#define BNX2_MISC_CONFIG_LFSR_DIV                       (0xffffL<<0)
+
+#define BNX2_MISC_LFSR_MASK_BITS                       0x00000828
+#define BNX2_MISC_LFSR_MASK_BITS_TX_SCHEDULER_ENABLE    (1L<<0)
+#define BNX2_MISC_LFSR_MASK_BITS_TX_BD_READ_ENABLE      (1L<<1)
+#define BNX2_MISC_LFSR_MASK_BITS_TX_BD_CACHE_ENABLE     (1L<<2)
+#define BNX2_MISC_LFSR_MASK_BITS_TX_PROCESSOR_ENABLE    (1L<<3)
+#define BNX2_MISC_LFSR_MASK_BITS_TX_DMA_ENABLE          (1L<<4)
+#define BNX2_MISC_LFSR_MASK_BITS_TX_PATCHUP_ENABLE      (1L<<5)
+#define BNX2_MISC_LFSR_MASK_BITS_TX_PAYLOAD_Q_ENABLE    (1L<<6)
+#define BNX2_MISC_LFSR_MASK_BITS_TX_HEADER_Q_ENABLE     (1L<<7)
+#define BNX2_MISC_LFSR_MASK_BITS_TX_ASSEMBLER_ENABLE    (1L<<8)
+#define BNX2_MISC_LFSR_MASK_BITS_EMAC_ENABLE            (1L<<9)
+#define BNX2_MISC_LFSR_MASK_BITS_RX_PARSER_MAC_ENABLE   (1L<<10)
+#define BNX2_MISC_LFSR_MASK_BITS_RX_PARSER_CATCHUP_ENABLE       (1L<<11)
+#define BNX2_MISC_LFSR_MASK_BITS_RX_MBUF_ENABLE                 (1L<<12)
+#define BNX2_MISC_LFSR_MASK_BITS_RX_LOOKUP_ENABLE       (1L<<13)
+#define BNX2_MISC_LFSR_MASK_BITS_RX_PROCESSOR_ENABLE    (1L<<14)
+#define BNX2_MISC_LFSR_MASK_BITS_RX_V2P_ENABLE          (1L<<15)
+#define BNX2_MISC_LFSR_MASK_BITS_RX_BD_CACHE_ENABLE     (1L<<16)
+#define BNX2_MISC_LFSR_MASK_BITS_RX_DMA_ENABLE          (1L<<17)
+#define BNX2_MISC_LFSR_MASK_BITS_COMPLETION_ENABLE      (1L<<18)
+#define BNX2_MISC_LFSR_MASK_BITS_HOST_COALESCE_ENABLE   (1L<<19)
+#define BNX2_MISC_LFSR_MASK_BITS_MAILBOX_QUEUE_ENABLE   (1L<<20)
+#define BNX2_MISC_LFSR_MASK_BITS_CONTEXT_ENABLE                 (1L<<21)
+#define BNX2_MISC_LFSR_MASK_BITS_CMD_SCHEDULER_ENABLE   (1L<<22)
+#define BNX2_MISC_LFSR_MASK_BITS_CMD_PROCESSOR_ENABLE   (1L<<23)
+#define BNX2_MISC_LFSR_MASK_BITS_MGMT_PROCESSOR_ENABLE  (1L<<24)
+#define BNX2_MISC_LFSR_MASK_BITS_TIMER_ENABLE           (1L<<25)
+#define BNX2_MISC_LFSR_MASK_BITS_DMA_ENGINE_ENABLE      (1L<<26)
+#define BNX2_MISC_LFSR_MASK_BITS_UMP_ENABLE             (1L<<27)
+
+#define BNX2_MISC_ARB_REQ0                             0x0000082c
+#define BNX2_MISC_ARB_REQ1                             0x00000830
+#define BNX2_MISC_ARB_REQ2                             0x00000834
+#define BNX2_MISC_ARB_REQ3                             0x00000838
+#define BNX2_MISC_ARB_REQ4                             0x0000083c
+#define BNX2_MISC_ARB_FREE0                            0x00000840
+#define BNX2_MISC_ARB_FREE1                            0x00000844
+#define BNX2_MISC_ARB_FREE2                            0x00000848
+#define BNX2_MISC_ARB_FREE3                            0x0000084c
+#define BNX2_MISC_ARB_FREE4                            0x00000850
+#define BNX2_MISC_ARB_REQ_STATUS0                      0x00000854
+#define BNX2_MISC_ARB_REQ_STATUS1                      0x00000858
+#define BNX2_MISC_ARB_REQ_STATUS2                      0x0000085c
+#define BNX2_MISC_ARB_REQ_STATUS3                      0x00000860
+#define BNX2_MISC_ARB_REQ_STATUS4                      0x00000864
+#define BNX2_MISC_ARB_GNT0                             0x00000868
+#define BNX2_MISC_ARB_GNT0_0                            (0x7L<<0)
+#define BNX2_MISC_ARB_GNT0_1                            (0x7L<<4)
+#define BNX2_MISC_ARB_GNT0_2                            (0x7L<<8)
+#define BNX2_MISC_ARB_GNT0_3                            (0x7L<<12)
+#define BNX2_MISC_ARB_GNT0_4                            (0x7L<<16)
+#define BNX2_MISC_ARB_GNT0_5                            (0x7L<<20)
+#define BNX2_MISC_ARB_GNT0_6                            (0x7L<<24)
+#define BNX2_MISC_ARB_GNT0_7                            (0x7L<<28)
+
+#define BNX2_MISC_ARB_GNT1                             0x0000086c
+#define BNX2_MISC_ARB_GNT1_8                            (0x7L<<0)
+#define BNX2_MISC_ARB_GNT1_9                            (0x7L<<4)
+#define BNX2_MISC_ARB_GNT1_10                           (0x7L<<8)
+#define BNX2_MISC_ARB_GNT1_11                           (0x7L<<12)
+#define BNX2_MISC_ARB_GNT1_12                           (0x7L<<16)
+#define BNX2_MISC_ARB_GNT1_13                           (0x7L<<20)
+#define BNX2_MISC_ARB_GNT1_14                           (0x7L<<24)
+#define BNX2_MISC_ARB_GNT1_15                           (0x7L<<28)
+
+#define BNX2_MISC_ARB_GNT2                             0x00000870
+#define BNX2_MISC_ARB_GNT2_16                           (0x7L<<0)
+#define BNX2_MISC_ARB_GNT2_17                           (0x7L<<4)
+#define BNX2_MISC_ARB_GNT2_18                           (0x7L<<8)
+#define BNX2_MISC_ARB_GNT2_19                           (0x7L<<12)
+#define BNX2_MISC_ARB_GNT2_20                           (0x7L<<16)
+#define BNX2_MISC_ARB_GNT2_21                           (0x7L<<20)
+#define BNX2_MISC_ARB_GNT2_22                           (0x7L<<24)
+#define BNX2_MISC_ARB_GNT2_23                           (0x7L<<28)
+
+#define BNX2_MISC_ARB_GNT3                             0x00000874
+#define BNX2_MISC_ARB_GNT3_24                           (0x7L<<0)
+#define BNX2_MISC_ARB_GNT3_25                           (0x7L<<4)
+#define BNX2_MISC_ARB_GNT3_26                           (0x7L<<8)
+#define BNX2_MISC_ARB_GNT3_27                           (0x7L<<12)
+#define BNX2_MISC_ARB_GNT3_28                           (0x7L<<16)
+#define BNX2_MISC_ARB_GNT3_29                           (0x7L<<20)
+#define BNX2_MISC_ARB_GNT3_30                           (0x7L<<24)
+#define BNX2_MISC_ARB_GNT3_31                           (0x7L<<28)
+
+#define BNX2_MISC_PRBS_CONTROL                         0x00000878
+#define BNX2_MISC_PRBS_CONTROL_EN                       (1L<<0)
+#define BNX2_MISC_PRBS_CONTROL_RSTB                     (1L<<1)
+#define BNX2_MISC_PRBS_CONTROL_INV                      (1L<<2)
+#define BNX2_MISC_PRBS_CONTROL_ERR_CLR                  (1L<<3)
+#define BNX2_MISC_PRBS_CONTROL_ORDER                    (0x3L<<4)
+#define BNX2_MISC_PRBS_CONTROL_ORDER_7TH                (0L<<4)
+#define BNX2_MISC_PRBS_CONTROL_ORDER_15TH               (1L<<4)
+#define BNX2_MISC_PRBS_CONTROL_ORDER_23RD               (2L<<4)
+#define BNX2_MISC_PRBS_CONTROL_ORDER_31ST               (3L<<4)
+
+#define BNX2_MISC_PRBS_STATUS                          0x0000087c
+#define BNX2_MISC_PRBS_STATUS_LOCK                      (1L<<0)
+#define BNX2_MISC_PRBS_STATUS_STKY                      (1L<<1)
+#define BNX2_MISC_PRBS_STATUS_ERRORS                    (0x3fffL<<2)
+#define BNX2_MISC_PRBS_STATUS_STATE                     (0xfL<<16)
+
+#define BNX2_MISC_SM_ASF_CONTROL                       0x00000880
+#define BNX2_MISC_SM_ASF_CONTROL_ASF_RST                (1L<<0)
+#define BNX2_MISC_SM_ASF_CONTROL_TSC_EN                         (1L<<1)
+#define BNX2_MISC_SM_ASF_CONTROL_WG_TO                  (1L<<2)
+#define BNX2_MISC_SM_ASF_CONTROL_HB_TO                  (1L<<3)
+#define BNX2_MISC_SM_ASF_CONTROL_PA_TO                  (1L<<4)
+#define BNX2_MISC_SM_ASF_CONTROL_PL_TO                  (1L<<5)
+#define BNX2_MISC_SM_ASF_CONTROL_RT_TO                  (1L<<6)
+#define BNX2_MISC_SM_ASF_CONTROL_SMB_EVENT              (1L<<7)
+#define BNX2_MISC_SM_ASF_CONTROL_RES                    (0xfL<<8)
+#define BNX2_MISC_SM_ASF_CONTROL_SMB_EN                         (1L<<12)
+#define BNX2_MISC_SM_ASF_CONTROL_SMB_BB_EN              (1L<<13)
+#define BNX2_MISC_SM_ASF_CONTROL_SMB_NO_ADDR_FILT       (1L<<14)
+#define BNX2_MISC_SM_ASF_CONTROL_SMB_AUTOREAD           (1L<<15)
+#define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR1          (0x3fL<<16)
+#define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR2          (0x3fL<<24)
+#define BNX2_MISC_SM_ASF_CONTROL_EN_NIC_SMB_ADDR_0      (1L<<30)
+#define BNX2_MISC_SM_ASF_CONTROL_SMB_EARLY_ATTN                 (1L<<31)
+
+#define BNX2_MISC_SMB_IN                               0x00000884
+#define BNX2_MISC_SMB_IN_DAT_IN                                 (0xffL<<0)
+#define BNX2_MISC_SMB_IN_RDY                            (1L<<8)
+#define BNX2_MISC_SMB_IN_DONE                           (1L<<9)
+#define BNX2_MISC_SMB_IN_FIRSTBYTE                      (1L<<10)
+#define BNX2_MISC_SMB_IN_STATUS                                 (0x7L<<11)
+#define BNX2_MISC_SMB_IN_STATUS_OK                      (0x0L<<11)
+#define BNX2_MISC_SMB_IN_STATUS_PEC                     (0x1L<<11)
+#define BNX2_MISC_SMB_IN_STATUS_OFLOW                   (0x2L<<11)
+#define BNX2_MISC_SMB_IN_STATUS_STOP                    (0x3L<<11)
+#define BNX2_MISC_SMB_IN_STATUS_TIMEOUT                         (0x4L<<11)
+
+#define BNX2_MISC_SMB_OUT                              0x00000888
+#define BNX2_MISC_SMB_OUT_DAT_OUT                       (0xffL<<0)
+#define BNX2_MISC_SMB_OUT_RDY                           (1L<<8)
+#define BNX2_MISC_SMB_OUT_START                                 (1L<<9)
+#define BNX2_MISC_SMB_OUT_LAST                          (1L<<10)
+#define BNX2_MISC_SMB_OUT_ACC_TYPE                      (1L<<11)
+#define BNX2_MISC_SMB_OUT_ENB_PEC                       (1L<<12)
+#define BNX2_MISC_SMB_OUT_GET_RX_LEN                    (1L<<13)
+#define BNX2_MISC_SMB_OUT_SMB_READ_LEN                  (0x3fL<<14)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS                (0xfL<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_OK             (0L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_NACK     (1L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_NACK       (9L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_UFLOW          (2L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_STOP           (3L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_TIMEOUT        (4L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_LOST     (5L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_LOST       (0xdL<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_BADACK                 (0x6L<<20)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_SLAVEMODE             (1L<<24)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_EN                (1L<<25)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_IN                (1L<<26)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_CLK_EN                (1L<<27)
+#define BNX2_MISC_SMB_OUT_SMB_OUT_CLK_IN                (1L<<28)
+
+#define BNX2_MISC_SMB_WATCHDOG                         0x0000088c
+#define BNX2_MISC_SMB_WATCHDOG_WATCHDOG                         (0xffffL<<0)
+
+#define BNX2_MISC_SMB_HEARTBEAT                                0x00000890
+#define BNX2_MISC_SMB_HEARTBEAT_HEARTBEAT               (0xffffL<<0)
+
+#define BNX2_MISC_SMB_POLL_ASF                         0x00000894
+#define BNX2_MISC_SMB_POLL_ASF_POLL_ASF                         (0xffffL<<0)
+
+#define BNX2_MISC_SMB_POLL_LEGACY                      0x00000898
+#define BNX2_MISC_SMB_POLL_LEGACY_POLL_LEGACY           (0xffffL<<0)
+
+#define BNX2_MISC_SMB_RETRAN                           0x0000089c
+#define BNX2_MISC_SMB_RETRAN_RETRAN                     (0xffL<<0)
+
+#define BNX2_MISC_SMB_TIMESTAMP                                0x000008a0
+#define BNX2_MISC_SMB_TIMESTAMP_TIMESTAMP               (0xffffffffL<<0)
+
+#define BNX2_MISC_PERR_ENA0                            0x000008a4
+#define BNX2_MISC_PERR_ENA0_COM_MISC_CTXC               (1L<<0)
+#define BNX2_MISC_PERR_ENA0_COM_MISC_REGF               (1L<<1)
+#define BNX2_MISC_PERR_ENA0_COM_MISC_SCPAD              (1L<<2)
+#define BNX2_MISC_PERR_ENA0_CP_MISC_CTXC                (1L<<3)
+#define BNX2_MISC_PERR_ENA0_CP_MISC_REGF                (1L<<4)
+#define BNX2_MISC_PERR_ENA0_CP_MISC_SCPAD               (1L<<5)
+#define BNX2_MISC_PERR_ENA0_CS_MISC_TMEM                (1L<<6)
+#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM0              (1L<<7)
+#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM1              (1L<<8)
+#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM2              (1L<<9)
+#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM3              (1L<<10)
+#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM4              (1L<<11)
+#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM5              (1L<<12)
+#define BNX2_MISC_PERR_ENA0_CTX_MISC_PGTBL              (1L<<13)
+#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR0               (1L<<14)
+#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR1               (1L<<15)
+#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR2               (1L<<16)
+#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR3               (1L<<17)
+#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR4               (1L<<18)
+#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW0               (1L<<19)
+#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW1               (1L<<20)
+#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW2               (1L<<21)
+#define BNX2_MISC_PERR_ENA0_HC_MISC_DMA                         (1L<<22)
+#define BNX2_MISC_PERR_ENA0_MCP_MISC_REGF               (1L<<23)
+#define BNX2_MISC_PERR_ENA0_MCP_MISC_SCPAD              (1L<<24)
+#define BNX2_MISC_PERR_ENA0_MQ_MISC_CTX                         (1L<<25)
+#define BNX2_MISC_PERR_ENA0_RBDC_MISC                   (1L<<26)
+#define BNX2_MISC_PERR_ENA0_RBUF_MISC_MB                (1L<<27)
+#define BNX2_MISC_PERR_ENA0_RBUF_MISC_PTR               (1L<<28)
+#define BNX2_MISC_PERR_ENA0_RDE_MISC_RPC                (1L<<29)
+#define BNX2_MISC_PERR_ENA0_RDE_MISC_RPM                (1L<<30)
+#define BNX2_MISC_PERR_ENA0_RV2P_MISC_CB0REGS           (1L<<31)
+
+#define BNX2_MISC_PERR_ENA1                            0x000008a8
+#define BNX2_MISC_PERR_ENA1_RV2P_MISC_CB1REGS           (1L<<0)
+#define BNX2_MISC_PERR_ENA1_RV2P_MISC_P1IRAM            (1L<<1)
+#define BNX2_MISC_PERR_ENA1_RV2P_MISC_P2IRAM            (1L<<2)
+#define BNX2_MISC_PERR_ENA1_RXP_MISC_CTXC               (1L<<3)
+#define BNX2_MISC_PERR_ENA1_RXP_MISC_REGF               (1L<<4)
+#define BNX2_MISC_PERR_ENA1_RXP_MISC_SCPAD              (1L<<5)
+#define BNX2_MISC_PERR_ENA1_RXP_MISC_RBUFC              (1L<<6)
+#define BNX2_MISC_PERR_ENA1_TBDC_MISC                   (1L<<7)
+#define BNX2_MISC_PERR_ENA1_TDMA_MISC                   (1L<<8)
+#define BNX2_MISC_PERR_ENA1_THBUF_MISC_MB0              (1L<<9)
+#define BNX2_MISC_PERR_ENA1_THBUF_MISC_MB1              (1L<<10)
+#define BNX2_MISC_PERR_ENA1_TPAT_MISC_REGF              (1L<<11)
+#define BNX2_MISC_PERR_ENA1_TPAT_MISC_SCPAD             (1L<<12)
+#define BNX2_MISC_PERR_ENA1_TPBUF_MISC_MB               (1L<<13)
+#define BNX2_MISC_PERR_ENA1_TSCH_MISC_LR                (1L<<14)
+#define BNX2_MISC_PERR_ENA1_TXP_MISC_CTXC               (1L<<15)
+#define BNX2_MISC_PERR_ENA1_TXP_MISC_REGF               (1L<<16)
+#define BNX2_MISC_PERR_ENA1_TXP_MISC_SCPAD              (1L<<17)
+#define BNX2_MISC_PERR_ENA1_UMP_MISC_FIORX              (1L<<18)
+#define BNX2_MISC_PERR_ENA1_UMP_MISC_FIOTX              (1L<<19)
+#define BNX2_MISC_PERR_ENA1_UMP_MISC_RX                         (1L<<20)
+#define BNX2_MISC_PERR_ENA1_UMP_MISC_TX                         (1L<<21)
+#define BNX2_MISC_PERR_ENA1_RDMAQ_MISC                  (1L<<22)
+#define BNX2_MISC_PERR_ENA1_CSQ_MISC                    (1L<<23)
+#define BNX2_MISC_PERR_ENA1_CPQ_MISC                    (1L<<24)
+#define BNX2_MISC_PERR_ENA1_MCPQ_MISC                   (1L<<25)
+#define BNX2_MISC_PERR_ENA1_RV2PMQ_MISC                         (1L<<26)
+#define BNX2_MISC_PERR_ENA1_RV2PPQ_MISC                         (1L<<27)
+#define BNX2_MISC_PERR_ENA1_RV2PTQ_MISC                         (1L<<28)
+#define BNX2_MISC_PERR_ENA1_RXPQ_MISC                   (1L<<29)
+#define BNX2_MISC_PERR_ENA1_RXPCQ_MISC                  (1L<<30)
+#define BNX2_MISC_PERR_ENA1_RLUPQ_MISC                  (1L<<31)
+
+#define BNX2_MISC_PERR_ENA2                            0x000008ac
+#define BNX2_MISC_PERR_ENA2_COMQ_MISC                   (1L<<0)
+#define BNX2_MISC_PERR_ENA2_COMXQ_MISC                  (1L<<1)
+#define BNX2_MISC_PERR_ENA2_COMTQ_MISC                  (1L<<2)
+#define BNX2_MISC_PERR_ENA2_TSCHQ_MISC                  (1L<<3)
+#define BNX2_MISC_PERR_ENA2_TBDRQ_MISC                  (1L<<4)
+#define BNX2_MISC_PERR_ENA2_TXPQ_MISC                   (1L<<5)
+#define BNX2_MISC_PERR_ENA2_TDMAQ_MISC                  (1L<<6)
+#define BNX2_MISC_PERR_ENA2_TPATQ_MISC                  (1L<<7)
+#define BNX2_MISC_PERR_ENA2_TASQ_MISC                   (1L<<8)
+
+#define BNX2_MISC_DEBUG_VECTOR_SEL                     0x000008b0
+#define BNX2_MISC_DEBUG_VECTOR_SEL_0                    (0xfffL<<0)
+#define BNX2_MISC_DEBUG_VECTOR_SEL_1                    (0xfffL<<12)
+
+#define BNX2_MISC_VREG_CONTROL                         0x000008b4
+#define BNX2_MISC_VREG_CONTROL_1_2                      (0xfL<<0)
+#define BNX2_MISC_VREG_CONTROL_2_5                      (0xfL<<4)
+
+#define BNX2_MISC_FINAL_CLK_CTL_VAL                    0x000008b8
+#define BNX2_MISC_FINAL_CLK_CTL_VAL_MISC_FINAL_CLK_CTL_VAL      (0x3ffffffL<<6)
+
+#define BNX2_MISC_UNUSED0                              0x000008bc
+
+
+/*
+ *  nvm_reg definition
+ *  offset: 0x6400
+ */
+#define BNX2_NVM_COMMAND                               0x00006400
+#define BNX2_NVM_COMMAND_RST                            (1L<<0)
+#define BNX2_NVM_COMMAND_DONE                           (1L<<3)
+#define BNX2_NVM_COMMAND_DOIT                           (1L<<4)
+#define BNX2_NVM_COMMAND_WR                             (1L<<5)
+#define BNX2_NVM_COMMAND_ERASE                          (1L<<6)
+#define BNX2_NVM_COMMAND_FIRST                          (1L<<7)
+#define BNX2_NVM_COMMAND_LAST                           (1L<<8)
+#define BNX2_NVM_COMMAND_WREN                           (1L<<16)
+#define BNX2_NVM_COMMAND_WRDI                           (1L<<17)
+#define BNX2_NVM_COMMAND_EWSR                           (1L<<18)
+#define BNX2_NVM_COMMAND_WRSR                           (1L<<19)
+
+#define BNX2_NVM_STATUS                                        0x00006404
+#define BNX2_NVM_STATUS_PI_FSM_STATE                    (0xfL<<0)
+#define BNX2_NVM_STATUS_EE_FSM_STATE                    (0xfL<<4)
+#define BNX2_NVM_STATUS_EQ_FSM_STATE                    (0xfL<<8)
+
+#define BNX2_NVM_WRITE                                 0x00006408
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE                  (0xffffffffL<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_BIT_BANG                 (0L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_EECLK            (1L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_EEDATA           (2L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SCLK             (4L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_CS_B             (8L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SO               (16L<<0)
+#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SI               (32L<<0)
+
+#define BNX2_NVM_ADDR                                  0x0000640c
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE                    (0xffffffL<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_BIT_BANG           (0L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_EECLK              (1L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_EEDATA             (2L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SCLK               (4L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_CS_B               (8L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SO                         (16L<<0)
+#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SI                         (32L<<0)
+
+#define BNX2_NVM_READ                                  0x00006410
+#define BNX2_NVM_READ_NVM_READ_VALUE                    (0xffffffffL<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_BIT_BANG           (0L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_EECLK              (1L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_EEDATA             (2L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_SCLK               (4L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_CS_B               (8L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_SO                         (16L<<0)
+#define BNX2_NVM_READ_NVM_READ_VALUE_SI                         (32L<<0)
+
+#define BNX2_NVM_CFG1                                  0x00006414
+#define BNX2_NVM_CFG1_FLASH_MODE                        (1L<<0)
+#define BNX2_NVM_CFG1_BUFFER_MODE                       (1L<<1)
+#define BNX2_NVM_CFG1_PASS_MODE                                 (1L<<2)
+#define BNX2_NVM_CFG1_BITBANG_MODE                      (1L<<3)
+#define BNX2_NVM_CFG1_STATUS_BIT                        (0x7L<<4)
+#define BNX2_NVM_CFG1_STATUS_BIT_FLASH_RDY              (0L<<4)
+#define BNX2_NVM_CFG1_STATUS_BIT_BUFFER_RDY             (7L<<4)
+#define BNX2_NVM_CFG1_SPI_CLK_DIV                       (0xfL<<7)
+#define BNX2_NVM_CFG1_SEE_CLK_DIV                       (0x7ffL<<11)
+#define BNX2_NVM_CFG1_PROTECT_MODE                      (1L<<24)
+#define BNX2_NVM_CFG1_FLASH_SIZE                        (1L<<25)
+#define BNX2_NVM_CFG1_COMPAT_BYPASSS                    (1L<<31)
+
+#define BNX2_NVM_CFG2                                  0x00006418
+#define BNX2_NVM_CFG2_ERASE_CMD                                 (0xffL<<0)
+#define BNX2_NVM_CFG2_DUMMY                             (0xffL<<8)
+#define BNX2_NVM_CFG2_STATUS_CMD                        (0xffL<<16)
+
+#define BNX2_NVM_CFG3                                  0x0000641c
+#define BNX2_NVM_CFG3_BUFFER_RD_CMD                     (0xffL<<0)
+#define BNX2_NVM_CFG3_WRITE_CMD                                 (0xffL<<8)
+#define BNX2_NVM_CFG3_BUFFER_WRITE_CMD                  (0xffL<<16)
+#define BNX2_NVM_CFG3_READ_CMD                          (0xffL<<24)
+
+#define BNX2_NVM_SW_ARB                                        0x00006420
+#define BNX2_NVM_SW_ARB_ARB_REQ_SET0                    (1L<<0)
+#define BNX2_NVM_SW_ARB_ARB_REQ_SET1                    (1L<<1)
+#define BNX2_NVM_SW_ARB_ARB_REQ_SET2                    (1L<<2)
+#define BNX2_NVM_SW_ARB_ARB_REQ_SET3                    (1L<<3)
+#define BNX2_NVM_SW_ARB_ARB_REQ_CLR0                    (1L<<4)
+#define BNX2_NVM_SW_ARB_ARB_REQ_CLR1                    (1L<<5)
+#define BNX2_NVM_SW_ARB_ARB_REQ_CLR2                    (1L<<6)
+#define BNX2_NVM_SW_ARB_ARB_REQ_CLR3                    (1L<<7)
+#define BNX2_NVM_SW_ARB_ARB_ARB0                        (1L<<8)
+#define BNX2_NVM_SW_ARB_ARB_ARB1                        (1L<<9)
+#define BNX2_NVM_SW_ARB_ARB_ARB2                        (1L<<10)
+#define BNX2_NVM_SW_ARB_ARB_ARB3                        (1L<<11)
+#define BNX2_NVM_SW_ARB_REQ0                            (1L<<12)
+#define BNX2_NVM_SW_ARB_REQ1                            (1L<<13)
+#define BNX2_NVM_SW_ARB_REQ2                            (1L<<14)
+#define BNX2_NVM_SW_ARB_REQ3                            (1L<<15)
+
+#define BNX2_NVM_ACCESS_ENABLE                         0x00006424
+#define BNX2_NVM_ACCESS_ENABLE_EN                       (1L<<0)
+#define BNX2_NVM_ACCESS_ENABLE_WR_EN                    (1L<<1)
+
+#define BNX2_NVM_WRITE1                                        0x00006428
+#define BNX2_NVM_WRITE1_WREN_CMD                        (0xffL<<0)
+#define BNX2_NVM_WRITE1_WRDI_CMD                        (0xffL<<8)
+#define BNX2_NVM_WRITE1_SR_DATA                                 (0xffL<<16)
+
+
+
+/*
+ *  dma_reg definition
+ *  offset: 0xc00
+ */
+#define BNX2_DMA_COMMAND                               0x00000c00
+#define BNX2_DMA_COMMAND_ENABLE                                 (1L<<0)
+
+#define BNX2_DMA_STATUS                                        0x00000c04
+#define BNX2_DMA_STATUS_PAR_ERROR_STATE                         (1L<<0)
+#define BNX2_DMA_STATUS_READ_TRANSFERS_STAT             (1L<<16)
+#define BNX2_DMA_STATUS_READ_DELAY_PCI_CLKS_STAT        (1L<<17)
+#define BNX2_DMA_STATUS_BIG_READ_TRANSFERS_STAT                 (1L<<18)
+#define BNX2_DMA_STATUS_BIG_READ_DELAY_PCI_CLKS_STAT    (1L<<19)
+#define BNX2_DMA_STATUS_BIG_READ_RETRY_AFTER_DATA_STAT  (1L<<20)
+#define BNX2_DMA_STATUS_WRITE_TRANSFERS_STAT            (1L<<21)
+#define BNX2_DMA_STATUS_WRITE_DELAY_PCI_CLKS_STAT       (1L<<22)
+#define BNX2_DMA_STATUS_BIG_WRITE_TRANSFERS_STAT        (1L<<23)
+#define BNX2_DMA_STATUS_BIG_WRITE_DELAY_PCI_CLKS_STAT   (1L<<24)
+#define BNX2_DMA_STATUS_BIG_WRITE_RETRY_AFTER_DATA_STAT         (1L<<25)
+
+#define BNX2_DMA_CONFIG                                        0x00000c08
+#define BNX2_DMA_CONFIG_DATA_BYTE_SWAP                  (1L<<0)
+#define BNX2_DMA_CONFIG_DATA_WORD_SWAP                  (1L<<1)
+#define BNX2_DMA_CONFIG_CNTL_BYTE_SWAP                  (1L<<4)
+#define BNX2_DMA_CONFIG_CNTL_WORD_SWAP                  (1L<<5)
+#define BNX2_DMA_CONFIG_ONE_DMA                                 (1L<<6)
+#define BNX2_DMA_CONFIG_CNTL_TWO_DMA                    (1L<<7)
+#define BNX2_DMA_CONFIG_CNTL_FPGA_MODE                  (1L<<8)
+#define BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA              (1L<<10)
+#define BNX2_DMA_CONFIG_CNTL_PCI_COMP_DLY               (1L<<11)
+#define BNX2_DMA_CONFIG_NO_RCHANS_IN_USE                (0xfL<<12)
+#define BNX2_DMA_CONFIG_NO_WCHANS_IN_USE                (0xfL<<16)
+#define BNX2_DMA_CONFIG_PCI_CLK_CMP_BITS                (0x7L<<20)
+#define BNX2_DMA_CONFIG_PCI_FAST_CLK_CMP                (1L<<23)
+#define BNX2_DMA_CONFIG_BIG_SIZE                        (0xfL<<24)
+#define BNX2_DMA_CONFIG_BIG_SIZE_NONE                   (0x0L<<24)
+#define BNX2_DMA_CONFIG_BIG_SIZE_64                     (0x1L<<24)
+#define BNX2_DMA_CONFIG_BIG_SIZE_128                    (0x2L<<24)
+#define BNX2_DMA_CONFIG_BIG_SIZE_256                    (0x4L<<24)
+#define BNX2_DMA_CONFIG_BIG_SIZE_512                    (0x8L<<24)
+
+#define BNX2_DMA_BLACKOUT                              0x00000c0c
+#define BNX2_DMA_BLACKOUT_RD_RETRY_BLACKOUT             (0xffL<<0)
+#define BNX2_DMA_BLACKOUT_2ND_RD_RETRY_BLACKOUT                 (0xffL<<8)
+#define BNX2_DMA_BLACKOUT_WR_RETRY_BLACKOUT             (0xffL<<16)
+
+#define BNX2_DMA_RCHAN_STAT                            0x00000c30
+#define BNX2_DMA_RCHAN_STAT_COMP_CODE_0                         (0x7L<<0)
+#define BNX2_DMA_RCHAN_STAT_PAR_ERR_0                   (1L<<3)
+#define BNX2_DMA_RCHAN_STAT_COMP_CODE_1                         (0x7L<<4)
+#define BNX2_DMA_RCHAN_STAT_PAR_ERR_1                   (1L<<7)
+#define BNX2_DMA_RCHAN_STAT_COMP_CODE_2                         (0x7L<<8)
+#define BNX2_DMA_RCHAN_STAT_PAR_ERR_2                   (1L<<11)
+#define BNX2_DMA_RCHAN_STAT_COMP_CODE_3                         (0x7L<<12)
+#define BNX2_DMA_RCHAN_STAT_PAR_ERR_3                   (1L<<15)
+#define BNX2_DMA_RCHAN_STAT_COMP_CODE_4                         (0x7L<<16)
+#define BNX2_DMA_RCHAN_STAT_PAR_ERR_4                   (1L<<19)
+#define BNX2_DMA_RCHAN_STAT_COMP_CODE_5                         (0x7L<<20)
+#define BNX2_DMA_RCHAN_STAT_PAR_ERR_5                   (1L<<23)
+#define BNX2_DMA_RCHAN_STAT_COMP_CODE_6                         (0x7L<<24)
+#define BNX2_DMA_RCHAN_STAT_PAR_ERR_6                   (1L<<27)
+#define BNX2_DMA_RCHAN_STAT_COMP_CODE_7                         (0x7L<<28)
+#define BNX2_DMA_RCHAN_STAT_PAR_ERR_7                   (1L<<31)
+
+#define BNX2_DMA_WCHAN_STAT                            0x00000c34
+#define BNX2_DMA_WCHAN_STAT_COMP_CODE_0                         (0x7L<<0)
+#define BNX2_DMA_WCHAN_STAT_PAR_ERR_0                   (1L<<3)
+#define BNX2_DMA_WCHAN_STAT_COMP_CODE_1                         (0x7L<<4)
+#define BNX2_DMA_WCHAN_STAT_PAR_ERR_1                   (1L<<7)
+#define BNX2_DMA_WCHAN_STAT_COMP_CODE_2                         (0x7L<<8)
+#define BNX2_DMA_WCHAN_STAT_PAR_ERR_2                   (1L<<11)
+#define BNX2_DMA_WCHAN_STAT_COMP_CODE_3                         (0x7L<<12)
+#define BNX2_DMA_WCHAN_STAT_PAR_ERR_3                   (1L<<15)
+#define BNX2_DMA_WCHAN_STAT_COMP_CODE_4                         (0x7L<<16)
+#define BNX2_DMA_WCHAN_STAT_PAR_ERR_4                   (1L<<19)
+#define BNX2_DMA_WCHAN_STAT_COMP_CODE_5                         (0x7L<<20)
+#define BNX2_DMA_WCHAN_STAT_PAR_ERR_5                   (1L<<23)
+#define BNX2_DMA_WCHAN_STAT_COMP_CODE_6                         (0x7L<<24)
+#define BNX2_DMA_WCHAN_STAT_PAR_ERR_6                   (1L<<27)
+#define BNX2_DMA_WCHAN_STAT_COMP_CODE_7                         (0x7L<<28)
+#define BNX2_DMA_WCHAN_STAT_PAR_ERR_7                   (1L<<31)
+
+#define BNX2_DMA_RCHAN_ASSIGNMENT                      0x00000c38
+#define BNX2_DMA_RCHAN_ASSIGNMENT_0                     (0xfL<<0)
+#define BNX2_DMA_RCHAN_ASSIGNMENT_1                     (0xfL<<4)
+#define BNX2_DMA_RCHAN_ASSIGNMENT_2                     (0xfL<<8)
+#define BNX2_DMA_RCHAN_ASSIGNMENT_3                     (0xfL<<12)
+#define BNX2_DMA_RCHAN_ASSIGNMENT_4                     (0xfL<<16)
+#define BNX2_DMA_RCHAN_ASSIGNMENT_5                     (0xfL<<20)
+#define BNX2_DMA_RCHAN_ASSIGNMENT_6                     (0xfL<<24)
+#define BNX2_DMA_RCHAN_ASSIGNMENT_7                     (0xfL<<28)
+
+#define BNX2_DMA_WCHAN_ASSIGNMENT                      0x00000c3c
+#define BNX2_DMA_WCHAN_ASSIGNMENT_0                     (0xfL<<0)
+#define BNX2_DMA_WCHAN_ASSIGNMENT_1                     (0xfL<<4)
+#define BNX2_DMA_WCHAN_ASSIGNMENT_2                     (0xfL<<8)
+#define BNX2_DMA_WCHAN_ASSIGNMENT_3                     (0xfL<<12)
+#define BNX2_DMA_WCHAN_ASSIGNMENT_4                     (0xfL<<16)
+#define BNX2_DMA_WCHAN_ASSIGNMENT_5                     (0xfL<<20)
+#define BNX2_DMA_WCHAN_ASSIGNMENT_6                     (0xfL<<24)
+#define BNX2_DMA_WCHAN_ASSIGNMENT_7                     (0xfL<<28)
+
+#define BNX2_DMA_RCHAN_STAT_00                         0x00000c40
+#define BNX2_DMA_RCHAN_STAT_00_RCHAN_STA_HOST_ADDR_LOW  (0xffffffffL<<0)
+
+#define BNX2_DMA_RCHAN_STAT_01                         0x00000c44
+#define BNX2_DMA_RCHAN_STAT_01_RCHAN_STA_HOST_ADDR_HIGH         (0xffffffffL<<0)
+
+#define BNX2_DMA_RCHAN_STAT_02                         0x00000c48
+#define BNX2_DMA_RCHAN_STAT_02_LENGTH                   (0xffffL<<0)
+#define BNX2_DMA_RCHAN_STAT_02_WORD_SWAP                (1L<<16)
+#define BNX2_DMA_RCHAN_STAT_02_BYTE_SWAP                (1L<<17)
+#define BNX2_DMA_RCHAN_STAT_02_PRIORITY_LVL             (1L<<18)
+
+#define BNX2_DMA_RCHAN_STAT_10                         0x00000c4c
+#define BNX2_DMA_RCHAN_STAT_11                         0x00000c50
+#define BNX2_DMA_RCHAN_STAT_12                         0x00000c54
+#define BNX2_DMA_RCHAN_STAT_20                         0x00000c58
+#define BNX2_DMA_RCHAN_STAT_21                         0x00000c5c
+#define BNX2_DMA_RCHAN_STAT_22                         0x00000c60
+#define BNX2_DMA_RCHAN_STAT_30                         0x00000c64
+#define BNX2_DMA_RCHAN_STAT_31                         0x00000c68
+#define BNX2_DMA_RCHAN_STAT_32                         0x00000c6c
+#define BNX2_DMA_RCHAN_STAT_40                         0x00000c70
+#define BNX2_DMA_RCHAN_STAT_41                         0x00000c74
+#define BNX2_DMA_RCHAN_STAT_42                         0x00000c78
+#define BNX2_DMA_RCHAN_STAT_50                         0x00000c7c
+#define BNX2_DMA_RCHAN_STAT_51                         0x00000c80
+#define BNX2_DMA_RCHAN_STAT_52                         0x00000c84
+#define BNX2_DMA_RCHAN_STAT_60                         0x00000c88
+#define BNX2_DMA_RCHAN_STAT_61                         0x00000c8c
+#define BNX2_DMA_RCHAN_STAT_62                         0x00000c90
+#define BNX2_DMA_RCHAN_STAT_70                         0x00000c94
+#define BNX2_DMA_RCHAN_STAT_71                         0x00000c98
+#define BNX2_DMA_RCHAN_STAT_72                         0x00000c9c
+#define BNX2_DMA_WCHAN_STAT_00                         0x00000ca0
+#define BNX2_DMA_WCHAN_STAT_00_WCHAN_STA_HOST_ADDR_LOW  (0xffffffffL<<0)
+
+#define BNX2_DMA_WCHAN_STAT_01                         0x00000ca4
+#define BNX2_DMA_WCHAN_STAT_01_WCHAN_STA_HOST_ADDR_HIGH         (0xffffffffL<<0)
+
+#define BNX2_DMA_WCHAN_STAT_02                         0x00000ca8
+#define BNX2_DMA_WCHAN_STAT_02_LENGTH                   (0xffffL<<0)
+#define BNX2_DMA_WCHAN_STAT_02_WORD_SWAP                (1L<<16)
+#define BNX2_DMA_WCHAN_STAT_02_BYTE_SWAP                (1L<<17)
+#define BNX2_DMA_WCHAN_STAT_02_PRIORITY_LVL             (1L<<18)
+
+#define BNX2_DMA_WCHAN_STAT_10                         0x00000cac
+#define BNX2_DMA_WCHAN_STAT_11                         0x00000cb0
+#define BNX2_DMA_WCHAN_STAT_12                         0x00000cb4
+#define BNX2_DMA_WCHAN_STAT_20                         0x00000cb8
+#define BNX2_DMA_WCHAN_STAT_21                         0x00000cbc
+#define BNX2_DMA_WCHAN_STAT_22                         0x00000cc0
+#define BNX2_DMA_WCHAN_STAT_30                         0x00000cc4
+#define BNX2_DMA_WCHAN_STAT_31                         0x00000cc8
+#define BNX2_DMA_WCHAN_STAT_32                         0x00000ccc
+#define BNX2_DMA_WCHAN_STAT_40                         0x00000cd0
+#define BNX2_DMA_WCHAN_STAT_41                         0x00000cd4
+#define BNX2_DMA_WCHAN_STAT_42                         0x00000cd8
+#define BNX2_DMA_WCHAN_STAT_50                         0x00000cdc
+#define BNX2_DMA_WCHAN_STAT_51                         0x00000ce0
+#define BNX2_DMA_WCHAN_STAT_52                         0x00000ce4
+#define BNX2_DMA_WCHAN_STAT_60                         0x00000ce8
+#define BNX2_DMA_WCHAN_STAT_61                         0x00000cec
+#define BNX2_DMA_WCHAN_STAT_62                         0x00000cf0
+#define BNX2_DMA_WCHAN_STAT_70                         0x00000cf4
+#define BNX2_DMA_WCHAN_STAT_71                         0x00000cf8
+#define BNX2_DMA_WCHAN_STAT_72                         0x00000cfc
+#define BNX2_DMA_ARB_STAT_00                           0x00000d00
+#define BNX2_DMA_ARB_STAT_00_MASTER                     (0xffffL<<0)
+#define BNX2_DMA_ARB_STAT_00_MASTER_ENC                         (0xffL<<16)
+#define BNX2_DMA_ARB_STAT_00_CUR_BINMSTR                (0xffL<<24)
+
+#define BNX2_DMA_ARB_STAT_01                           0x00000d04
+#define BNX2_DMA_ARB_STAT_01_LPR_RPTR                   (0xfL<<0)
+#define BNX2_DMA_ARB_STAT_01_LPR_WPTR                   (0xfL<<4)
+#define BNX2_DMA_ARB_STAT_01_LPB_RPTR                   (0xfL<<8)
+#define BNX2_DMA_ARB_STAT_01_LPB_WPTR                   (0xfL<<12)
+#define BNX2_DMA_ARB_STAT_01_HPR_RPTR                   (0xfL<<16)
+#define BNX2_DMA_ARB_STAT_01_HPR_WPTR                   (0xfL<<20)
+#define BNX2_DMA_ARB_STAT_01_HPB_RPTR                   (0xfL<<24)
+#define BNX2_DMA_ARB_STAT_01_HPB_WPTR                   (0xfL<<28)
+
+#define BNX2_DMA_FUSE_CTRL0_CMD                                0x00000f00
+#define BNX2_DMA_FUSE_CTRL0_CMD_PWRUP_DONE              (1L<<0)
+#define BNX2_DMA_FUSE_CTRL0_CMD_SHIFT_DONE              (1L<<1)
+#define BNX2_DMA_FUSE_CTRL0_CMD_SHIFT                   (1L<<2)
+#define BNX2_DMA_FUSE_CTRL0_CMD_LOAD                    (1L<<3)
+#define BNX2_DMA_FUSE_CTRL0_CMD_SEL                     (0xfL<<8)
+
+#define BNX2_DMA_FUSE_CTRL0_DATA                       0x00000f04
+#define BNX2_DMA_FUSE_CTRL1_CMD                                0x00000f08
+#define BNX2_DMA_FUSE_CTRL1_CMD_PWRUP_DONE              (1L<<0)
+#define BNX2_DMA_FUSE_CTRL1_CMD_SHIFT_DONE              (1L<<1)
+#define BNX2_DMA_FUSE_CTRL1_CMD_SHIFT                   (1L<<2)
+#define BNX2_DMA_FUSE_CTRL1_CMD_LOAD                    (1L<<3)
+#define BNX2_DMA_FUSE_CTRL1_CMD_SEL                     (0xfL<<8)
+
+#define BNX2_DMA_FUSE_CTRL1_DATA                       0x00000f0c
+#define BNX2_DMA_FUSE_CTRL2_CMD                                0x00000f10
+#define BNX2_DMA_FUSE_CTRL2_CMD_PWRUP_DONE              (1L<<0)
+#define BNX2_DMA_FUSE_CTRL2_CMD_SHIFT_DONE              (1L<<1)
+#define BNX2_DMA_FUSE_CTRL2_CMD_SHIFT                   (1L<<2)
+#define BNX2_DMA_FUSE_CTRL2_CMD_LOAD                    (1L<<3)
+#define BNX2_DMA_FUSE_CTRL2_CMD_SEL                     (0xfL<<8)
+
+#define BNX2_DMA_FUSE_CTRL2_DATA                       0x00000f14
+
+
+/*
+ *  context_reg definition
+ *  offset: 0x1000
+ */
+#define BNX2_CTX_COMMAND                               0x00001000
+#define BNX2_CTX_COMMAND_ENABLED                        (1L<<0)
+
+#define BNX2_CTX_STATUS                                        0x00001004
+#define BNX2_CTX_STATUS_LOCK_WAIT                       (1L<<0)
+#define BNX2_CTX_STATUS_READ_STAT                       (1L<<16)
+#define BNX2_CTX_STATUS_WRITE_STAT                      (1L<<17)
+#define BNX2_CTX_STATUS_ACC_STALL_STAT                  (1L<<18)
+#define BNX2_CTX_STATUS_LOCK_STALL_STAT                         (1L<<19)
+
+#define BNX2_CTX_VIRT_ADDR                             0x00001008
+#define BNX2_CTX_VIRT_ADDR_VIRT_ADDR                    (0x7fffL<<6)
+
+#define BNX2_CTX_PAGE_TBL                              0x0000100c
+#define BNX2_CTX_PAGE_TBL_PAGE_TBL                      (0x3fffL<<6)
+
+#define BNX2_CTX_DATA_ADR                              0x00001010
+#define BNX2_CTX_DATA_ADR_DATA_ADR                      (0x7ffffL<<2)
+
+#define BNX2_CTX_DATA                                  0x00001014
+#define BNX2_CTX_LOCK                                  0x00001018
+#define BNX2_CTX_LOCK_TYPE                              (0x7L<<0)
+#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_VOID               (0x0L<<0)
+#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_COMPLETE           (0x7L<<0)
+#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_PROTOCOL           (0x1L<<0)
+#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TX                         (0x2L<<0)
+#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TIMER              (0x4L<<0)
+#define BNX2_CTX_LOCK_CID_VALUE                                 (0x3fffL<<7)
+#define BNX2_CTX_LOCK_GRANTED                           (1L<<26)
+#define BNX2_CTX_LOCK_MODE                              (0x7L<<27)
+#define BNX2_CTX_LOCK_MODE_UNLOCK                       (0x0L<<27)
+#define BNX2_CTX_LOCK_MODE_IMMEDIATE                    (0x1L<<27)
+#define BNX2_CTX_LOCK_MODE_SURE                                 (0x2L<<27)
+#define BNX2_CTX_LOCK_STATUS                            (1L<<30)
+#define BNX2_CTX_LOCK_REQ                               (1L<<31)
+
+#define BNX2_CTX_ACCESS_STATUS                         0x00001040
+#define BNX2_CTX_ACCESS_STATUS_MASTERENCODED            (0xfL<<0)
+#define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYSM           (0x3L<<10)
+#define BNX2_CTX_ACCESS_STATUS_PAGETABLEINITSM          (0x3L<<12)
+#define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYINITSM       (0x3L<<14)
+#define BNX2_CTX_ACCESS_STATUS_QUALIFIED_REQUEST        (0x7ffL<<17)
+
+#define BNX2_CTX_DBG_LOCK_STATUS                       0x00001044
+#define BNX2_CTX_DBG_LOCK_STATUS_SM                     (0x3ffL<<0)
+#define BNX2_CTX_DBG_LOCK_STATUS_MATCH                  (0x3ffL<<22)
+
+#define BNX2_CTX_CHNL_LOCK_STATUS_0                    0x00001080
+#define BNX2_CTX_CHNL_LOCK_STATUS_0_CID                         (0x3fffL<<0)
+#define BNX2_CTX_CHNL_LOCK_STATUS_0_TYPE                (0x3L<<14)
+#define BNX2_CTX_CHNL_LOCK_STATUS_0_MODE                (1L<<16)
+
+#define BNX2_CTX_CHNL_LOCK_STATUS_1                    0x00001084
+#define BNX2_CTX_CHNL_LOCK_STATUS_2                    0x00001088
+#define BNX2_CTX_CHNL_LOCK_STATUS_3                    0x0000108c
+#define BNX2_CTX_CHNL_LOCK_STATUS_4                    0x00001090
+#define BNX2_CTX_CHNL_LOCK_STATUS_5                    0x00001094
+#define BNX2_CTX_CHNL_LOCK_STATUS_6                    0x00001098
+#define BNX2_CTX_CHNL_LOCK_STATUS_7                    0x0000109c
+#define BNX2_CTX_CHNL_LOCK_STATUS_8                    0x000010a0
+
+
+/*
+ *  emac_reg definition
+ *  offset: 0x1400
+ */
+#define BNX2_EMAC_MODE                                 0x00001400
+#define BNX2_EMAC_MODE_RESET                            (1L<<0)
+#define BNX2_EMAC_MODE_HALF_DUPLEX                      (1L<<1)
+#define BNX2_EMAC_MODE_PORT                             (0x3L<<2)
+#define BNX2_EMAC_MODE_PORT_NONE                        (0L<<2)
+#define BNX2_EMAC_MODE_PORT_MII                                 (1L<<2)
+#define BNX2_EMAC_MODE_PORT_GMII                        (2L<<2)
+#define BNX2_EMAC_MODE_PORT_UNDEF                       (3L<<2)
+#define BNX2_EMAC_MODE_MAC_LOOP                                 (1L<<4)
+#define BNX2_EMAC_MODE_TAGGED_MAC_CTL                   (1L<<7)
+#define BNX2_EMAC_MODE_TX_BURST                                 (1L<<8)
+#define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA               (1L<<9)
+#define BNX2_EMAC_MODE_EXT_LINK_POL                     (1L<<10)
+#define BNX2_EMAC_MODE_FORCE_LINK                       (1L<<11)
+#define BNX2_EMAC_MODE_MPKT                             (1L<<18)
+#define BNX2_EMAC_MODE_MPKT_RCVD                        (1L<<19)
+#define BNX2_EMAC_MODE_ACPI_RCVD                        (1L<<20)
+
+#define BNX2_EMAC_STATUS                               0x00001404
+#define BNX2_EMAC_STATUS_LINK                           (1L<<11)
+#define BNX2_EMAC_STATUS_LINK_CHANGE                    (1L<<12)
+#define BNX2_EMAC_STATUS_MI_COMPLETE                    (1L<<22)
+#define BNX2_EMAC_STATUS_MI_INT                                 (1L<<23)
+#define BNX2_EMAC_STATUS_AP_ERROR                       (1L<<24)
+#define BNX2_EMAC_STATUS_PARITY_ERROR_STATE             (1L<<31)
+
+#define BNX2_EMAC_ATTENTION_ENA                                0x00001408
+#define BNX2_EMAC_ATTENTION_ENA_LINK                    (1L<<11)
+#define BNX2_EMAC_ATTENTION_ENA_MI_COMPLETE             (1L<<22)
+#define BNX2_EMAC_ATTENTION_ENA_MI_INT                  (1L<<23)
+#define BNX2_EMAC_ATTENTION_ENA_AP_ERROR                (1L<<24)
+
+#define BNX2_EMAC_LED                                  0x0000140c
+#define BNX2_EMAC_LED_OVERRIDE                          (1L<<0)
+#define BNX2_EMAC_LED_1000MB_OVERRIDE                   (1L<<1)
+#define BNX2_EMAC_LED_100MB_OVERRIDE                    (1L<<2)
+#define BNX2_EMAC_LED_10MB_OVERRIDE                     (1L<<3)
+#define BNX2_EMAC_LED_TRAFFIC_OVERRIDE                  (1L<<4)
+#define BNX2_EMAC_LED_BLNK_TRAFFIC                      (1L<<5)
+#define BNX2_EMAC_LED_TRAFFIC                           (1L<<6)
+#define BNX2_EMAC_LED_1000MB                            (1L<<7)
+#define BNX2_EMAC_LED_100MB                             (1L<<8)
+#define BNX2_EMAC_LED_10MB                              (1L<<9)
+#define BNX2_EMAC_LED_TRAFFIC_STAT                      (1L<<10)
+#define BNX2_EMAC_LED_BLNK_RATE                                 (0xfffL<<19)
+#define BNX2_EMAC_LED_BLNK_RATE_ENA                     (1L<<31)
+
+#define BNX2_EMAC_MAC_MATCH0                           0x00001410
+#define BNX2_EMAC_MAC_MATCH1                           0x00001414
+#define BNX2_EMAC_MAC_MATCH2                           0x00001418
+#define BNX2_EMAC_MAC_MATCH3                           0x0000141c
+#define BNX2_EMAC_MAC_MATCH4                           0x00001420
+#define BNX2_EMAC_MAC_MATCH5                           0x00001424
+#define BNX2_EMAC_MAC_MATCH6                           0x00001428
+#define BNX2_EMAC_MAC_MATCH7                           0x0000142c
+#define BNX2_EMAC_MAC_MATCH8                           0x00001430
+#define BNX2_EMAC_MAC_MATCH9                           0x00001434
+#define BNX2_EMAC_MAC_MATCH10                          0x00001438
+#define BNX2_EMAC_MAC_MATCH11                          0x0000143c
+#define BNX2_EMAC_MAC_MATCH12                          0x00001440
+#define BNX2_EMAC_MAC_MATCH13                          0x00001444
+#define BNX2_EMAC_MAC_MATCH14                          0x00001448
+#define BNX2_EMAC_MAC_MATCH15                          0x0000144c
+#define BNX2_EMAC_MAC_MATCH16                          0x00001450
+#define BNX2_EMAC_MAC_MATCH17                          0x00001454
+#define BNX2_EMAC_MAC_MATCH18                          0x00001458
+#define BNX2_EMAC_MAC_MATCH19                          0x0000145c
+#define BNX2_EMAC_MAC_MATCH20                          0x00001460
+#define BNX2_EMAC_MAC_MATCH21                          0x00001464
+#define BNX2_EMAC_MAC_MATCH22                          0x00001468
+#define BNX2_EMAC_MAC_MATCH23                          0x0000146c
+#define BNX2_EMAC_MAC_MATCH24                          0x00001470
+#define BNX2_EMAC_MAC_MATCH25                          0x00001474
+#define BNX2_EMAC_MAC_MATCH26                          0x00001478
+#define BNX2_EMAC_MAC_MATCH27                          0x0000147c
+#define BNX2_EMAC_MAC_MATCH28                          0x00001480
+#define BNX2_EMAC_MAC_MATCH29                          0x00001484
+#define BNX2_EMAC_MAC_MATCH30                          0x00001488
+#define BNX2_EMAC_MAC_MATCH31                          0x0000148c
+#define BNX2_EMAC_BACKOFF_SEED                         0x00001498
+#define BNX2_EMAC_BACKOFF_SEED_EMAC_BACKOFF_SEED        (0x3ffL<<0)
+
+#define BNX2_EMAC_RX_MTU_SIZE                          0x0000149c
+#define BNX2_EMAC_RX_MTU_SIZE_MTU_SIZE                  (0xffffL<<0)
+#define BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA                         (1L<<31)
+
+#define BNX2_EMAC_SERDES_CNTL                          0x000014a4
+#define BNX2_EMAC_SERDES_CNTL_RXR                       (0x7L<<0)
+#define BNX2_EMAC_SERDES_CNTL_RXG                       (0x3L<<3)
+#define BNX2_EMAC_SERDES_CNTL_RXCKSEL                   (1L<<6)
+#define BNX2_EMAC_SERDES_CNTL_TXBIAS                    (0x7L<<7)
+#define BNX2_EMAC_SERDES_CNTL_BGMAX                     (1L<<10)
+#define BNX2_EMAC_SERDES_CNTL_BGMIN                     (1L<<11)
+#define BNX2_EMAC_SERDES_CNTL_TXMODE                    (1L<<12)
+#define BNX2_EMAC_SERDES_CNTL_TXEDGE                    (1L<<13)
+#define BNX2_EMAC_SERDES_CNTL_SERDES_MODE               (1L<<14)
+#define BNX2_EMAC_SERDES_CNTL_PLLTEST                   (1L<<15)
+#define BNX2_EMAC_SERDES_CNTL_CDET_EN                   (1L<<16)
+#define BNX2_EMAC_SERDES_CNTL_TBI_LBK                   (1L<<17)
+#define BNX2_EMAC_SERDES_CNTL_REMOTE_LBK                (1L<<18)
+#define BNX2_EMAC_SERDES_CNTL_REV_PHASE                         (1L<<19)
+#define BNX2_EMAC_SERDES_CNTL_REGCTL12                  (0x3L<<20)
+#define BNX2_EMAC_SERDES_CNTL_REGCTL25                  (0x3L<<22)
+
+#define BNX2_EMAC_SERDES_STATUS                                0x000014a8
+#define BNX2_EMAC_SERDES_STATUS_RX_STAT                         (0xffL<<0)
+#define BNX2_EMAC_SERDES_STATUS_COMMA_DET               (1L<<8)
+
+#define BNX2_EMAC_MDIO_COMM                            0x000014ac
+#define BNX2_EMAC_MDIO_COMM_DATA                        (0xffffL<<0)
+#define BNX2_EMAC_MDIO_COMM_REG_ADDR                    (0x1fL<<16)
+#define BNX2_EMAC_MDIO_COMM_PHY_ADDR                    (0x1fL<<21)
+#define BNX2_EMAC_MDIO_COMM_COMMAND                     (0x3L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_0                 (0L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_WRITE               (1L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_READ                (2L<<26)
+#define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_3                 (3L<<26)
+#define BNX2_EMAC_MDIO_COMM_FAIL                        (1L<<28)
+#define BNX2_EMAC_MDIO_COMM_START_BUSY                  (1L<<29)
+#define BNX2_EMAC_MDIO_COMM_DISEXT                      (1L<<30)
+
+#define BNX2_EMAC_MDIO_STATUS                          0x000014b0
+#define BNX2_EMAC_MDIO_STATUS_LINK                      (1L<<0)
+#define BNX2_EMAC_MDIO_STATUS_10MB                      (1L<<1)
+
+#define BNX2_EMAC_MDIO_MODE                            0x000014b4
+#define BNX2_EMAC_MDIO_MODE_SHORT_PREAMBLE              (1L<<1)
+#define BNX2_EMAC_MDIO_MODE_AUTO_POLL                   (1L<<4)
+#define BNX2_EMAC_MDIO_MODE_BIT_BANG                    (1L<<8)
+#define BNX2_EMAC_MDIO_MODE_MDIO                        (1L<<9)
+#define BNX2_EMAC_MDIO_MODE_MDIO_OE                     (1L<<10)
+#define BNX2_EMAC_MDIO_MODE_MDC                                 (1L<<11)
+#define BNX2_EMAC_MDIO_MODE_MDINT                       (1L<<12)
+#define BNX2_EMAC_MDIO_MODE_CLOCK_CNT                   (0x1fL<<16)
+
+#define BNX2_EMAC_MDIO_AUTO_STATUS                     0x000014b8
+#define BNX2_EMAC_MDIO_AUTO_STATUS_AUTO_ERR             (1L<<0)
+
+#define BNX2_EMAC_TX_MODE                              0x000014bc
+#define BNX2_EMAC_TX_MODE_RESET                                 (1L<<0)
+#define BNX2_EMAC_TX_MODE_EXT_PAUSE_EN                  (1L<<3)
+#define BNX2_EMAC_TX_MODE_FLOW_EN                       (1L<<4)
+#define BNX2_EMAC_TX_MODE_BIG_BACKOFF                   (1L<<5)
+#define BNX2_EMAC_TX_MODE_LONG_PAUSE                    (1L<<6)
+#define BNX2_EMAC_TX_MODE_LINK_AWARE                    (1L<<7)
+
+#define BNX2_EMAC_TX_STATUS                            0x000014c0
+#define BNX2_EMAC_TX_STATUS_XOFFED                      (1L<<0)
+#define BNX2_EMAC_TX_STATUS_XOFF_SENT                   (1L<<1)
+#define BNX2_EMAC_TX_STATUS_XON_SENT                    (1L<<2)
+#define BNX2_EMAC_TX_STATUS_LINK_UP                     (1L<<3)
+#define BNX2_EMAC_TX_STATUS_UNDERRUN                    (1L<<4)
+
+#define BNX2_EMAC_TX_LENGTHS                           0x000014c4
+#define BNX2_EMAC_TX_LENGTHS_SLOT                       (0xffL<<0)
+#define BNX2_EMAC_TX_LENGTHS_IPG                        (0xfL<<8)
+#define BNX2_EMAC_TX_LENGTHS_IPG_CRS                    (0x3L<<12)
+
+#define BNX2_EMAC_RX_MODE                              0x000014c8
+#define BNX2_EMAC_RX_MODE_RESET                                 (1L<<0)
+#define BNX2_EMAC_RX_MODE_FLOW_EN                       (1L<<2)
+#define BNX2_EMAC_RX_MODE_KEEP_MAC_CONTROL              (1L<<3)
+#define BNX2_EMAC_RX_MODE_KEEP_PAUSE                    (1L<<4)
+#define BNX2_EMAC_RX_MODE_ACCEPT_OVERSIZE               (1L<<5)
+#define BNX2_EMAC_RX_MODE_ACCEPT_RUNTS                  (1L<<6)
+#define BNX2_EMAC_RX_MODE_LLC_CHK                       (1L<<7)
+#define BNX2_EMAC_RX_MODE_PROMISCUOUS                   (1L<<8)
+#define BNX2_EMAC_RX_MODE_NO_CRC_CHK                    (1L<<9)
+#define BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG                         (1L<<10)
+#define BNX2_EMAC_RX_MODE_FILT_BROADCAST                (1L<<11)
+#define BNX2_EMAC_RX_MODE_SORT_MODE                     (1L<<12)
+
+#define BNX2_EMAC_RX_STATUS                            0x000014cc
+#define BNX2_EMAC_RX_STATUS_FFED                        (1L<<0)
+#define BNX2_EMAC_RX_STATUS_FF_RECEIVED                         (1L<<1)
+#define BNX2_EMAC_RX_STATUS_N_RECEIVED                  (1L<<2)
+
+#define BNX2_EMAC_MULTICAST_HASH0                      0x000014d0
+#define BNX2_EMAC_MULTICAST_HASH1                      0x000014d4
+#define BNX2_EMAC_MULTICAST_HASH2                      0x000014d8
+#define BNX2_EMAC_MULTICAST_HASH3                      0x000014dc
+#define BNX2_EMAC_MULTICAST_HASH4                      0x000014e0
+#define BNX2_EMAC_MULTICAST_HASH5                      0x000014e4
+#define BNX2_EMAC_MULTICAST_HASH6                      0x000014e8
+#define BNX2_EMAC_MULTICAST_HASH7                      0x000014ec
+#define BNX2_EMAC_RX_STAT_IFHCINOCTETS                 0x00001500
+#define BNX2_EMAC_RX_STAT_IFHCINBADOCTETS              0x00001504
+#define BNX2_EMAC_RX_STAT_ETHERSTATSFRAGMENTS          0x00001508
+#define BNX2_EMAC_RX_STAT_IFHCINUCASTPKTS              0x0000150c
+#define BNX2_EMAC_RX_STAT_IFHCINMULTICASTPKTS          0x00001510
+#define BNX2_EMAC_RX_STAT_IFHCINBROADCASTPKTS          0x00001514
+#define BNX2_EMAC_RX_STAT_DOT3STATSFCSERRORS           0x00001518
+#define BNX2_EMAC_RX_STAT_DOT3STATSALIGNMENTERRORS     0x0000151c
+#define BNX2_EMAC_RX_STAT_DOT3STATSCARRIERSENSEERRORS  0x00001520
+#define BNX2_EMAC_RX_STAT_XONPAUSEFRAMESRECEIVED       0x00001524
+#define BNX2_EMAC_RX_STAT_XOFFPAUSEFRAMESRECEIVED      0x00001528
+#define BNX2_EMAC_RX_STAT_MACCONTROLFRAMESRECEIVED     0x0000152c
+#define BNX2_EMAC_RX_STAT_XOFFSTATEENTERED             0x00001530
+#define BNX2_EMAC_RX_STAT_DOT3STATSFRAMESTOOLONG       0x00001534
+#define BNX2_EMAC_RX_STAT_ETHERSTATSJABBERS            0x00001538
+#define BNX2_EMAC_RX_STAT_ETHERSTATSUNDERSIZEPKTS      0x0000153c
+#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS64OCTETS       0x00001540
+#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS65OCTETSTO127OCTETS    0x00001544
+#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS128OCTETSTO255OCTETS   0x00001548
+#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS   0x0000154c
+#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS  0x00001550
+#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS 0x00001554
+#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS1523OCTETSTO9022OCTETS 0x00001558
+#define BNX2_EMAC_RXMAC_DEBUG0                         0x0000155c
+#define BNX2_EMAC_RXMAC_DEBUG1                         0x00001560
+#define BNX2_EMAC_RXMAC_DEBUG1_LENGTH_NE_BYTE_COUNT     (1L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG1_LENGTH_OUT_RANGE                 (1L<<1)
+#define BNX2_EMAC_RXMAC_DEBUG1_BAD_CRC                  (1L<<2)
+#define BNX2_EMAC_RXMAC_DEBUG1_RX_ERROR                         (1L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG1_ALIGN_ERROR              (1L<<4)
+#define BNX2_EMAC_RXMAC_DEBUG1_LAST_DATA                (1L<<5)
+#define BNX2_EMAC_RXMAC_DEBUG1_ODD_BYTE_START           (1L<<6)
+#define BNX2_EMAC_RXMAC_DEBUG1_BYTE_COUNT               (0xffffL<<7)
+#define BNX2_EMAC_RXMAC_DEBUG1_SLOT_TIME                (0xffL<<23)
+
+#define BNX2_EMAC_RXMAC_DEBUG2                         0x00001564
+#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE                         (0x7L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_IDLE            (0x0L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SFD             (0x1L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_DATA            (0x2L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SKEEP           (0x3L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_EXT             (0x4L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_DROP            (0x5L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SDROP           (0x6L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_FC              (0x7L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE                (0xfL<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_IDLE           (0x0L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA0          (0x1L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA1          (0x2L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA2          (0x3L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA3          (0x4L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_ABORT          (0x5L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_WAIT           (0x6L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_STATUS                 (0x7L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_LAST           (0x8L<<3)
+#define BNX2_EMAC_RXMAC_DEBUG2_BYTE_IN                  (0xffL<<7)
+#define BNX2_EMAC_RXMAC_DEBUG2_FALSEC                   (1L<<15)
+#define BNX2_EMAC_RXMAC_DEBUG2_TAGGED                   (1L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE              (1L<<18)
+#define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE_IDLE                 (0L<<18)
+#define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE_PAUSED       (1L<<18)
+#define BNX2_EMAC_RXMAC_DEBUG2_SE_COUNTER               (0xfL<<19)
+#define BNX2_EMAC_RXMAC_DEBUG2_QUANTA                   (0x1fL<<23)
+
+#define BNX2_EMAC_RXMAC_DEBUG3                         0x00001568
+#define BNX2_EMAC_RXMAC_DEBUG3_PAUSE_CTR                (0xffffL<<0)
+#define BNX2_EMAC_RXMAC_DEBUG3_TMP_PAUSE_CTR            (0xffffL<<16)
+
+#define BNX2_EMAC_RXMAC_DEBUG4                         0x0000156c
+#define BNX2_EMAC_RXMAC_DEBUG4_TYPE_FIELD               (0xffffL<<0)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE               (0x3fL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_IDLE          (0x0L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC2                 (0x1L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC3                 (0x2L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UNI           (0x3L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC2                 (0x7L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC3                 (0x5L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA1          (0x6L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA2          (0x7L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA3          (0x8L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC2           (0x9L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC3           (0xaL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MWAIT1        (0xeL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MWAIT2        (0xfL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MCHECK        (0x10L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC            (0x11L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC2           (0x12L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC3           (0x13L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA1          (0x14L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA2          (0x15L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA3          (0x16L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BTYPE                 (0x17L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC            (0x18L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PTYPE                 (0x19L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_CMD           (0x1aL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MAC           (0x1bL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_LATCH                 (0x1cL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_XOFF          (0x1dL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_XON           (0x1eL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PAUSED        (0x1fL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_NPAUSED       (0x20L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_TTYPE                 (0x21L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_TVAL          (0x22L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA1          (0x23L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA2          (0x24L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA3          (0x25L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTYPE                 (0x26L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTTYPE        (0x27L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTVAL                 (0x28L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MTYPE                 (0x29L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_DROP          (0x2aL<<16)
+#define BNX2_EMAC_RXMAC_DEBUG4_DROP_PKT                         (1L<<22)
+#define BNX2_EMAC_RXMAC_DEBUG4_SLOT_FILLED              (1L<<23)
+#define BNX2_EMAC_RXMAC_DEBUG4_FALSE_CARRIER            (1L<<24)
+#define BNX2_EMAC_RXMAC_DEBUG4_LAST_DATA                (1L<<25)
+#define BNX2_EMAC_RXMAC_DEBUG4_sfd_FOUND                (1L<<26)
+#define BNX2_EMAC_RXMAC_DEBUG4_ADVANCE                  (1L<<27)
+#define BNX2_EMAC_RXMAC_DEBUG4_START                    (1L<<28)
+
+#define BNX2_EMAC_RXMAC_DEBUG5                         0x00001570
+#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM                         (0x7L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_IDLE            (0L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_WAIT_EOF        (1L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_WAIT_STAT       (2L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4FCRC    (3L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4RDE     (4L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4ALL     (5L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_1WD_WAIT_STAT   (6L<<0)
+#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1               (0x7L<<4)
+#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_VDW           (0x0L<<4)
+#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_STAT          (0x1L<<4)
+#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_AEOF          (0x2L<<4)
+#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_NEOF          (0x3L<<4)
+#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SOF           (0x4L<<4)
+#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SAEOF                 (0x6L<<4)
+#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SNEOF                 (0x7L<<4)
+#define BNX2_EMAC_RXMAC_DEBUG5_EOF_DETECTED             (1L<<7)
+#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF0               (0x7L<<8)
+#define BNX2_EMAC_RXMAC_DEBUG5_RPM_IDI_FIFO_FULL        (1L<<11)
+#define BNX2_EMAC_RXMAC_DEBUG5_LOAD_CCODE               (1L<<12)
+#define BNX2_EMAC_RXMAC_DEBUG5_LOAD_DATA                (1L<<13)
+#define BNX2_EMAC_RXMAC_DEBUG5_LOAD_STAT                (1L<<14)
+#define BNX2_EMAC_RXMAC_DEBUG5_CLR_STAT                         (1L<<15)
+#define BNX2_EMAC_RXMAC_DEBUG5_IDI_RPM_CCODE            (0x3L<<16)
+#define BNX2_EMAC_RXMAC_DEBUG5_IDI_RPM_ACCEPT           (1L<<19)
+#define BNX2_EMAC_RXMAC_DEBUG5_FMLEN                    (0xfffL<<20)
+
+#define BNX2_EMAC_RX_STAT_AC0                          0x00001580
+#define BNX2_EMAC_RX_STAT_AC1                          0x00001584
+#define BNX2_EMAC_RX_STAT_AC2                          0x00001588
+#define BNX2_EMAC_RX_STAT_AC3                          0x0000158c
+#define BNX2_EMAC_RX_STAT_AC4                          0x00001590
+#define BNX2_EMAC_RX_STAT_AC5                          0x00001594
+#define BNX2_EMAC_RX_STAT_AC6                          0x00001598
+#define BNX2_EMAC_RX_STAT_AC7                          0x0000159c
+#define BNX2_EMAC_RX_STAT_AC8                          0x000015a0
+#define BNX2_EMAC_RX_STAT_AC9                          0x000015a4
+#define BNX2_EMAC_RX_STAT_AC10                         0x000015a8
+#define BNX2_EMAC_RX_STAT_AC11                         0x000015ac
+#define BNX2_EMAC_RX_STAT_AC12                         0x000015b0
+#define BNX2_EMAC_RX_STAT_AC13                         0x000015b4
+#define BNX2_EMAC_RX_STAT_AC14                         0x000015b8
+#define BNX2_EMAC_RX_STAT_AC15                         0x000015bc
+#define BNX2_EMAC_RX_STAT_AC16                         0x000015c0
+#define BNX2_EMAC_RX_STAT_AC17                         0x000015c4
+#define BNX2_EMAC_RX_STAT_AC18                         0x000015c8
+#define BNX2_EMAC_RX_STAT_AC19                         0x000015cc
+#define BNX2_EMAC_RX_STAT_AC20                         0x000015d0
+#define BNX2_EMAC_RX_STAT_AC21                         0x000015d4
+#define BNX2_EMAC_RX_STAT_AC22                         0x000015d8
+#define BNX2_EMAC_RXMAC_SUC_DBG_OVERRUNVEC             0x000015dc
+#define BNX2_EMAC_TX_STAT_IFHCOUTOCTETS                        0x00001600
+#define BNX2_EMAC_TX_STAT_IFHCOUTBADOCTETS             0x00001604
+#define BNX2_EMAC_TX_STAT_ETHERSTATSCOLLISIONS         0x00001608
+#define BNX2_EMAC_TX_STAT_OUTXONSENT                   0x0000160c
+#define BNX2_EMAC_TX_STAT_OUTXOFFSENT                  0x00001610
+#define BNX2_EMAC_TX_STAT_FLOWCONTROLDONE              0x00001614
+#define BNX2_EMAC_TX_STAT_DOT3STATSSINGLECOLLISIONFRAMES       0x00001618
+#define BNX2_EMAC_TX_STAT_DOT3STATSMULTIPLECOLLISIONFRAMES     0x0000161c
+#define BNX2_EMAC_TX_STAT_DOT3STATSDEFERREDTRANSMISSIONS       0x00001620
+#define BNX2_EMAC_TX_STAT_DOT3STATSEXCESSIVECOLLISIONS 0x00001624
+#define BNX2_EMAC_TX_STAT_DOT3STATSLATECOLLISIONS      0x00001628
+#define BNX2_EMAC_TX_STAT_IFHCOUTUCASTPKTS             0x0000162c
+#define BNX2_EMAC_TX_STAT_IFHCOUTMULTICASTPKTS         0x00001630
+#define BNX2_EMAC_TX_STAT_IFHCOUTBROADCASTPKTS         0x00001634
+#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS64OCTETS       0x00001638
+#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS65OCTETSTO127OCTETS    0x0000163c
+#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS128OCTETSTO255OCTETS   0x00001640
+#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS   0x00001644
+#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS  0x00001648
+#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS 0x0000164c
+#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS1523OCTETSTO9022OCTETS 0x00001650
+#define BNX2_EMAC_TX_STAT_DOT3STATSINTERNALMACTRANSMITERRORS   0x00001654
+#define BNX2_EMAC_TXMAC_DEBUG0                         0x00001658
+#define BNX2_EMAC_TXMAC_DEBUG1                         0x0000165c
+#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE                (0xfL<<0)
+#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_IDLE           (0x0L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_START0                 (0x1L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA0          (0x4L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA1          (0x5L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA2          (0x6L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA3          (0x7L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_WAIT0          (0x8L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_WAIT1          (0x9L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG1_CRS_ENABLE               (1L<<4)
+#define BNX2_EMAC_TXMAC_DEBUG1_BAD_CRC                  (1L<<5)
+#define BNX2_EMAC_TXMAC_DEBUG1_SE_COUNTER               (0xfL<<6)
+#define BNX2_EMAC_TXMAC_DEBUG1_SEND_PAUSE               (1L<<10)
+#define BNX2_EMAC_TXMAC_DEBUG1_LATE_COLLISION           (1L<<11)
+#define BNX2_EMAC_TXMAC_DEBUG1_MAX_DEFER                (1L<<12)
+#define BNX2_EMAC_TXMAC_DEBUG1_DEFERRED                         (1L<<13)
+#define BNX2_EMAC_TXMAC_DEBUG1_ONE_BYTE                         (1L<<14)
+#define BNX2_EMAC_TXMAC_DEBUG1_IPG_TIME                         (0xfL<<15)
+#define BNX2_EMAC_TXMAC_DEBUG1_SLOT_TIME                (0xffL<<19)
+
+#define BNX2_EMAC_TXMAC_DEBUG2                         0x00001660
+#define BNX2_EMAC_TXMAC_DEBUG2_BACK_OFF                         (0x3ffL<<0)
+#define BNX2_EMAC_TXMAC_DEBUG2_BYTE_COUNT               (0xffffL<<10)
+#define BNX2_EMAC_TXMAC_DEBUG2_COL_COUNT                (0x1fL<<26)
+#define BNX2_EMAC_TXMAC_DEBUG2_COL_BIT                  (1L<<31)
+
+#define BNX2_EMAC_TXMAC_DEBUG3                         0x00001664
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE                         (0xfL<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_IDLE            (0x0L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_PRE1            (0x1L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_PRE2            (0x2L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_SFD             (0x3L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_DATA            (0x4L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_CRC1            (0x5L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_CRC2            (0x6L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_EXT             (0x7L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_STATB           (0x8L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_STATG           (0x9L<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_JAM             (0xaL<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_EJAM            (0xbL<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_BJAM            (0xcL<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_SWAIT           (0xdL<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_BACKOFF                 (0xeL<<0)
+#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE               (0x7L<<4)
+#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_IDLE          (0x0L<<4)
+#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_WAIT          (0x1L<<4)
+#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_UNI           (0x2L<<4)
+#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_MC            (0x3L<<4)
+#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC2           (0x4L<<4)
+#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC3           (0x5L<<4)
+#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC            (0x6L<<4)
+#define BNX2_EMAC_TXMAC_DEBUG3_CRS_DONE                         (1L<<7)
+#define BNX2_EMAC_TXMAC_DEBUG3_XOFF                     (1L<<8)
+#define BNX2_EMAC_TXMAC_DEBUG3_SE_COUNTER               (0xfL<<9)
+#define BNX2_EMAC_TXMAC_DEBUG3_QUANTA_COUNTER           (0x1fL<<13)
+
+#define BNX2_EMAC_TXMAC_DEBUG4                         0x00001668
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_COUNTER            (0xffffL<<0)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE              (0xfL<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_IDLE                 (0x0L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA1                 (0x2L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA2                 (0x3L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA3                 (0x6L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC1                 (0x7L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC2                 (0x5L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC3                 (0x4L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TYPE                 (0xcL<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CMD          (0xeL<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TIME                 (0xaL<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC1                 (0x8L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC2                 (0x9L<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_WAIT                 (0xdL<<16)
+#define BNX2_EMAC_TXMAC_DEBUG4_STATS0_VALID             (1L<<20)
+#define BNX2_EMAC_TXMAC_DEBUG4_APPEND_CRC               (1L<<21)
+#define BNX2_EMAC_TXMAC_DEBUG4_SLOT_FILLED              (1L<<22)
+#define BNX2_EMAC_TXMAC_DEBUG4_MAX_DEFER                (1L<<23)
+#define BNX2_EMAC_TXMAC_DEBUG4_SEND_EXTEND              (1L<<24)
+#define BNX2_EMAC_TXMAC_DEBUG4_SEND_PADDING             (1L<<25)
+#define BNX2_EMAC_TXMAC_DEBUG4_EOF_LOC                  (1L<<26)
+#define BNX2_EMAC_TXMAC_DEBUG4_COLLIDING                (1L<<27)
+#define BNX2_EMAC_TXMAC_DEBUG4_COL_IN                   (1L<<28)
+#define BNX2_EMAC_TXMAC_DEBUG4_BURSTING                         (1L<<29)
+#define BNX2_EMAC_TXMAC_DEBUG4_ADVANCE                  (1L<<30)
+#define BNX2_EMAC_TXMAC_DEBUG4_GO                       (1L<<31)
+
+#define BNX2_EMAC_TX_STAT_AC0                          0x00001680
+#define BNX2_EMAC_TX_STAT_AC1                          0x00001684
+#define BNX2_EMAC_TX_STAT_AC2                          0x00001688
+#define BNX2_EMAC_TX_STAT_AC3                          0x0000168c
+#define BNX2_EMAC_TX_STAT_AC4                          0x00001690
+#define BNX2_EMAC_TX_STAT_AC5                          0x00001694
+#define BNX2_EMAC_TX_STAT_AC6                          0x00001698
+#define BNX2_EMAC_TX_STAT_AC7                          0x0000169c
+#define BNX2_EMAC_TX_STAT_AC8                          0x000016a0
+#define BNX2_EMAC_TX_STAT_AC9                          0x000016a4
+#define BNX2_EMAC_TX_STAT_AC10                         0x000016a8
+#define BNX2_EMAC_TX_STAT_AC11                         0x000016ac
+#define BNX2_EMAC_TX_STAT_AC12                         0x000016b0
+#define BNX2_EMAC_TX_STAT_AC13                         0x000016b4
+#define BNX2_EMAC_TX_STAT_AC14                         0x000016b8
+#define BNX2_EMAC_TX_STAT_AC15                         0x000016bc
+#define BNX2_EMAC_TX_STAT_AC16                         0x000016c0
+#define BNX2_EMAC_TX_STAT_AC17                         0x000016c4
+#define BNX2_EMAC_TX_STAT_AC18                         0x000016c8
+#define BNX2_EMAC_TX_STAT_AC19                         0x000016cc
+#define BNX2_EMAC_TX_STAT_AC20                         0x000016d0
+#define BNX2_EMAC_TX_STAT_AC21                         0x000016d4
+#define BNX2_EMAC_TXMAC_SUC_DBG_OVERRUNVEC             0x000016d8
+
+
+/*
+ *  rpm_reg definition
+ *  offset: 0x1800
+ */
+#define BNX2_RPM_COMMAND                               0x00001800
+#define BNX2_RPM_COMMAND_ENABLED                        (1L<<0)
+#define BNX2_RPM_COMMAND_OVERRUN_ABORT                  (1L<<4)
+
+#define BNX2_RPM_STATUS                                        0x00001804
+#define BNX2_RPM_STATUS_MBUF_WAIT                       (1L<<0)
+#define BNX2_RPM_STATUS_FREE_WAIT                       (1L<<1)
+
+#define BNX2_RPM_CONFIG                                        0x00001808
+#define BNX2_RPM_CONFIG_NO_PSD_HDR_CKSUM                (1L<<0)
+#define BNX2_RPM_CONFIG_ACPI_ENA                        (1L<<1)
+#define BNX2_RPM_CONFIG_ACPI_KEEP                       (1L<<2)
+#define BNX2_RPM_CONFIG_MP_KEEP                                 (1L<<3)
+#define BNX2_RPM_CONFIG_SORT_VECT_VAL                   (0xfL<<4)
+#define BNX2_RPM_CONFIG_IGNORE_VLAN                     (1L<<31)
+
+#define BNX2_RPM_VLAN_MATCH0                           0x00001810
+#define BNX2_RPM_VLAN_MATCH0_RPM_VLAN_MTCH0_VALUE       (0xfffL<<0)
+
+#define BNX2_RPM_VLAN_MATCH1                           0x00001814
+#define BNX2_RPM_VLAN_MATCH1_RPM_VLAN_MTCH1_VALUE       (0xfffL<<0)
+
+#define BNX2_RPM_VLAN_MATCH2                           0x00001818
+#define BNX2_RPM_VLAN_MATCH2_RPM_VLAN_MTCH2_VALUE       (0xfffL<<0)
+
+#define BNX2_RPM_VLAN_MATCH3                           0x0000181c
+#define BNX2_RPM_VLAN_MATCH3_RPM_VLAN_MTCH3_VALUE       (0xfffL<<0)
+
+#define BNX2_RPM_SORT_USER0                            0x00001820
+#define BNX2_RPM_SORT_USER0_PM_EN                       (0xffffL<<0)
+#define BNX2_RPM_SORT_USER0_BC_EN                       (1L<<16)
+#define BNX2_RPM_SORT_USER0_MC_EN                       (1L<<17)
+#define BNX2_RPM_SORT_USER0_MC_HSH_EN                   (1L<<18)
+#define BNX2_RPM_SORT_USER0_PROM_EN                     (1L<<19)
+#define BNX2_RPM_SORT_USER0_VLAN_EN                     (0xfL<<20)
+#define BNX2_RPM_SORT_USER0_PROM_VLAN                   (1L<<24)
+#define BNX2_RPM_SORT_USER0_ENA                                 (1L<<31)
+
+#define BNX2_RPM_SORT_USER1                            0x00001824
+#define BNX2_RPM_SORT_USER1_PM_EN                       (0xffffL<<0)
+#define BNX2_RPM_SORT_USER1_BC_EN                       (1L<<16)
+#define BNX2_RPM_SORT_USER1_MC_EN                       (1L<<17)
+#define BNX2_RPM_SORT_USER1_MC_HSH_EN                   (1L<<18)
+#define BNX2_RPM_SORT_USER1_PROM_EN                     (1L<<19)
+#define BNX2_RPM_SORT_USER1_VLAN_EN                     (0xfL<<20)
+#define BNX2_RPM_SORT_USER1_PROM_VLAN                   (1L<<24)
+#define BNX2_RPM_SORT_USER1_ENA                                 (1L<<31)
+
+#define BNX2_RPM_SORT_USER2                            0x00001828
+#define BNX2_RPM_SORT_USER2_PM_EN                       (0xffffL<<0)
+#define BNX2_RPM_SORT_USER2_BC_EN                       (1L<<16)
+#define BNX2_RPM_SORT_USER2_MC_EN                       (1L<<17)
+#define BNX2_RPM_SORT_USER2_MC_HSH_EN                   (1L<<18)
+#define BNX2_RPM_SORT_USER2_PROM_EN                     (1L<<19)
+#define BNX2_RPM_SORT_USER2_VLAN_EN                     (0xfL<<20)
+#define BNX2_RPM_SORT_USER2_PROM_VLAN                   (1L<<24)
+#define BNX2_RPM_SORT_USER2_ENA                                 (1L<<31)
+
+#define BNX2_RPM_SORT_USER3                            0x0000182c
+#define BNX2_RPM_SORT_USER3_PM_EN                       (0xffffL<<0)
+#define BNX2_RPM_SORT_USER3_BC_EN                       (1L<<16)
+#define BNX2_RPM_SORT_USER3_MC_EN                       (1L<<17)
+#define BNX2_RPM_SORT_USER3_MC_HSH_EN                   (1L<<18)
+#define BNX2_RPM_SORT_USER3_PROM_EN                     (1L<<19)
+#define BNX2_RPM_SORT_USER3_VLAN_EN                     (0xfL<<20)
+#define BNX2_RPM_SORT_USER3_PROM_VLAN                   (1L<<24)
+#define BNX2_RPM_SORT_USER3_ENA                                 (1L<<31)
+
+#define BNX2_RPM_STAT_L2_FILTER_DISCARDS               0x00001840
+#define BNX2_RPM_STAT_RULE_CHECKER_DISCARDS            0x00001844
+#define BNX2_RPM_STAT_IFINFTQDISCARDS                  0x00001848
+#define BNX2_RPM_STAT_IFINMBUFDISCARD                  0x0000184c
+#define BNX2_RPM_STAT_RULE_CHECKER_P4_HIT              0x00001850
+#define BNX2_RPM_STAT_AC0                              0x00001880
+#define BNX2_RPM_STAT_AC1                              0x00001884
+#define BNX2_RPM_STAT_AC2                              0x00001888
+#define BNX2_RPM_STAT_AC3                              0x0000188c
+#define BNX2_RPM_STAT_AC4                              0x00001890
+#define BNX2_RPM_RC_CNTL_0                             0x00001900
+#define BNX2_RPM_RC_CNTL_0_OFFSET                       (0xffL<<0)
+#define BNX2_RPM_RC_CNTL_0_CLASS                        (0x7L<<8)
+#define BNX2_RPM_RC_CNTL_0_PRIORITY                     (1L<<11)
+#define BNX2_RPM_RC_CNTL_0_P4                           (1L<<12)
+#define BNX2_RPM_RC_CNTL_0_HDR_TYPE                     (0x7L<<13)
+#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_START               (0L<<13)
+#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_IP                  (1L<<13)
+#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_TCP                         (2L<<13)
+#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_UDP                         (3L<<13)
+#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_DATA                (4L<<13)
+#define BNX2_RPM_RC_CNTL_0_COMP                                 (0x3L<<16)
+#define BNX2_RPM_RC_CNTL_0_COMP_EQUAL                   (0L<<16)
+#define BNX2_RPM_RC_CNTL_0_COMP_NEQUAL                  (1L<<16)
+#define BNX2_RPM_RC_CNTL_0_COMP_GREATER                         (2L<<16)
+#define BNX2_RPM_RC_CNTL_0_COMP_LESS                    (3L<<16)
+#define BNX2_RPM_RC_CNTL_0_SBIT                                 (1L<<19)
+#define BNX2_RPM_RC_CNTL_0_CMDSEL                       (0xfL<<20)
+#define BNX2_RPM_RC_CNTL_0_MAP                          (1L<<24)
+#define BNX2_RPM_RC_CNTL_0_DISCARD                      (1L<<25)
+#define BNX2_RPM_RC_CNTL_0_MASK                                 (1L<<26)
+#define BNX2_RPM_RC_CNTL_0_P1                           (1L<<27)
+#define BNX2_RPM_RC_CNTL_0_P2                           (1L<<28)
+#define BNX2_RPM_RC_CNTL_0_P3                           (1L<<29)
+#define BNX2_RPM_RC_CNTL_0_NBIT                                 (1L<<30)
+
+#define BNX2_RPM_RC_VALUE_MASK_0                       0x00001904
+#define BNX2_RPM_RC_VALUE_MASK_0_VALUE                  (0xffffL<<0)
+#define BNX2_RPM_RC_VALUE_MASK_0_MASK                   (0xffffL<<16)
+
+#define BNX2_RPM_RC_CNTL_1                             0x00001908
+#define BNX2_RPM_RC_CNTL_1_A                            (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_1_B                            (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_1                       0x0000190c
+#define BNX2_RPM_RC_CNTL_2                             0x00001910
+#define BNX2_RPM_RC_CNTL_2_A                            (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_2_B                            (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_2                       0x00001914
+#define BNX2_RPM_RC_CNTL_3                             0x00001918
+#define BNX2_RPM_RC_CNTL_3_A                            (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_3_B                            (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_3                       0x0000191c
+#define BNX2_RPM_RC_CNTL_4                             0x00001920
+#define BNX2_RPM_RC_CNTL_4_A                            (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_4_B                            (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_4                       0x00001924
+#define BNX2_RPM_RC_CNTL_5                             0x00001928
+#define BNX2_RPM_RC_CNTL_5_A                            (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_5_B                            (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_5                       0x0000192c
+#define BNX2_RPM_RC_CNTL_6                             0x00001930
+#define BNX2_RPM_RC_CNTL_6_A                            (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_6_B                            (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_6                       0x00001934
+#define BNX2_RPM_RC_CNTL_7                             0x00001938
+#define BNX2_RPM_RC_CNTL_7_A                            (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_7_B                            (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_7                       0x0000193c
+#define BNX2_RPM_RC_CNTL_8                             0x00001940
+#define BNX2_RPM_RC_CNTL_8_A                            (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_8_B                            (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_8                       0x00001944
+#define BNX2_RPM_RC_CNTL_9                             0x00001948
+#define BNX2_RPM_RC_CNTL_9_A                            (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_9_B                            (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_9                       0x0000194c
+#define BNX2_RPM_RC_CNTL_10                            0x00001950
+#define BNX2_RPM_RC_CNTL_10_A                           (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_10_B                           (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_10                      0x00001954
+#define BNX2_RPM_RC_CNTL_11                            0x00001958
+#define BNX2_RPM_RC_CNTL_11_A                           (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_11_B                           (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_11                      0x0000195c
+#define BNX2_RPM_RC_CNTL_12                            0x00001960
+#define BNX2_RPM_RC_CNTL_12_A                           (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_12_B                           (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_12                      0x00001964
+#define BNX2_RPM_RC_CNTL_13                            0x00001968
+#define BNX2_RPM_RC_CNTL_13_A                           (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_13_B                           (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_13                      0x0000196c
+#define BNX2_RPM_RC_CNTL_14                            0x00001970
+#define BNX2_RPM_RC_CNTL_14_A                           (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_14_B                           (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_14                      0x00001974
+#define BNX2_RPM_RC_CNTL_15                            0x00001978
+#define BNX2_RPM_RC_CNTL_15_A                           (0x3ffffL<<0)
+#define BNX2_RPM_RC_CNTL_15_B                           (0xfffL<<19)
+
+#define BNX2_RPM_RC_VALUE_MASK_15                      0x0000197c
+#define BNX2_RPM_RC_CONFIG                             0x00001980
+#define BNX2_RPM_RC_CONFIG_RULE_ENABLE                  (0xffffL<<0)
+#define BNX2_RPM_RC_CONFIG_DEF_CLASS                    (0x7L<<24)
+
+#define BNX2_RPM_DEBUG0                                        0x00001984
+#define BNX2_RPM_DEBUG0_FM_BCNT                                 (0xffffL<<0)
+#define BNX2_RPM_DEBUG0_T_DATA_OFST_VLD                         (1L<<16)
+#define BNX2_RPM_DEBUG0_T_UDP_OFST_VLD                  (1L<<17)
+#define BNX2_RPM_DEBUG0_T_TCP_OFST_VLD                  (1L<<18)
+#define BNX2_RPM_DEBUG0_T_IP_OFST_VLD                   (1L<<19)
+#define BNX2_RPM_DEBUG0_IP_MORE_FRGMT                   (1L<<20)
+#define BNX2_RPM_DEBUG0_T_IP_NO_TCP_UDP_HDR             (1L<<21)
+#define BNX2_RPM_DEBUG0_LLC_SNAP                        (1L<<22)
+#define BNX2_RPM_DEBUG0_FM_STARTED                      (1L<<23)
+#define BNX2_RPM_DEBUG0_DONE                            (1L<<24)
+#define BNX2_RPM_DEBUG0_WAIT_4_DONE                     (1L<<25)
+#define BNX2_RPM_DEBUG0_USE_TPBUF_CKSUM                         (1L<<26)
+#define BNX2_RPM_DEBUG0_RX_NO_PSD_HDR_CKSUM             (1L<<27)
+#define BNX2_RPM_DEBUG0_IGNORE_VLAN                     (1L<<28)
+#define BNX2_RPM_DEBUG0_RP_ENA_ACTIVE                   (1L<<31)
+
+#define BNX2_RPM_DEBUG1                                        0x00001988
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST                      (0xffffL<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_IDLE                         (0L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B6_ALL                 (1L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B2_IPLLC       (2L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B6_IP          (4L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B2_IP          (8L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_IP_START             (16L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_IP                   (32L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_TCP                  (64L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_UDP                  (128L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_AH                   (256L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ESP                  (512L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ESP_PAYLOAD          (1024L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_DATA                         (2048L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ADD_CARRY            (0x2000L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ADD_CARRYOUT                 (0x4000L<<0)
+#define BNX2_RPM_DEBUG1_FSM_CUR_ST_LATCH_RESULT                 (0x8000L<<0)
+#define BNX2_RPM_DEBUG1_HDR_BCNT                        (0x7ffL<<16)
+#define BNX2_RPM_DEBUG1_UNKNOWN_ETYPE_D                         (1L<<28)
+#define BNX2_RPM_DEBUG1_VLAN_REMOVED_D2                         (1L<<29)
+#define BNX2_RPM_DEBUG1_VLAN_REMOVED_D1                         (1L<<30)
+#define BNX2_RPM_DEBUG1_EOF_0XTRA_WD                    (1L<<31)
+
+#define BNX2_RPM_DEBUG2                                        0x0000198c
+#define BNX2_RPM_DEBUG2_CMD_HIT_VEC                     (0xffffL<<0)
+#define BNX2_RPM_DEBUG2_IP_BCNT                                 (0xffL<<16)
+#define BNX2_RPM_DEBUG2_THIS_CMD_M4                     (1L<<24)
+#define BNX2_RPM_DEBUG2_THIS_CMD_M3                     (1L<<25)
+#define BNX2_RPM_DEBUG2_THIS_CMD_M2                     (1L<<26)
+#define BNX2_RPM_DEBUG2_THIS_CMD_M1                     (1L<<27)
+#define BNX2_RPM_DEBUG2_IPIPE_EMPTY                     (1L<<28)
+#define BNX2_RPM_DEBUG2_FM_DISCARD                      (1L<<29)
+#define BNX2_RPM_DEBUG2_LAST_RULE_IN_FM_D2              (1L<<30)
+#define BNX2_RPM_DEBUG2_LAST_RULE_IN_FM_D1              (1L<<31)
+
+#define BNX2_RPM_DEBUG3                                        0x00001990
+#define BNX2_RPM_DEBUG3_AVAIL_MBUF_PTR                  (0x1ffL<<0)
+#define BNX2_RPM_DEBUG3_RDE_RLUPQ_WR_REQ_INT            (1L<<9)
+#define BNX2_RPM_DEBUG3_RDE_RBUF_WR_LAST_INT            (1L<<10)
+#define BNX2_RPM_DEBUG3_RDE_RBUF_WR_REQ_INT             (1L<<11)
+#define BNX2_RPM_DEBUG3_RDE_RBUF_FREE_REQ               (1L<<12)
+#define BNX2_RPM_DEBUG3_RDE_RBUF_ALLOC_REQ              (1L<<13)
+#define BNX2_RPM_DEBUG3_DFSM_MBUF_NOTAVAIL              (1L<<14)
+#define BNX2_RPM_DEBUG3_RBUF_RDE_SOF_DROP               (1L<<15)
+#define BNX2_RPM_DEBUG3_DFIFO_VLD_ENTRY_CT              (0xfL<<16)
+#define BNX2_RPM_DEBUG3_RDE_SRC_FIFO_ALMFULL            (1L<<21)
+#define BNX2_RPM_DEBUG3_DROP_NXT_VLD                    (1L<<22)
+#define BNX2_RPM_DEBUG3_DROP_NXT                        (1L<<23)
+#define BNX2_RPM_DEBUG3_FTQ_FSM                                 (0x3L<<24)
+#define BNX2_RPM_DEBUG3_FTQ_FSM_IDLE                    (0x0L<<24)
+#define BNX2_RPM_DEBUG3_FTQ_FSM_WAIT_ACK                (0x1L<<24)
+#define BNX2_RPM_DEBUG3_FTQ_FSM_WAIT_FREE               (0x2L<<24)
+#define BNX2_RPM_DEBUG3_MBWRITE_FSM                     (0x3L<<26)
+#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_SOF            (0x0L<<26)
+#define BNX2_RPM_DEBUG3_MBWRITE_FSM_GET_MBUF            (0x1L<<26)
+#define BNX2_RPM_DEBUG3_MBWRITE_FSM_DMA_DATA            (0x2L<<26)
+#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_DATA           (0x3L<<26)
+#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_EOF            (0x4L<<26)
+#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_MF_ACK                 (0x5L<<26)
+#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_DROP_NXT_VLD   (0x6L<<26)
+#define BNX2_RPM_DEBUG3_MBWRITE_FSM_DONE                (0x7L<<26)
+#define BNX2_RPM_DEBUG3_MBFREE_FSM                      (1L<<29)
+#define BNX2_RPM_DEBUG3_MBFREE_FSM_IDLE                         (0L<<29)
+#define BNX2_RPM_DEBUG3_MBFREE_FSM_WAIT_ACK             (1L<<29)
+#define BNX2_RPM_DEBUG3_MBALLOC_FSM                     (1L<<30)
+#define BNX2_RPM_DEBUG3_MBALLOC_FSM_ET_MBUF             (0x0L<<30)
+#define BNX2_RPM_DEBUG3_MBALLOC_FSM_IVE_MBUF            (0x1L<<30)
+#define BNX2_RPM_DEBUG3_CCODE_EOF_ERROR                         (1L<<31)
+
+#define BNX2_RPM_DEBUG4                                        0x00001994
+#define BNX2_RPM_DEBUG4_DFSM_MBUF_CLUSTER               (0x1ffffffL<<0)
+#define BNX2_RPM_DEBUG4_DFIFO_CUR_CCODE                         (0x7L<<25)
+#define BNX2_RPM_DEBUG4_MBWRITE_FSM                     (0x7L<<28)
+#define BNX2_RPM_DEBUG4_DFIFO_EMPTY                     (1L<<31)
+
+#define BNX2_RPM_DEBUG5                                        0x00001998
+#define BNX2_RPM_DEBUG5_RDROP_WPTR                      (0x1fL<<0)
+#define BNX2_RPM_DEBUG5_RDROP_ACPI_RPTR                         (0x1fL<<5)
+#define BNX2_RPM_DEBUG5_RDROP_MC_RPTR                   (0x1fL<<10)
+#define BNX2_RPM_DEBUG5_RDROP_RC_RPTR                   (0x1fL<<15)
+#define BNX2_RPM_DEBUG5_RDROP_ACPI_EMPTY                (1L<<20)
+#define BNX2_RPM_DEBUG5_RDROP_MC_EMPTY                  (1L<<21)
+#define BNX2_RPM_DEBUG5_RDROP_AEOF_VEC_AT_RDROP_MC_RPTR         (1L<<22)
+#define BNX2_RPM_DEBUG5_HOLDREG_WOL_DROP_INT            (1L<<23)
+#define BNX2_RPM_DEBUG5_HOLDREG_DISCARD                         (1L<<24)
+#define BNX2_RPM_DEBUG5_HOLDREG_MBUF_NOTAVAIL           (1L<<25)
+#define BNX2_RPM_DEBUG5_HOLDREG_MC_EMPTY                (1L<<26)
+#define BNX2_RPM_DEBUG5_HOLDREG_RC_EMPTY                (1L<<27)
+#define BNX2_RPM_DEBUG5_HOLDREG_FC_EMPTY                (1L<<28)
+#define BNX2_RPM_DEBUG5_HOLDREG_ACPI_EMPTY              (1L<<29)
+#define BNX2_RPM_DEBUG5_HOLDREG_FULL_T                  (1L<<30)
+#define BNX2_RPM_DEBUG5_HOLDREG_RD                      (1L<<31)
+
+#define BNX2_RPM_DEBUG6                                        0x0000199c
+#define BNX2_RPM_DEBUG6_ACPI_VEC                        (0xffffL<<0)
+#define BNX2_RPM_DEBUG6_VEC                             (0xffffL<<16)
+
+#define BNX2_RPM_DEBUG7                                        0x000019a0
+#define BNX2_RPM_DEBUG7_RPM_DBG7_LAST_CRC               (0xffffffffL<<0)
+
+#define BNX2_RPM_DEBUG8                                        0x000019a4
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM                     (0xfL<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_IDLE                (0L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W1_ADDR                 (1L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W2_ADDR                 (2L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W3_ADDR                 (3L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_WAIT_THBUF      (4L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W3_DATA             (5L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W0_ADDR             (6L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W1_ADDR             (7L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W2_ADDR             (8L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W3_ADDR             (9L<<0)
+#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_WAIT_THBUF          (10L<<0)
+#define BNX2_RPM_DEBUG8_COMPARE_AT_W0                   (1L<<4)
+#define BNX2_RPM_DEBUG8_COMPARE_AT_W3_DATA              (1L<<5)
+#define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_WAIT             (1L<<6)
+#define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_W3               (1L<<7)
+#define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_W2               (1L<<8)
+#define BNX2_RPM_DEBUG8_EOF_W_LTEQ6_VLDBYTES            (1L<<9)
+#define BNX2_RPM_DEBUG8_EOF_W_LTEQ4_VLDBYTES            (1L<<10)
+#define BNX2_RPM_DEBUG8_NXT_EOF_W_12_VLDBYTES           (1L<<11)
+#define BNX2_RPM_DEBUG8_EOF_DET                                 (1L<<12)
+#define BNX2_RPM_DEBUG8_SOF_DET                                 (1L<<13)
+#define BNX2_RPM_DEBUG8_WAIT_4_SOF                      (1L<<14)
+#define BNX2_RPM_DEBUG8_ALL_DONE                        (1L<<15)
+#define BNX2_RPM_DEBUG8_THBUF_ADDR                      (0x7fL<<16)
+#define BNX2_RPM_DEBUG8_BYTE_CTR                        (0xffL<<24)
+
+#define BNX2_RPM_DEBUG9                                        0x000019a8
+#define BNX2_RPM_DEBUG9_OUTFIFO_COUNT                   (0x7L<<0)
+#define BNX2_RPM_DEBUG9_RDE_ACPI_RDY                    (1L<<3)
+#define BNX2_RPM_DEBUG9_VLD_RD_ENTRY_CT                         (0x7L<<4)
+#define BNX2_RPM_DEBUG9_OUTFIFO_OVERRUN_OCCURRED        (1L<<28)
+#define BNX2_RPM_DEBUG9_INFIFO_OVERRUN_OCCURRED                 (1L<<29)
+#define BNX2_RPM_DEBUG9_ACPI_MATCH_INT                  (1L<<30)
+#define BNX2_RPM_DEBUG9_ACPI_ENABLE_SYN                         (1L<<31)
+
+#define BNX2_RPM_ACPI_DBG_BUF_W00                      0x000019c0
+#define BNX2_RPM_ACPI_DBG_BUF_W01                      0x000019c4
+#define BNX2_RPM_ACPI_DBG_BUF_W02                      0x000019c8
+#define BNX2_RPM_ACPI_DBG_BUF_W03                      0x000019cc
+#define BNX2_RPM_ACPI_DBG_BUF_W10                      0x000019d0
+#define BNX2_RPM_ACPI_DBG_BUF_W11                      0x000019d4
+#define BNX2_RPM_ACPI_DBG_BUF_W12                      0x000019d8
+#define BNX2_RPM_ACPI_DBG_BUF_W13                      0x000019dc
+#define BNX2_RPM_ACPI_DBG_BUF_W20                      0x000019e0
+#define BNX2_RPM_ACPI_DBG_BUF_W21                      0x000019e4
+#define BNX2_RPM_ACPI_DBG_BUF_W22                      0x000019e8
+#define BNX2_RPM_ACPI_DBG_BUF_W23                      0x000019ec
+#define BNX2_RPM_ACPI_DBG_BUF_W30                      0x000019f0
+#define BNX2_RPM_ACPI_DBG_BUF_W31                      0x000019f4
+#define BNX2_RPM_ACPI_DBG_BUF_W32                      0x000019f8
+#define BNX2_RPM_ACPI_DBG_BUF_W33                      0x000019fc
+
+
+/*
+ *  rbuf_reg definition
+ *  offset: 0x200000
+ */
+#define BNX2_RBUF_COMMAND                              0x00200000
+#define BNX2_RBUF_COMMAND_ENABLED                       (1L<<0)
+#define BNX2_RBUF_COMMAND_FREE_INIT                     (1L<<1)
+#define BNX2_RBUF_COMMAND_RAM_INIT                      (1L<<2)
+#define BNX2_RBUF_COMMAND_OVER_FREE                     (1L<<4)
+#define BNX2_RBUF_COMMAND_ALLOC_REQ                     (1L<<5)
+
+#define BNX2_RBUF_STATUS1                              0x00200004
+#define BNX2_RBUF_STATUS1_FREE_COUNT                    (0x3ffL<<0)
+
+#define BNX2_RBUF_STATUS2                              0x00200008
+#define BNX2_RBUF_STATUS2_FREE_TAIL                     (0x3ffL<<0)
+#define BNX2_RBUF_STATUS2_FREE_HEAD                     (0x3ffL<<16)
+
+#define BNX2_RBUF_CONFIG                               0x0020000c
+#define BNX2_RBUF_CONFIG_XOFF_TRIP                      (0x3ffL<<0)
+#define BNX2_RBUF_CONFIG_XON_TRIP                       (0x3ffL<<16)
+
+#define BNX2_RBUF_FW_BUF_ALLOC                         0x00200010
+#define BNX2_RBUF_FW_BUF_ALLOC_VALUE                    (0x1ffL<<7)
+
+#define BNX2_RBUF_FW_BUF_FREE                          0x00200014
+#define BNX2_RBUF_FW_BUF_FREE_COUNT                     (0x7fL<<0)
+#define BNX2_RBUF_FW_BUF_FREE_TAIL                      (0x1ffL<<7)
+#define BNX2_RBUF_FW_BUF_FREE_HEAD                      (0x1ffL<<16)
+
+#define BNX2_RBUF_FW_BUF_SEL                           0x00200018
+#define BNX2_RBUF_FW_BUF_SEL_COUNT                      (0x7fL<<0)
+#define BNX2_RBUF_FW_BUF_SEL_TAIL                       (0x1ffL<<7)
+#define BNX2_RBUF_FW_BUF_SEL_HEAD                       (0x1ffL<<16)
+
+#define BNX2_RBUF_CONFIG2                              0x0020001c
+#define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP                         (0x3ffL<<0)
+#define BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP                         (0x3ffL<<16)
+
+#define BNX2_RBUF_CONFIG3                              0x00200020
+#define BNX2_RBUF_CONFIG3_CU_DROP_TRIP                  (0x3ffL<<0)
+#define BNX2_RBUF_CONFIG3_CU_KEEP_TRIP                  (0x3ffL<<16)
+
+#define BNX2_RBUF_PKT_DATA                             0x00208000
+#define BNX2_RBUF_CLIST_DATA                           0x00210000
+#define BNX2_RBUF_BUF_DATA                             0x00220000
+
+
+/*
+ *  rv2p_reg definition
+ *  offset: 0x2800
+ */
+#define BNX2_RV2P_COMMAND                              0x00002800
+#define BNX2_RV2P_COMMAND_ENABLED                       (1L<<0)
+#define BNX2_RV2P_COMMAND_PROC1_INTRPT                  (1L<<1)
+#define BNX2_RV2P_COMMAND_PROC2_INTRPT                  (1L<<2)
+#define BNX2_RV2P_COMMAND_ABORT0                        (1L<<4)
+#define BNX2_RV2P_COMMAND_ABORT1                        (1L<<5)
+#define BNX2_RV2P_COMMAND_ABORT2                        (1L<<6)
+#define BNX2_RV2P_COMMAND_ABORT3                        (1L<<7)
+#define BNX2_RV2P_COMMAND_ABORT4                        (1L<<8)
+#define BNX2_RV2P_COMMAND_ABORT5                        (1L<<9)
+#define BNX2_RV2P_COMMAND_PROC1_RESET                   (1L<<16)
+#define BNX2_RV2P_COMMAND_PROC2_RESET                   (1L<<17)
+#define BNX2_RV2P_COMMAND_CTXIF_RESET                   (1L<<18)
+
+#define BNX2_RV2P_STATUS                               0x00002804
+#define BNX2_RV2P_STATUS_ALWAYS_0                       (1L<<0)
+#define BNX2_RV2P_STATUS_RV2P_GEN_STAT0_CNT             (1L<<8)
+#define BNX2_RV2P_STATUS_RV2P_GEN_STAT1_CNT             (1L<<9)
+#define BNX2_RV2P_STATUS_RV2P_GEN_STAT2_CNT             (1L<<10)
+#define BNX2_RV2P_STATUS_RV2P_GEN_STAT3_CNT             (1L<<11)
+#define BNX2_RV2P_STATUS_RV2P_GEN_STAT4_CNT             (1L<<12)
+#define BNX2_RV2P_STATUS_RV2P_GEN_STAT5_CNT             (1L<<13)
+
+#define BNX2_RV2P_CONFIG                               0x00002808
+#define BNX2_RV2P_CONFIG_STALL_PROC1                    (1L<<0)
+#define BNX2_RV2P_CONFIG_STALL_PROC2                    (1L<<1)
+#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT0          (1L<<8)
+#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT1          (1L<<9)
+#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT2          (1L<<10)
+#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT3          (1L<<11)
+#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT4          (1L<<12)
+#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT5          (1L<<13)
+#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT0          (1L<<16)
+#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT1          (1L<<17)
+#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT2          (1L<<18)
+#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT3          (1L<<19)
+#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT4          (1L<<20)
+#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT5          (1L<<21)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE                      (0xfL<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_256                  (0L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_512                  (1L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_1K                   (2L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_2K                   (3L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_4K                   (4L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_8K                   (5L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_16K                  (6L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_32K                  (7L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_64K                  (8L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_128K                         (9L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_256K                         (10L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_512K                         (11L<<24)
+#define BNX2_RV2P_CONFIG_PAGE_SIZE_1M                   (12L<<24)
+
+#define BNX2_RV2P_GEN_BFR_ADDR_0                       0x00002810
+#define BNX2_RV2P_GEN_BFR_ADDR_0_VALUE                  (0xffffL<<16)
+
+#define BNX2_RV2P_GEN_BFR_ADDR_1                       0x00002814
+#define BNX2_RV2P_GEN_BFR_ADDR_1_VALUE                  (0xffffL<<16)
+
+#define BNX2_RV2P_GEN_BFR_ADDR_2                       0x00002818
+#define BNX2_RV2P_GEN_BFR_ADDR_2_VALUE                  (0xffffL<<16)
+
+#define BNX2_RV2P_GEN_BFR_ADDR_3                       0x0000281c
+#define BNX2_RV2P_GEN_BFR_ADDR_3_VALUE                  (0xffffL<<16)
+
+#define BNX2_RV2P_INSTR_HIGH                           0x00002830
+#define BNX2_RV2P_INSTR_HIGH_HIGH                       (0x1fL<<0)
+
+#define BNX2_RV2P_INSTR_LOW                            0x00002834
+#define BNX2_RV2P_PROC1_ADDR_CMD                       0x00002838
+#define BNX2_RV2P_PROC1_ADDR_CMD_ADD                    (0x3ffL<<0)
+#define BNX2_RV2P_PROC1_ADDR_CMD_RDWR                   (1L<<31)
+
+#define BNX2_RV2P_PROC2_ADDR_CMD                       0x0000283c
+#define BNX2_RV2P_PROC2_ADDR_CMD_ADD                    (0x3ffL<<0)
+#define BNX2_RV2P_PROC2_ADDR_CMD_RDWR                   (1L<<31)
+
+#define BNX2_RV2P_PROC1_GRC_DEBUG                      0x00002840
+#define BNX2_RV2P_PROC2_GRC_DEBUG                      0x00002844
+#define BNX2_RV2P_GRC_PROC_DEBUG                       0x00002848
+#define BNX2_RV2P_DEBUG_VECT_PEEK                      0x0000284c
+#define BNX2_RV2P_DEBUG_VECT_PEEK_1_VALUE               (0x7ffL<<0)
+#define BNX2_RV2P_DEBUG_VECT_PEEK_1_PEEK_EN             (1L<<11)
+#define BNX2_RV2P_DEBUG_VECT_PEEK_1_SEL                         (0xfL<<12)
+#define BNX2_RV2P_DEBUG_VECT_PEEK_2_VALUE               (0x7ffL<<16)
+#define BNX2_RV2P_DEBUG_VECT_PEEK_2_PEEK_EN             (1L<<27)
+#define BNX2_RV2P_DEBUG_VECT_PEEK_2_SEL                         (0xfL<<28)
+
+#define BNX2_RV2P_PFTQ_DATA                            0x00002b40
+#define BNX2_RV2P_PFTQ_CMD                             0x00002b78
+#define BNX2_RV2P_PFTQ_CMD_OFFSET                       (0x3ffL<<0)
+#define BNX2_RV2P_PFTQ_CMD_WR_TOP                       (1L<<10)
+#define BNX2_RV2P_PFTQ_CMD_WR_TOP_0                     (0L<<10)
+#define BNX2_RV2P_PFTQ_CMD_WR_TOP_1                     (1L<<10)
+#define BNX2_RV2P_PFTQ_CMD_SFT_RESET                    (1L<<25)
+#define BNX2_RV2P_PFTQ_CMD_RD_DATA                      (1L<<26)
+#define BNX2_RV2P_PFTQ_CMD_ADD_INTERVEN                         (1L<<27)
+#define BNX2_RV2P_PFTQ_CMD_ADD_DATA                     (1L<<28)
+#define BNX2_RV2P_PFTQ_CMD_INTERVENE_CLR                (1L<<29)
+#define BNX2_RV2P_PFTQ_CMD_POP                          (1L<<30)
+#define BNX2_RV2P_PFTQ_CMD_BUSY                                 (1L<<31)
+
+#define BNX2_RV2P_PFTQ_CTL                             0x00002b7c
+#define BNX2_RV2P_PFTQ_CTL_INTERVENE                    (1L<<0)
+#define BNX2_RV2P_PFTQ_CTL_OVERFLOW                     (1L<<1)
+#define BNX2_RV2P_PFTQ_CTL_FORCE_INTERVENE              (1L<<2)
+#define BNX2_RV2P_PFTQ_CTL_MAX_DEPTH                    (0x3ffL<<12)
+#define BNX2_RV2P_PFTQ_CTL_CUR_DEPTH                    (0x3ffL<<22)
+
+#define BNX2_RV2P_TFTQ_DATA                            0x00002b80
+#define BNX2_RV2P_TFTQ_CMD                             0x00002bb8
+#define BNX2_RV2P_TFTQ_CMD_OFFSET                       (0x3ffL<<0)
+#define BNX2_RV2P_TFTQ_CMD_WR_TOP                       (1L<<10)
+#define BNX2_RV2P_TFTQ_CMD_WR_TOP_0                     (0L<<10)
+#define BNX2_RV2P_TFTQ_CMD_WR_TOP_1                     (1L<<10)
+#define BNX2_RV2P_TFTQ_CMD_SFT_RESET                    (1L<<25)
+#define BNX2_RV2P_TFTQ_CMD_RD_DATA                      (1L<<26)
+#define BNX2_RV2P_TFTQ_CMD_ADD_INTERVEN                         (1L<<27)
+#define BNX2_RV2P_TFTQ_CMD_ADD_DATA                     (1L<<28)
+#define BNX2_RV2P_TFTQ_CMD_INTERVENE_CLR                (1L<<29)
+#define BNX2_RV2P_TFTQ_CMD_POP                          (1L<<30)
+#define BNX2_RV2P_TFTQ_CMD_BUSY                                 (1L<<31)
+
+#define BNX2_RV2P_TFTQ_CTL                             0x00002bbc
+#define BNX2_RV2P_TFTQ_CTL_INTERVENE                    (1L<<0)
+#define BNX2_RV2P_TFTQ_CTL_OVERFLOW                     (1L<<1)
+#define BNX2_RV2P_TFTQ_CTL_FORCE_INTERVENE              (1L<<2)
+#define BNX2_RV2P_TFTQ_CTL_MAX_DEPTH                    (0x3ffL<<12)
+#define BNX2_RV2P_TFTQ_CTL_CUR_DEPTH                    (0x3ffL<<22)
+
+#define BNX2_RV2P_MFTQ_DATA                            0x00002bc0
+#define BNX2_RV2P_MFTQ_CMD                             0x00002bf8
+#define BNX2_RV2P_MFTQ_CMD_OFFSET                       (0x3ffL<<0)
+#define BNX2_RV2P_MFTQ_CMD_WR_TOP                       (1L<<10)
+#define BNX2_RV2P_MFTQ_CMD_WR_TOP_0                     (0L<<10)
+#define BNX2_RV2P_MFTQ_CMD_WR_TOP_1                     (1L<<10)
+#define BNX2_RV2P_MFTQ_CMD_SFT_RESET                    (1L<<25)
+#define BNX2_RV2P_MFTQ_CMD_RD_DATA                      (1L<<26)
+#define BNX2_RV2P_MFTQ_CMD_ADD_INTERVEN                         (1L<<27)
+#define BNX2_RV2P_MFTQ_CMD_ADD_DATA                     (1L<<28)
+#define BNX2_RV2P_MFTQ_CMD_INTERVENE_CLR                (1L<<29)
+#define BNX2_RV2P_MFTQ_CMD_POP                          (1L<<30)
+#define BNX2_RV2P_MFTQ_CMD_BUSY                                 (1L<<31)
+
+#define BNX2_RV2P_MFTQ_CTL                             0x00002bfc
+#define BNX2_RV2P_MFTQ_CTL_INTERVENE                    (1L<<0)
+#define BNX2_RV2P_MFTQ_CTL_OVERFLOW                     (1L<<1)
+#define BNX2_RV2P_MFTQ_CTL_FORCE_INTERVENE              (1L<<2)
+#define BNX2_RV2P_MFTQ_CTL_MAX_DEPTH                    (0x3ffL<<12)
+#define BNX2_RV2P_MFTQ_CTL_CUR_DEPTH                    (0x3ffL<<22)
+
+
+
+/*
+ *  mq_reg definition
+ *  offset: 0x3c00
+ */
+#define BNX2_MQ_COMMAND                                        0x00003c00
+#define BNX2_MQ_COMMAND_ENABLED                                 (1L<<0)
+#define BNX2_MQ_COMMAND_OVERFLOW                        (1L<<4)
+#define BNX2_MQ_COMMAND_WR_ERROR                        (1L<<5)
+#define BNX2_MQ_COMMAND_RD_ERROR                        (1L<<6)
+
+#define BNX2_MQ_STATUS                                 0x00003c04
+#define BNX2_MQ_STATUS_CTX_ACCESS_STAT                  (1L<<16)
+#define BNX2_MQ_STATUS_CTX_ACCESS64_STAT                (1L<<17)
+#define BNX2_MQ_STATUS_PCI_STALL_STAT                   (1L<<18)
+
+#define BNX2_MQ_CONFIG                                 0x00003c08
+#define BNX2_MQ_CONFIG_TX_HIGH_PRI                      (1L<<0)
+#define BNX2_MQ_CONFIG_HALT_DIS                                 (1L<<1)
+#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE                         (0x7L<<4)
+#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256             (0L<<4)
+#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_512             (1L<<4)
+#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_1K              (2L<<4)
+#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_2K              (3L<<4)
+#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_4K              (4L<<4)
+#define BNX2_MQ_CONFIG_MAX_DEPTH                        (0x7fL<<8)
+#define BNX2_MQ_CONFIG_CUR_DEPTH                        (0x7fL<<20)
+
+#define BNX2_MQ_ENQUEUE1                               0x00003c0c
+#define BNX2_MQ_ENQUEUE1_OFFSET                                 (0x3fL<<2)
+#define BNX2_MQ_ENQUEUE1_CID                            (0x3fffL<<8)
+#define BNX2_MQ_ENQUEUE1_BYTE_MASK                      (0xfL<<24)
+#define BNX2_MQ_ENQUEUE1_KNL_MODE                       (1L<<28)
+
+#define BNX2_MQ_ENQUEUE2                               0x00003c10
+#define BNX2_MQ_BAD_WR_ADDR                            0x00003c14
+#define BNX2_MQ_BAD_RD_ADDR                            0x00003c18
+#define BNX2_MQ_KNL_BYP_WIND_START                     0x00003c1c
+#define BNX2_MQ_KNL_BYP_WIND_START_VALUE                (0xfffffL<<12)
+
+#define BNX2_MQ_KNL_WIND_END                           0x00003c20
+#define BNX2_MQ_KNL_WIND_END_VALUE                      (0xffffffL<<8)
+
+#define BNX2_MQ_KNL_WRITE_MASK1                                0x00003c24
+#define BNX2_MQ_KNL_TX_MASK1                           0x00003c28
+#define BNX2_MQ_KNL_CMD_MASK1                          0x00003c2c
+#define BNX2_MQ_KNL_COND_ENQUEUE_MASK1                 0x00003c30
+#define BNX2_MQ_KNL_RX_V2P_MASK1                       0x00003c34
+#define BNX2_MQ_KNL_WRITE_MASK2                                0x00003c38
+#define BNX2_MQ_KNL_TX_MASK2                           0x00003c3c
+#define BNX2_MQ_KNL_CMD_MASK2                          0x00003c40
+#define BNX2_MQ_KNL_COND_ENQUEUE_MASK2                 0x00003c44
+#define BNX2_MQ_KNL_RX_V2P_MASK2                       0x00003c48
+#define BNX2_MQ_KNL_BYP_WRITE_MASK1                    0x00003c4c
+#define BNX2_MQ_KNL_BYP_TX_MASK1                       0x00003c50
+#define BNX2_MQ_KNL_BYP_CMD_MASK1                      0x00003c54
+#define BNX2_MQ_KNL_BYP_COND_ENQUEUE_MASK1             0x00003c58
+#define BNX2_MQ_KNL_BYP_RX_V2P_MASK1                   0x00003c5c
+#define BNX2_MQ_KNL_BYP_WRITE_MASK2                    0x00003c60
+#define BNX2_MQ_KNL_BYP_TX_MASK2                       0x00003c64
+#define BNX2_MQ_KNL_BYP_CMD_MASK2                      0x00003c68
+#define BNX2_MQ_KNL_BYP_COND_ENQUEUE_MASK2             0x00003c6c
+#define BNX2_MQ_KNL_BYP_RX_V2P_MASK2                   0x00003c70
+#define BNX2_MQ_MEM_WR_ADDR                            0x00003c74
+#define BNX2_MQ_MEM_WR_ADDR_VALUE                       (0x3fL<<0)
+
+#define BNX2_MQ_MEM_WR_DATA0                           0x00003c78
+#define BNX2_MQ_MEM_WR_DATA0_VALUE                      (0xffffffffL<<0)
+
+#define BNX2_MQ_MEM_WR_DATA1                           0x00003c7c
+#define BNX2_MQ_MEM_WR_DATA1_VALUE                      (0xffffffffL<<0)
+
+#define BNX2_MQ_MEM_WR_DATA2                           0x00003c80
+#define BNX2_MQ_MEM_WR_DATA2_VALUE                      (0x3fffffffL<<0)
+
+#define BNX2_MQ_MEM_RD_ADDR                            0x00003c84
+#define BNX2_MQ_MEM_RD_ADDR_VALUE                       (0x3fL<<0)
+
+#define BNX2_MQ_MEM_RD_DATA0                           0x00003c88
+#define BNX2_MQ_MEM_RD_DATA0_VALUE                      (0xffffffffL<<0)
+
+#define BNX2_MQ_MEM_RD_DATA1                           0x00003c8c
+#define BNX2_MQ_MEM_RD_DATA1_VALUE                      (0xffffffffL<<0)
+
+#define BNX2_MQ_MEM_RD_DATA2                           0x00003c90
+#define BNX2_MQ_MEM_RD_DATA2_VALUE                      (0x3fffffffL<<0)
+
+
+
+/*
+ *  tbdr_reg definition
+ *  offset: 0x5000
+ */
+#define BNX2_TBDR_COMMAND                              0x00005000
+#define BNX2_TBDR_COMMAND_ENABLE                        (1L<<0)
+#define BNX2_TBDR_COMMAND_SOFT_RST                      (1L<<1)
+#define BNX2_TBDR_COMMAND_MSTR_ABORT                    (1L<<4)
+
+#define BNX2_TBDR_STATUS                               0x00005004
+#define BNX2_TBDR_STATUS_DMA_WAIT                       (1L<<0)
+#define BNX2_TBDR_STATUS_FTQ_WAIT                       (1L<<1)
+#define BNX2_TBDR_STATUS_FIFO_OVERFLOW                  (1L<<2)
+#define BNX2_TBDR_STATUS_FIFO_UNDERFLOW                         (1L<<3)
+#define BNX2_TBDR_STATUS_SEARCHMISS_ERROR               (1L<<4)
+#define BNX2_TBDR_STATUS_FTQ_ENTRY_CNT                  (1L<<5)
+#define BNX2_TBDR_STATUS_BURST_CNT                      (1L<<6)
+
+#define BNX2_TBDR_CONFIG                               0x00005008
+#define BNX2_TBDR_CONFIG_MAX_BDS                        (0xffL<<0)
+#define BNX2_TBDR_CONFIG_SWAP_MODE                      (1L<<8)
+#define BNX2_TBDR_CONFIG_PRIORITY                       (1L<<9)
+#define BNX2_TBDR_CONFIG_CACHE_NEXT_PAGE_PTRS           (1L<<10)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE                      (0xfL<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_256                  (0L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_512                  (1L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_1K                   (2L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_2K                   (3L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_4K                   (4L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_8K                   (5L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_16K                  (6L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_32K                  (7L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_64K                  (8L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_128K                         (9L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_256K                         (10L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_512K                         (11L<<24)
+#define BNX2_TBDR_CONFIG_PAGE_SIZE_1M                   (12L<<24)
+
+#define BNX2_TBDR_DEBUG_VECT_PEEK                      0x0000500c
+#define BNX2_TBDR_DEBUG_VECT_PEEK_1_VALUE               (0x7ffL<<0)
+#define BNX2_TBDR_DEBUG_VECT_PEEK_1_PEEK_EN             (1L<<11)
+#define BNX2_TBDR_DEBUG_VECT_PEEK_1_SEL                         (0xfL<<12)
+#define BNX2_TBDR_DEBUG_VECT_PEEK_2_VALUE               (0x7ffL<<16)
+#define BNX2_TBDR_DEBUG_VECT_PEEK_2_PEEK_EN             (1L<<27)
+#define BNX2_TBDR_DEBUG_VECT_PEEK_2_SEL                         (0xfL<<28)
+
+#define BNX2_TBDR_FTQ_DATA                             0x000053c0
+#define BNX2_TBDR_FTQ_CMD                              0x000053f8
+#define BNX2_TBDR_FTQ_CMD_OFFSET                        (0x3ffL<<0)
+#define BNX2_TBDR_FTQ_CMD_WR_TOP                        (1L<<10)
+#define BNX2_TBDR_FTQ_CMD_WR_TOP_0                      (0L<<10)
+#define BNX2_TBDR_FTQ_CMD_WR_TOP_1                      (1L<<10)
+#define BNX2_TBDR_FTQ_CMD_SFT_RESET                     (1L<<25)
+#define BNX2_TBDR_FTQ_CMD_RD_DATA                       (1L<<26)
+#define BNX2_TBDR_FTQ_CMD_ADD_INTERVEN                  (1L<<27)
+#define BNX2_TBDR_FTQ_CMD_ADD_DATA                      (1L<<28)
+#define BNX2_TBDR_FTQ_CMD_INTERVENE_CLR                         (1L<<29)
+#define BNX2_TBDR_FTQ_CMD_POP                           (1L<<30)
+#define BNX2_TBDR_FTQ_CMD_BUSY                          (1L<<31)
+
+#define BNX2_TBDR_FTQ_CTL                              0x000053fc
+#define BNX2_TBDR_FTQ_CTL_INTERVENE                     (1L<<0)
+#define BNX2_TBDR_FTQ_CTL_OVERFLOW                      (1L<<1)
+#define BNX2_TBDR_FTQ_CTL_FORCE_INTERVENE               (1L<<2)
+#define BNX2_TBDR_FTQ_CTL_MAX_DEPTH                     (0x3ffL<<12)
+#define BNX2_TBDR_FTQ_CTL_CUR_DEPTH                     (0x3ffL<<22)
+
+
+
+/*
+ *  tdma_reg definition
+ *  offset: 0x5c00
+ */
+#define BNX2_TDMA_COMMAND                              0x00005c00
+#define BNX2_TDMA_COMMAND_ENABLED                       (1L<<0)
+#define BNX2_TDMA_COMMAND_MASTER_ABORT                  (1L<<4)
+#define BNX2_TDMA_COMMAND_BAD_L2_LENGTH_ABORT           (1L<<7)
+
+#define BNX2_TDMA_STATUS                               0x00005c04
+#define BNX2_TDMA_STATUS_DMA_WAIT                       (1L<<0)
+#define BNX2_TDMA_STATUS_PAYLOAD_WAIT                   (1L<<1)
+#define BNX2_TDMA_STATUS_PATCH_FTQ_WAIT                         (1L<<2)
+#define BNX2_TDMA_STATUS_LOCK_WAIT                      (1L<<3)
+#define BNX2_TDMA_STATUS_FTQ_ENTRY_CNT                  (1L<<16)
+#define BNX2_TDMA_STATUS_BURST_CNT                      (1L<<17)
+
+#define BNX2_TDMA_CONFIG                               0x00005c08
+#define BNX2_TDMA_CONFIG_ONE_DMA                        (1L<<0)
+#define BNX2_TDMA_CONFIG_ONE_RECORD                     (1L<<1)
+#define BNX2_TDMA_CONFIG_LIMIT_SZ                       (0xfL<<4)
+#define BNX2_TDMA_CONFIG_LIMIT_SZ_64                    (0L<<4)
+#define BNX2_TDMA_CONFIG_LIMIT_SZ_128                   (0x4L<<4)
+#define BNX2_TDMA_CONFIG_LIMIT_SZ_256                   (0x6L<<4)
+#define BNX2_TDMA_CONFIG_LIMIT_SZ_512                   (0x8L<<4)
+#define BNX2_TDMA_CONFIG_LINE_SZ                        (0xfL<<8)
+#define BNX2_TDMA_CONFIG_LINE_SZ_64                     (0L<<8)
+#define BNX2_TDMA_CONFIG_LINE_SZ_128                    (4L<<8)
+#define BNX2_TDMA_CONFIG_LINE_SZ_256                    (6L<<8)
+#define BNX2_TDMA_CONFIG_LINE_SZ_512                    (8L<<8)
+#define BNX2_TDMA_CONFIG_ALIGN_ENA                      (1L<<15)
+#define BNX2_TDMA_CONFIG_CHK_L2_BD                      (1L<<16)
+#define BNX2_TDMA_CONFIG_FIFO_CMP                       (0xfL<<20)
+
+#define BNX2_TDMA_PAYLOAD_PROD                         0x00005c0c
+#define BNX2_TDMA_PAYLOAD_PROD_VALUE                    (0x1fffL<<3)
+
+#define BNX2_TDMA_DBG_WATCHDOG                         0x00005c10
+#define BNX2_TDMA_DBG_TRIGGER                          0x00005c14
+#define BNX2_TDMA_DMAD_FSM                             0x00005c80
+#define BNX2_TDMA_DMAD_FSM_BD_INVLD                     (1L<<0)
+#define BNX2_TDMA_DMAD_FSM_PUSH                                 (0xfL<<4)
+#define BNX2_TDMA_DMAD_FSM_ARB_TBDC                     (0x3L<<8)
+#define BNX2_TDMA_DMAD_FSM_ARB_CTX                      (1L<<12)
+#define BNX2_TDMA_DMAD_FSM_DR_INTF                      (1L<<16)
+#define BNX2_TDMA_DMAD_FSM_DMAD                                 (0x7L<<20)
+#define BNX2_TDMA_DMAD_FSM_BD                           (0xfL<<24)
+
+#define BNX2_TDMA_DMAD_STATUS                          0x00005c84
+#define BNX2_TDMA_DMAD_STATUS_RHOLD_PUSH_ENTRY          (0x3L<<0)
+#define BNX2_TDMA_DMAD_STATUS_RHOLD_DMAD_ENTRY          (0x3L<<4)
+#define BNX2_TDMA_DMAD_STATUS_RHOLD_BD_ENTRY            (0x3L<<8)
+#define BNX2_TDMA_DMAD_STATUS_IFTQ_ENUM                         (0xfL<<12)
+
+#define BNX2_TDMA_DR_INTF_FSM                          0x00005c88
+#define BNX2_TDMA_DR_INTF_FSM_L2_COMP                   (0x3L<<0)
+#define BNX2_TDMA_DR_INTF_FSM_TPATQ                     (0x7L<<4)
+#define BNX2_TDMA_DR_INTF_FSM_TPBUF                     (0x3L<<8)
+#define BNX2_TDMA_DR_INTF_FSM_DR_BUF                    (0x7L<<12)
+#define BNX2_TDMA_DR_INTF_FSM_DMAD                      (0x7L<<16)
+
+#define BNX2_TDMA_DR_INTF_STATUS                       0x00005c8c
+#define BNX2_TDMA_DR_INTF_STATUS_HOLE_PHASE             (0x7L<<0)
+#define BNX2_TDMA_DR_INTF_STATUS_DATA_AVAIL             (0x3L<<4)
+#define BNX2_TDMA_DR_INTF_STATUS_SHIFT_ADDR             (0x7L<<8)
+#define BNX2_TDMA_DR_INTF_STATUS_NXT_PNTR               (0xfL<<12)
+#define BNX2_TDMA_DR_INTF_STATUS_BYTE_COUNT             (0x7L<<16)
+
+#define BNX2_TDMA_FTQ_DATA                             0x00005fc0
+#define BNX2_TDMA_FTQ_CMD                              0x00005ff8
+#define BNX2_TDMA_FTQ_CMD_OFFSET                        (0x3ffL<<0)
+#define BNX2_TDMA_FTQ_CMD_WR_TOP                        (1L<<10)
+#define BNX2_TDMA_FTQ_CMD_WR_TOP_0                      (0L<<10)
+#define BNX2_TDMA_FTQ_CMD_WR_TOP_1                      (1L<<10)
+#define BNX2_TDMA_FTQ_CMD_SFT_RESET                     (1L<<25)
+#define BNX2_TDMA_FTQ_CMD_RD_DATA                       (1L<<26)
+#define BNX2_TDMA_FTQ_CMD_ADD_INTERVEN                  (1L<<27)
+#define BNX2_TDMA_FTQ_CMD_ADD_DATA                      (1L<<28)
+#define BNX2_TDMA_FTQ_CMD_INTERVENE_CLR                         (1L<<29)
+#define BNX2_TDMA_FTQ_CMD_POP                           (1L<<30)
+#define BNX2_TDMA_FTQ_CMD_BUSY                          (1L<<31)
+
+#define BNX2_TDMA_FTQ_CTL                              0x00005ffc
+#define BNX2_TDMA_FTQ_CTL_INTERVENE                     (1L<<0)
+#define BNX2_TDMA_FTQ_CTL_OVERFLOW                      (1L<<1)
+#define BNX2_TDMA_FTQ_CTL_FORCE_INTERVENE               (1L<<2)
+#define BNX2_TDMA_FTQ_CTL_MAX_DEPTH                     (0x3ffL<<12)
+#define BNX2_TDMA_FTQ_CTL_CUR_DEPTH                     (0x3ffL<<22)
+
+
+
+/*
+ *  hc_reg definition
+ *  offset: 0x6800
+ */
+#define BNX2_HC_COMMAND                                        0x00006800
+#define BNX2_HC_COMMAND_ENABLE                          (1L<<0)
+#define BNX2_HC_COMMAND_SKIP_ABORT                      (1L<<4)
+#define BNX2_HC_COMMAND_COAL_NOW                        (1L<<16)
+#define BNX2_HC_COMMAND_COAL_NOW_WO_INT                         (1L<<17)
+#define BNX2_HC_COMMAND_STATS_NOW                       (1L<<18)
+#define BNX2_HC_COMMAND_FORCE_INT                       (0x3L<<19)
+#define BNX2_HC_COMMAND_FORCE_INT_NULL                  (0L<<19)
+#define BNX2_HC_COMMAND_FORCE_INT_HIGH                  (1L<<19)
+#define BNX2_HC_COMMAND_FORCE_INT_LOW                   (2L<<19)
+#define BNX2_HC_COMMAND_FORCE_INT_FREE                  (3L<<19)
+#define BNX2_HC_COMMAND_CLR_STAT_NOW                    (1L<<21)
+
+#define BNX2_HC_STATUS                                 0x00006804
+#define BNX2_HC_STATUS_MASTER_ABORT                     (1L<<0)
+#define BNX2_HC_STATUS_PARITY_ERROR_STATE               (1L<<1)
+#define BNX2_HC_STATUS_PCI_CLK_CNT_STAT                         (1L<<16)
+#define BNX2_HC_STATUS_CORE_CLK_CNT_STAT                (1L<<17)
+#define BNX2_HC_STATUS_NUM_STATUS_BLOCKS_STAT           (1L<<18)
+#define BNX2_HC_STATUS_NUM_INT_GEN_STAT                         (1L<<19)
+#define BNX2_HC_STATUS_NUM_INT_MBOX_WR_STAT             (1L<<20)
+#define BNX2_HC_STATUS_CORE_CLKS_TO_HW_INTACK_STAT      (1L<<23)
+#define BNX2_HC_STATUS_CORE_CLKS_TO_SW_INTACK_STAT      (1L<<24)
+#define BNX2_HC_STATUS_CORE_CLKS_DURING_SW_INTACK_STAT  (1L<<25)
+
+#define BNX2_HC_CONFIG                                 0x00006808
+#define BNX2_HC_CONFIG_COLLECT_STATS                    (1L<<0)
+#define BNX2_HC_CONFIG_RX_TMR_MODE                      (1L<<1)
+#define BNX2_HC_CONFIG_TX_TMR_MODE                      (1L<<2)
+#define BNX2_HC_CONFIG_COM_TMR_MODE                     (1L<<3)
+#define BNX2_HC_CONFIG_CMD_TMR_MODE                     (1L<<4)
+#define BNX2_HC_CONFIG_STATISTIC_PRIORITY               (1L<<5)
+#define BNX2_HC_CONFIG_STATUS_PRIORITY                  (1L<<6)
+#define BNX2_HC_CONFIG_STAT_MEM_ADDR                    (0xffL<<8)
+
+#define BNX2_HC_ATTN_BITS_ENABLE                       0x0000680c
+#define BNX2_HC_STATUS_ADDR_L                          0x00006810
+#define BNX2_HC_STATUS_ADDR_H                          0x00006814
+#define BNX2_HC_STATISTICS_ADDR_L                      0x00006818
+#define BNX2_HC_STATISTICS_ADDR_H                      0x0000681c
+#define BNX2_HC_TX_QUICK_CONS_TRIP                     0x00006820
+#define BNX2_HC_TX_QUICK_CONS_TRIP_VALUE                (0xffL<<0)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_INT                  (0xffL<<16)
+
+#define BNX2_HC_COMP_PROD_TRIP                         0x00006824
+#define BNX2_HC_COMP_PROD_TRIP_VALUE                    (0xffL<<0)
+#define BNX2_HC_COMP_PROD_TRIP_INT                      (0xffL<<16)
+
+#define BNX2_HC_RX_QUICK_CONS_TRIP                     0x00006828
+#define BNX2_HC_RX_QUICK_CONS_TRIP_VALUE                (0xffL<<0)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_INT                  (0xffL<<16)
+
+#define BNX2_HC_RX_TICKS                               0x0000682c
+#define BNX2_HC_RX_TICKS_VALUE                          (0x3ffL<<0)
+#define BNX2_HC_RX_TICKS_INT                            (0x3ffL<<16)
+
+#define BNX2_HC_TX_TICKS                               0x00006830
+#define BNX2_HC_TX_TICKS_VALUE                          (0x3ffL<<0)
+#define BNX2_HC_TX_TICKS_INT                            (0x3ffL<<16)
+
+#define BNX2_HC_COM_TICKS                              0x00006834
+#define BNX2_HC_COM_TICKS_VALUE                                 (0x3ffL<<0)
+#define BNX2_HC_COM_TICKS_INT                           (0x3ffL<<16)
+
+#define BNX2_HC_CMD_TICKS                              0x00006838
+#define BNX2_HC_CMD_TICKS_VALUE                                 (0x3ffL<<0)
+#define BNX2_HC_CMD_TICKS_INT                           (0x3ffL<<16)
+
+#define BNX2_HC_PERIODIC_TICKS                         0x0000683c
+#define BNX2_HC_PERIODIC_TICKS_HC_PERIODIC_TICKS        (0xffffL<<0)
+
+#define BNX2_HC_STAT_COLLECT_TICKS                     0x00006840
+#define BNX2_HC_STAT_COLLECT_TICKS_HC_STAT_COLL_TICKS   (0xffL<<4)
+
+#define BNX2_HC_STATS_TICKS                            0x00006844
+#define BNX2_HC_STATS_TICKS_HC_STAT_TICKS               (0xffffL<<8)
+
+#define BNX2_HC_STAT_MEM_DATA                          0x0000684c
+#define BNX2_HC_STAT_GEN_SEL_0                         0x00006850
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0                (0x7fL<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT0      (0L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT1      (1L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT2      (2L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT3      (3L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT4      (4L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT5      (5L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT6      (6L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT7      (7L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT8      (8L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT9      (9L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT10     (10L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT11     (11L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT0      (12L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT1      (13L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT2      (14L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT3      (15L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT4      (16L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT5      (17L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT6      (18L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT7      (19L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT0      (20L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT1      (21L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT2      (22L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT3      (23L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT4      (24L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT5      (25L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT6      (26L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT7      (27L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT8      (28L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT9      (29L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT10     (30L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT11     (31L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT0     (32L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT1     (33L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT2     (34L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT3     (35L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT0       (36L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT1       (37L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT2       (38L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT3       (39L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT4       (40L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT5       (41L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT6       (42L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT7       (43L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT0      (44L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT1      (45L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT2      (46L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT3      (47L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT4      (48L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT5      (49L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT6      (50L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT7      (51L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_PCI_CLK_CNT    (52L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CORE_CLK_CNT   (53L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS   (54L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN         (55L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR     (56L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK      (59L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK      (60L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK  (61L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCH_CMD_CNT   (62L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCH_SLOT_CNT  (63L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSCH_CMD_CNT   (64L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSCH_SLOT_CNT  (65L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT        (66L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT         (67L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT        (68L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT       (69L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT       (70L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT       (71L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT        (72L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT        (73L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT        (74L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT         (75L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT        (76L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT        (77L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT         (78L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  (79L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  (80L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT        (81L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT        (82L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT         (83L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT         (84L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_READ_TRANSFERS_CNT        (85L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_READ_DELAY_PCI_CLKS_CNT   (86L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_TRANSFERS_CNT    (87L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_DELAY_PCI_CLKS_CNT       (88L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_RETRY_AFTER_DATA_CNT     (89L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_WRITE_TRANSFERS_CNT       (90L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_WRITE_DELAY_PCI_CLKS_CNT  (91L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_TRANSFERS_CNT   (92L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_DELAY_PCI_CLKS_CNT      (93L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_RETRY_AFTER_DATA_CNT    (94L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_WR_CNT64   (95L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_RD_CNT64   (96L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_ACC_STALL_CLKS     (97L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_LOCK_STALL_CLKS    (98L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_CTX_ACCESS_STAT    (99L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_CTX_ACCESS64_STAT  (100L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_PCI_STALL_STAT     (101L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDR_FTQ_ENTRY_CNT     (102L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDR_BURST_CNT         (103L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMA_FTQ_ENTRY_CNT     (104L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMA_BURST_CNT         (105L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMA_FTQ_ENTRY_CNT     (106L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMA_BURST_CNT         (107L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUP_MATCH_CNT         (108L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_POLL_PASS_CNT      (109L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR1_CNT   (110L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR2_CNT   (111L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR3_CNT   (112L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR4_CNT   (113L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR5_CNT   (114L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT0     (115L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT1     (116L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT2     (117L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT3     (118L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT4     (119L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT5     (120L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_PROC1_MISS        (121L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_PROC2_MISS        (122L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_BURST_CNT         (127L<<0)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_1                (0x7fL<<8)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_2                (0x7fL<<16)
+#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_3                (0x7fL<<24)
+
+#define BNX2_HC_STAT_GEN_SEL_1                         0x00006854
+#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_4                (0x7fL<<0)
+#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_5                (0x7fL<<8)
+#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_6                (0x7fL<<16)
+#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_7                (0x7fL<<24)
+
+#define BNX2_HC_STAT_GEN_SEL_2                         0x00006858
+#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_8                (0x7fL<<0)
+#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_9                (0x7fL<<8)
+#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_10               (0x7fL<<16)
+#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_11               (0x7fL<<24)
+
+#define BNX2_HC_STAT_GEN_SEL_3                         0x0000685c
+#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_12               (0x7fL<<0)
+#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_13               (0x7fL<<8)
+#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_14               (0x7fL<<16)
+#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_15               (0x7fL<<24)
+
+#define BNX2_HC_STAT_GEN_STAT0                         0x00006888
+#define BNX2_HC_STAT_GEN_STAT1                         0x0000688c
+#define BNX2_HC_STAT_GEN_STAT2                         0x00006890
+#define BNX2_HC_STAT_GEN_STAT3                         0x00006894
+#define BNX2_HC_STAT_GEN_STAT4                         0x00006898
+#define BNX2_HC_STAT_GEN_STAT5                         0x0000689c
+#define BNX2_HC_STAT_GEN_STAT6                         0x000068a0
+#define BNX2_HC_STAT_GEN_STAT7                         0x000068a4
+#define BNX2_HC_STAT_GEN_STAT8                         0x000068a8
+#define BNX2_HC_STAT_GEN_STAT9                         0x000068ac
+#define BNX2_HC_STAT_GEN_STAT10                                0x000068b0
+#define BNX2_HC_STAT_GEN_STAT11                                0x000068b4
+#define BNX2_HC_STAT_GEN_STAT12                                0x000068b8
+#define BNX2_HC_STAT_GEN_STAT13                                0x000068bc
+#define BNX2_HC_STAT_GEN_STAT14                                0x000068c0
+#define BNX2_HC_STAT_GEN_STAT15                                0x000068c4
+#define BNX2_HC_STAT_GEN_STAT_AC0                      0x000068c8
+#define BNX2_HC_STAT_GEN_STAT_AC1                      0x000068cc
+#define BNX2_HC_STAT_GEN_STAT_AC2                      0x000068d0
+#define BNX2_HC_STAT_GEN_STAT_AC3                      0x000068d4
+#define BNX2_HC_STAT_GEN_STAT_AC4                      0x000068d8
+#define BNX2_HC_STAT_GEN_STAT_AC5                      0x000068dc
+#define BNX2_HC_STAT_GEN_STAT_AC6                      0x000068e0
+#define BNX2_HC_STAT_GEN_STAT_AC7                      0x000068e4
+#define BNX2_HC_STAT_GEN_STAT_AC8                      0x000068e8
+#define BNX2_HC_STAT_GEN_STAT_AC9                      0x000068ec
+#define BNX2_HC_STAT_GEN_STAT_AC10                     0x000068f0
+#define BNX2_HC_STAT_GEN_STAT_AC11                     0x000068f4
+#define BNX2_HC_STAT_GEN_STAT_AC12                     0x000068f8
+#define BNX2_HC_STAT_GEN_STAT_AC13                     0x000068fc
+#define BNX2_HC_STAT_GEN_STAT_AC14                     0x00006900
+#define BNX2_HC_STAT_GEN_STAT_AC15                     0x00006904
+#define BNX2_HC_VIS                                    0x00006908
+#define BNX2_HC_VIS_STAT_BUILD_STATE                    (0xfL<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_IDLE               (0L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_START              (1L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_REQUEST            (2L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE64           (3L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE32           (4L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE_DONE        (5L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_DMA                (6L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_CONTROL        (7L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_LOW            (8L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_HIGH           (9L<<0)
+#define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_DATA           (10L<<0)
+#define BNX2_HC_VIS_DMA_STAT_STATE                      (0xfL<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_IDLE                         (0L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_STATUS_PARAM                 (1L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_STATUS_DMA           (2L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP           (3L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_COMP                         (4L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_STATISTIC_PARAM      (5L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_STATISTIC_DMA        (6L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP_1                 (7L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP_2                 (8L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_WAIT                         (9L<<8)
+#define BNX2_HC_VIS_DMA_STAT_STATE_ABORT                (15L<<8)
+#define BNX2_HC_VIS_DMA_MSI_STATE                       (0x7L<<12)
+#define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE              (0x3L<<15)
+#define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_IDLE                 (0L<<15)
+#define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_COUNT        (1L<<15)
+#define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_START        (2L<<15)
+
+#define BNX2_HC_VIS_1                                  0x0000690c
+#define BNX2_HC_VIS_1_HW_INTACK_STATE                   (1L<<4)
+#define BNX2_HC_VIS_1_HW_INTACK_STATE_IDLE              (0L<<4)
+#define BNX2_HC_VIS_1_HW_INTACK_STATE_COUNT             (1L<<4)
+#define BNX2_HC_VIS_1_SW_INTACK_STATE                   (1L<<5)
+#define BNX2_HC_VIS_1_SW_INTACK_STATE_IDLE              (0L<<5)
+#define BNX2_HC_VIS_1_SW_INTACK_STATE_COUNT             (1L<<5)
+#define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE            (1L<<6)
+#define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE_IDLE       (0L<<6)
+#define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE_COUNT      (1L<<6)
+#define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE               (1L<<7)
+#define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE_IDLE          (0L<<7)
+#define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE_COUNT                 (1L<<7)
+#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE                  (0xfL<<17)
+#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_IDLE             (0L<<17)
+#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_DMA              (1L<<17)
+#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_UPDATE           (2L<<17)
+#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_ASSIGN           (3L<<17)
+#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_WAIT             (4L<<17)
+#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_UPDATE       (5L<<17)
+#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_ASSIGN       (6L<<17)
+#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_WAIT                 (7L<<17)
+#define BNX2_HC_VIS_1_RAM_WR_ARB_STATE                  (0x3L<<21)
+#define BNX2_HC_VIS_1_RAM_WR_ARB_STATE_NORMAL           (0L<<21)
+#define BNX2_HC_VIS_1_RAM_WR_ARB_STATE_CLEAR            (1L<<21)
+#define BNX2_HC_VIS_1_INT_GEN_STATE                     (1L<<23)
+#define BNX2_HC_VIS_1_INT_GEN_STATE_DLE                         (0L<<23)
+#define BNX2_HC_VIS_1_INT_GEN_STATE_NTERRUPT            (1L<<23)
+#define BNX2_HC_VIS_1_STAT_CHAN_ID                      (0x7L<<24)
+#define BNX2_HC_VIS_1_INT_B                             (1L<<27)
+
+#define BNX2_HC_DEBUG_VECT_PEEK                                0x00006910
+#define BNX2_HC_DEBUG_VECT_PEEK_1_VALUE                         (0x7ffL<<0)
+#define BNX2_HC_DEBUG_VECT_PEEK_1_PEEK_EN               (1L<<11)
+#define BNX2_HC_DEBUG_VECT_PEEK_1_SEL                   (0xfL<<12)
+#define BNX2_HC_DEBUG_VECT_PEEK_2_VALUE                         (0x7ffL<<16)
+#define BNX2_HC_DEBUG_VECT_PEEK_2_PEEK_EN               (1L<<27)
+#define BNX2_HC_DEBUG_VECT_PEEK_2_SEL                   (0xfL<<28)
+
+
+
+/*
+ *  txp_reg definition
+ *  offset: 0x40000
+ */
+#define BNX2_TXP_CPU_MODE                              0x00045000
+#define BNX2_TXP_CPU_MODE_LOCAL_RST                     (1L<<0)
+#define BNX2_TXP_CPU_MODE_STEP_ENA                      (1L<<1)
+#define BNX2_TXP_CPU_MODE_PAGE_0_DATA_ENA               (1L<<2)
+#define BNX2_TXP_CPU_MODE_PAGE_0_INST_ENA               (1L<<3)
+#define BNX2_TXP_CPU_MODE_MSG_BIT1                      (1L<<6)
+#define BNX2_TXP_CPU_MODE_INTERRUPT_ENA                         (1L<<7)
+#define BNX2_TXP_CPU_MODE_SOFT_HALT                     (1L<<10)
+#define BNX2_TXP_CPU_MODE_BAD_DATA_HALT_ENA             (1L<<11)
+#define BNX2_TXP_CPU_MODE_BAD_INST_HALT_ENA             (1L<<12)
+#define BNX2_TXP_CPU_MODE_FIO_ABORT_HALT_ENA            (1L<<13)
+#define BNX2_TXP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA       (1L<<15)
+
+#define BNX2_TXP_CPU_STATE                             0x00045004
+#define BNX2_TXP_CPU_STATE_BREAKPOINT                   (1L<<0)
+#define BNX2_TXP_CPU_STATE_BAD_INST_HALTED              (1L<<2)
+#define BNX2_TXP_CPU_STATE_PAGE_0_DATA_HALTED           (1L<<3)
+#define BNX2_TXP_CPU_STATE_PAGE_0_INST_HALTED           (1L<<4)
+#define BNX2_TXP_CPU_STATE_BAD_DATA_ADDR_HALTED                 (1L<<5)
+#define BNX2_TXP_CPU_STATE_BAD_pc_HALTED                (1L<<6)
+#define BNX2_TXP_CPU_STATE_ALIGN_HALTED                         (1L<<7)
+#define BNX2_TXP_CPU_STATE_FIO_ABORT_HALTED             (1L<<8)
+#define BNX2_TXP_CPU_STATE_SOFT_HALTED                  (1L<<10)
+#define BNX2_TXP_CPU_STATE_SPAD_UNDERFLOW               (1L<<11)
+#define BNX2_TXP_CPU_STATE_INTERRRUPT                   (1L<<12)
+#define BNX2_TXP_CPU_STATE_DATA_ACCESS_STALL            (1L<<14)
+#define BNX2_TXP_CPU_STATE_INST_FETCH_STALL             (1L<<15)
+#define BNX2_TXP_CPU_STATE_BLOCKED_READ                         (1L<<31)
+
+#define BNX2_TXP_CPU_EVENT_MASK                                0x00045008
+#define BNX2_TXP_CPU_EVENT_MASK_BREAKPOINT_MASK                 (1L<<0)
+#define BNX2_TXP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK    (1L<<2)
+#define BNX2_TXP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK         (1L<<3)
+#define BNX2_TXP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK         (1L<<4)
+#define BNX2_TXP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK       (1L<<5)
+#define BNX2_TXP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK      (1L<<6)
+#define BNX2_TXP_CPU_EVENT_MASK_ALIGN_HALTED_MASK       (1L<<7)
+#define BNX2_TXP_CPU_EVENT_MASK_FIO_ABORT_MASK          (1L<<8)
+#define BNX2_TXP_CPU_EVENT_MASK_SOFT_HALTED_MASK        (1L<<10)
+#define BNX2_TXP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK     (1L<<11)
+#define BNX2_TXP_CPU_EVENT_MASK_INTERRUPT_MASK          (1L<<12)
+
+#define BNX2_TXP_CPU_PROGRAM_COUNTER                   0x0004501c
+#define BNX2_TXP_CPU_INSTRUCTION                       0x00045020
+#define BNX2_TXP_CPU_DATA_ACCESS                       0x00045024
+#define BNX2_TXP_CPU_INTERRUPT_ENABLE                  0x00045028
+#define BNX2_TXP_CPU_INTERRUPT_VECTOR                  0x0004502c
+#define BNX2_TXP_CPU_INTERRUPT_SAVED_PC                        0x00045030
+#define BNX2_TXP_CPU_HW_BREAKPOINT                     0x00045034
+#define BNX2_TXP_CPU_HW_BREAKPOINT_DISABLE              (1L<<0)
+#define BNX2_TXP_CPU_HW_BREAKPOINT_ADDRESS              (0x3fffffffL<<2)
+
+#define BNX2_TXP_CPU_DEBUG_VECT_PEEK                   0x00045038
+#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_VALUE            (0x7ffL<<0)
+#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN          (1L<<11)
+#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_SEL              (0xfL<<12)
+#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_VALUE            (0x7ffL<<16)
+#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN          (1L<<27)
+#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_SEL              (0xfL<<28)
+
+#define BNX2_TXP_CPU_LAST_BRANCH_ADDR                  0x00045048
+#define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE              (1L<<1)
+#define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP                 (0L<<1)
+#define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH       (1L<<1)
+#define BNX2_TXP_CPU_LAST_BRANCH_ADDR_LBA               (0x3fffffffL<<2)
+
+#define BNX2_TXP_CPU_REG_FILE                          0x00045200
+#define BNX2_TXP_FTQ_DATA                              0x000453c0
+#define BNX2_TXP_FTQ_CMD                               0x000453f8
+#define BNX2_TXP_FTQ_CMD_OFFSET                                 (0x3ffL<<0)
+#define BNX2_TXP_FTQ_CMD_WR_TOP                                 (1L<<10)
+#define BNX2_TXP_FTQ_CMD_WR_TOP_0                       (0L<<10)
+#define BNX2_TXP_FTQ_CMD_WR_TOP_1                       (1L<<10)
+#define BNX2_TXP_FTQ_CMD_SFT_RESET                      (1L<<25)
+#define BNX2_TXP_FTQ_CMD_RD_DATA                        (1L<<26)
+#define BNX2_TXP_FTQ_CMD_ADD_INTERVEN                   (1L<<27)
+#define BNX2_TXP_FTQ_CMD_ADD_DATA                       (1L<<28)
+#define BNX2_TXP_FTQ_CMD_INTERVENE_CLR                  (1L<<29)
+#define BNX2_TXP_FTQ_CMD_POP                            (1L<<30)
+#define BNX2_TXP_FTQ_CMD_BUSY                           (1L<<31)
+
+#define BNX2_TXP_FTQ_CTL                               0x000453fc
+#define BNX2_TXP_FTQ_CTL_INTERVENE                      (1L<<0)
+#define BNX2_TXP_FTQ_CTL_OVERFLOW                       (1L<<1)
+#define BNX2_TXP_FTQ_CTL_FORCE_INTERVENE                (1L<<2)
+#define BNX2_TXP_FTQ_CTL_MAX_DEPTH                      (0x3ffL<<12)
+#define BNX2_TXP_FTQ_CTL_CUR_DEPTH                      (0x3ffL<<22)
+
+#define BNX2_TXP_SCRATCH                               0x00060000
+
+
+/*
+ *  tpat_reg definition
+ *  offset: 0x80000
+ */
+#define BNX2_TPAT_CPU_MODE                             0x00085000
+#define BNX2_TPAT_CPU_MODE_LOCAL_RST                    (1L<<0)
+#define BNX2_TPAT_CPU_MODE_STEP_ENA                     (1L<<1)
+#define BNX2_TPAT_CPU_MODE_PAGE_0_DATA_ENA              (1L<<2)
+#define BNX2_TPAT_CPU_MODE_PAGE_0_INST_ENA              (1L<<3)
+#define BNX2_TPAT_CPU_MODE_MSG_BIT1                     (1L<<6)
+#define BNX2_TPAT_CPU_MODE_INTERRUPT_ENA                (1L<<7)
+#define BNX2_TPAT_CPU_MODE_SOFT_HALT                    (1L<<10)
+#define BNX2_TPAT_CPU_MODE_BAD_DATA_HALT_ENA            (1L<<11)
+#define BNX2_TPAT_CPU_MODE_BAD_INST_HALT_ENA            (1L<<12)
+#define BNX2_TPAT_CPU_MODE_FIO_ABORT_HALT_ENA           (1L<<13)
+#define BNX2_TPAT_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA      (1L<<15)
+
+#define BNX2_TPAT_CPU_STATE                            0x00085004
+#define BNX2_TPAT_CPU_STATE_BREAKPOINT                  (1L<<0)
+#define BNX2_TPAT_CPU_STATE_BAD_INST_HALTED             (1L<<2)
+#define BNX2_TPAT_CPU_STATE_PAGE_0_DATA_HALTED          (1L<<3)
+#define BNX2_TPAT_CPU_STATE_PAGE_0_INST_HALTED          (1L<<4)
+#define BNX2_TPAT_CPU_STATE_BAD_DATA_ADDR_HALTED        (1L<<5)
+#define BNX2_TPAT_CPU_STATE_BAD_pc_HALTED               (1L<<6)
+#define BNX2_TPAT_CPU_STATE_ALIGN_HALTED                (1L<<7)
+#define BNX2_TPAT_CPU_STATE_FIO_ABORT_HALTED            (1L<<8)
+#define BNX2_TPAT_CPU_STATE_SOFT_HALTED                         (1L<<10)
+#define BNX2_TPAT_CPU_STATE_SPAD_UNDERFLOW              (1L<<11)
+#define BNX2_TPAT_CPU_STATE_INTERRRUPT                  (1L<<12)
+#define BNX2_TPAT_CPU_STATE_DATA_ACCESS_STALL           (1L<<14)
+#define BNX2_TPAT_CPU_STATE_INST_FETCH_STALL            (1L<<15)
+#define BNX2_TPAT_CPU_STATE_BLOCKED_READ                (1L<<31)
+
+#define BNX2_TPAT_CPU_EVENT_MASK                       0x00085008
+#define BNX2_TPAT_CPU_EVENT_MASK_BREAKPOINT_MASK        (1L<<0)
+#define BNX2_TPAT_CPU_EVENT_MASK_BAD_INST_HALTED_MASK   (1L<<2)
+#define BNX2_TPAT_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK        (1L<<3)
+#define BNX2_TPAT_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK        (1L<<4)
+#define BNX2_TPAT_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK      (1L<<5)
+#define BNX2_TPAT_CPU_EVENT_MASK_BAD_PC_HALTED_MASK     (1L<<6)
+#define BNX2_TPAT_CPU_EVENT_MASK_ALIGN_HALTED_MASK      (1L<<7)
+#define BNX2_TPAT_CPU_EVENT_MASK_FIO_ABORT_MASK                 (1L<<8)
+#define BNX2_TPAT_CPU_EVENT_MASK_SOFT_HALTED_MASK       (1L<<10)
+#define BNX2_TPAT_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK    (1L<<11)
+#define BNX2_TPAT_CPU_EVENT_MASK_INTERRUPT_MASK                 (1L<<12)
+
+#define BNX2_TPAT_CPU_PROGRAM_COUNTER                  0x0008501c
+#define BNX2_TPAT_CPU_INSTRUCTION                      0x00085020
+#define BNX2_TPAT_CPU_DATA_ACCESS                      0x00085024
+#define BNX2_TPAT_CPU_INTERRUPT_ENABLE                 0x00085028
+#define BNX2_TPAT_CPU_INTERRUPT_VECTOR                 0x0008502c
+#define BNX2_TPAT_CPU_INTERRUPT_SAVED_PC               0x00085030
+#define BNX2_TPAT_CPU_HW_BREAKPOINT                    0x00085034
+#define BNX2_TPAT_CPU_HW_BREAKPOINT_DISABLE             (1L<<0)
+#define BNX2_TPAT_CPU_HW_BREAKPOINT_ADDRESS             (0x3fffffffL<<2)
+
+#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK                  0x00085038
+#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_VALUE           (0x7ffL<<0)
+#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_PEEK_EN                 (1L<<11)
+#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_SEL             (0xfL<<12)
+#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_VALUE           (0x7ffL<<16)
+#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_PEEK_EN                 (1L<<27)
+#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_SEL             (0xfL<<28)
+
+#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR                 0x00085048
+#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE             (1L<<1)
+#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE_JUMP        (0L<<1)
+#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH      (1L<<1)
+#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_LBA              (0x3fffffffL<<2)
+
+#define BNX2_TPAT_CPU_REG_FILE                         0x00085200
+#define BNX2_TPAT_FTQ_DATA                             0x000853c0
+#define BNX2_TPAT_FTQ_CMD                              0x000853f8
+#define BNX2_TPAT_FTQ_CMD_OFFSET                        (0x3ffL<<0)
+#define BNX2_TPAT_FTQ_CMD_WR_TOP                        (1L<<10)
+#define BNX2_TPAT_FTQ_CMD_WR_TOP_0                      (0L<<10)
+#define BNX2_TPAT_FTQ_CMD_WR_TOP_1                      (1L<<10)
+#define BNX2_TPAT_FTQ_CMD_SFT_RESET                     (1L<<25)
+#define BNX2_TPAT_FTQ_CMD_RD_DATA                       (1L<<26)
+#define BNX2_TPAT_FTQ_CMD_ADD_INTERVEN                  (1L<<27)
+#define BNX2_TPAT_FTQ_CMD_ADD_DATA                      (1L<<28)
+#define BNX2_TPAT_FTQ_CMD_INTERVENE_CLR                         (1L<<29)
+#define BNX2_TPAT_FTQ_CMD_POP                           (1L<<30)
+#define BNX2_TPAT_FTQ_CMD_BUSY                          (1L<<31)
+
+#define BNX2_TPAT_FTQ_CTL                              0x000853fc
+#define BNX2_TPAT_FTQ_CTL_INTERVENE                     (1L<<0)
+#define BNX2_TPAT_FTQ_CTL_OVERFLOW                      (1L<<1)
+#define BNX2_TPAT_FTQ_CTL_FORCE_INTERVENE               (1L<<2)
+#define BNX2_TPAT_FTQ_CTL_MAX_DEPTH                     (0x3ffL<<12)
+#define BNX2_TPAT_FTQ_CTL_CUR_DEPTH                     (0x3ffL<<22)
+
+#define BNX2_TPAT_SCRATCH                              0x000a0000
+
+
+/*
+ *  rxp_reg definition
+ *  offset: 0xc0000
+ */
+#define BNX2_RXP_CPU_MODE                              0x000c5000
+#define BNX2_RXP_CPU_MODE_LOCAL_RST                     (1L<<0)
+#define BNX2_RXP_CPU_MODE_STEP_ENA                      (1L<<1)
+#define BNX2_RXP_CPU_MODE_PAGE_0_DATA_ENA               (1L<<2)
+#define BNX2_RXP_CPU_MODE_PAGE_0_INST_ENA               (1L<<3)
+#define BNX2_RXP_CPU_MODE_MSG_BIT1                      (1L<<6)
+#define BNX2_RXP_CPU_MODE_INTERRUPT_ENA                         (1L<<7)
+#define BNX2_RXP_CPU_MODE_SOFT_HALT                     (1L<<10)
+#define BNX2_RXP_CPU_MODE_BAD_DATA_HALT_ENA             (1L<<11)
+#define BNX2_RXP_CPU_MODE_BAD_INST_HALT_ENA             (1L<<12)
+#define BNX2_RXP_CPU_MODE_FIO_ABORT_HALT_ENA            (1L<<13)
+#define BNX2_RXP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA       (1L<<15)
+
+#define BNX2_RXP_CPU_STATE                             0x000c5004
+#define BNX2_RXP_CPU_STATE_BREAKPOINT                   (1L<<0)
+#define BNX2_RXP_CPU_STATE_BAD_INST_HALTED              (1L<<2)
+#define BNX2_RXP_CPU_STATE_PAGE_0_DATA_HALTED           (1L<<3)
+#define BNX2_RXP_CPU_STATE_PAGE_0_INST_HALTED           (1L<<4)
+#define BNX2_RXP_CPU_STATE_BAD_DATA_ADDR_HALTED                 (1L<<5)
+#define BNX2_RXP_CPU_STATE_BAD_pc_HALTED                (1L<<6)
+#define BNX2_RXP_CPU_STATE_ALIGN_HALTED                         (1L<<7)
+#define BNX2_RXP_CPU_STATE_FIO_ABORT_HALTED             (1L<<8)
+#define BNX2_RXP_CPU_STATE_SOFT_HALTED                  (1L<<10)
+#define BNX2_RXP_CPU_STATE_SPAD_UNDERFLOW               (1L<<11)
+#define BNX2_RXP_CPU_STATE_INTERRRUPT                   (1L<<12)
+#define BNX2_RXP_CPU_STATE_DATA_ACCESS_STALL            (1L<<14)
+#define BNX2_RXP_CPU_STATE_INST_FETCH_STALL             (1L<<15)
+#define BNX2_RXP_CPU_STATE_BLOCKED_READ                         (1L<<31)
+
+#define BNX2_RXP_CPU_EVENT_MASK                                0x000c5008
+#define BNX2_RXP_CPU_EVENT_MASK_BREAKPOINT_MASK                 (1L<<0)
+#define BNX2_RXP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK    (1L<<2)
+#define BNX2_RXP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK         (1L<<3)
+#define BNX2_RXP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK         (1L<<4)
+#define BNX2_RXP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK       (1L<<5)
+#define BNX2_RXP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK      (1L<<6)
+#define BNX2_RXP_CPU_EVENT_MASK_ALIGN_HALTED_MASK       (1L<<7)
+#define BNX2_RXP_CPU_EVENT_MASK_FIO_ABORT_MASK          (1L<<8)
+#define BNX2_RXP_CPU_EVENT_MASK_SOFT_HALTED_MASK        (1L<<10)
+#define BNX2_RXP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK     (1L<<11)
+#define BNX2_RXP_CPU_EVENT_MASK_INTERRUPT_MASK          (1L<<12)
+
+#define BNX2_RXP_CPU_PROGRAM_COUNTER                   0x000c501c
+#define BNX2_RXP_CPU_INSTRUCTION                       0x000c5020
+#define BNX2_RXP_CPU_DATA_ACCESS                       0x000c5024
+#define BNX2_RXP_CPU_INTERRUPT_ENABLE                  0x000c5028
+#define BNX2_RXP_CPU_INTERRUPT_VECTOR                  0x000c502c
+#define BNX2_RXP_CPU_INTERRUPT_SAVED_PC                        0x000c5030
+#define BNX2_RXP_CPU_HW_BREAKPOINT                     0x000c5034
+#define BNX2_RXP_CPU_HW_BREAKPOINT_DISABLE              (1L<<0)
+#define BNX2_RXP_CPU_HW_BREAKPOINT_ADDRESS              (0x3fffffffL<<2)
+
+#define BNX2_RXP_CPU_DEBUG_VECT_PEEK                   0x000c5038
+#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_VALUE            (0x7ffL<<0)
+#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN          (1L<<11)
+#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_SEL              (0xfL<<12)
+#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_VALUE            (0x7ffL<<16)
+#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN          (1L<<27)
+#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_SEL              (0xfL<<28)
+
+#define BNX2_RXP_CPU_LAST_BRANCH_ADDR                  0x000c5048
+#define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE              (1L<<1)
+#define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP                 (0L<<1)
+#define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH       (1L<<1)
+#define BNX2_RXP_CPU_LAST_BRANCH_ADDR_LBA               (0x3fffffffL<<2)
+
+#define BNX2_RXP_CPU_REG_FILE                          0x000c5200
+#define BNX2_RXP_CFTQ_DATA                             0x000c5380
+#define BNX2_RXP_CFTQ_CMD                              0x000c53b8
+#define BNX2_RXP_CFTQ_CMD_OFFSET                        (0x3ffL<<0)
+#define BNX2_RXP_CFTQ_CMD_WR_TOP                        (1L<<10)
+#define BNX2_RXP_CFTQ_CMD_WR_TOP_0                      (0L<<10)
+#define BNX2_RXP_CFTQ_CMD_WR_TOP_1                      (1L<<10)
+#define BNX2_RXP_CFTQ_CMD_SFT_RESET                     (1L<<25)
+#define BNX2_RXP_CFTQ_CMD_RD_DATA                       (1L<<26)
+#define BNX2_RXP_CFTQ_CMD_ADD_INTERVEN                  (1L<<27)
+#define BNX2_RXP_CFTQ_CMD_ADD_DATA                      (1L<<28)
+#define BNX2_RXP_CFTQ_CMD_INTERVENE_CLR                         (1L<<29)
+#define BNX2_RXP_CFTQ_CMD_POP                           (1L<<30)
+#define BNX2_RXP_CFTQ_CMD_BUSY                          (1L<<31)
+
+#define BNX2_RXP_CFTQ_CTL                              0x000c53bc
+#define BNX2_RXP_CFTQ_CTL_INTERVENE                     (1L<<0)
+#define BNX2_RXP_CFTQ_CTL_OVERFLOW                      (1L<<1)
+#define BNX2_RXP_CFTQ_CTL_FORCE_INTERVENE               (1L<<2)
+#define BNX2_RXP_CFTQ_CTL_MAX_DEPTH                     (0x3ffL<<12)
+#define BNX2_RXP_CFTQ_CTL_CUR_DEPTH                     (0x3ffL<<22)
+
+#define BNX2_RXP_FTQ_DATA                              0x000c53c0
+#define BNX2_RXP_FTQ_CMD                               0x000c53f8
+#define BNX2_RXP_FTQ_CMD_OFFSET                                 (0x3ffL<<0)
+#define BNX2_RXP_FTQ_CMD_WR_TOP                                 (1L<<10)
+#define BNX2_RXP_FTQ_CMD_WR_TOP_0                       (0L<<10)
+#define BNX2_RXP_FTQ_CMD_WR_TOP_1                       (1L<<10)
+#define BNX2_RXP_FTQ_CMD_SFT_RESET                      (1L<<25)
+#define BNX2_RXP_FTQ_CMD_RD_DATA                        (1L<<26)
+#define BNX2_RXP_FTQ_CMD_ADD_INTERVEN                   (1L<<27)
+#define BNX2_RXP_FTQ_CMD_ADD_DATA                       (1L<<28)
+#define BNX2_RXP_FTQ_CMD_INTERVENE_CLR                  (1L<<29)
+#define BNX2_RXP_FTQ_CMD_POP                            (1L<<30)
+#define BNX2_RXP_FTQ_CMD_BUSY                           (1L<<31)
+
+#define BNX2_RXP_FTQ_CTL                               0x000c53fc
+#define BNX2_RXP_FTQ_CTL_INTERVENE                      (1L<<0)
+#define BNX2_RXP_FTQ_CTL_OVERFLOW                       (1L<<1)
+#define BNX2_RXP_FTQ_CTL_FORCE_INTERVENE                (1L<<2)
+#define BNX2_RXP_FTQ_CTL_MAX_DEPTH                      (0x3ffL<<12)
+#define BNX2_RXP_FTQ_CTL_CUR_DEPTH                      (0x3ffL<<22)
+
+#define BNX2_RXP_SCRATCH                               0x000e0000
+
+
+/*
+ *  com_reg definition
+ *  offset: 0x100000
+ */
+#define BNX2_COM_CPU_MODE                              0x00105000
+#define BNX2_COM_CPU_MODE_LOCAL_RST                     (1L<<0)
+#define BNX2_COM_CPU_MODE_STEP_ENA                      (1L<<1)
+#define BNX2_COM_CPU_MODE_PAGE_0_DATA_ENA               (1L<<2)
+#define BNX2_COM_CPU_MODE_PAGE_0_INST_ENA               (1L<<3)
+#define BNX2_COM_CPU_MODE_MSG_BIT1                      (1L<<6)
+#define BNX2_COM_CPU_MODE_INTERRUPT_ENA                         (1L<<7)
+#define BNX2_COM_CPU_MODE_SOFT_HALT                     (1L<<10)
+#define BNX2_COM_CPU_MODE_BAD_DATA_HALT_ENA             (1L<<11)
+#define BNX2_COM_CPU_MODE_BAD_INST_HALT_ENA             (1L<<12)
+#define BNX2_COM_CPU_MODE_FIO_ABORT_HALT_ENA            (1L<<13)
+#define BNX2_COM_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA       (1L<<15)
+
+#define BNX2_COM_CPU_STATE                             0x00105004
+#define BNX2_COM_CPU_STATE_BREAKPOINT                   (1L<<0)
+#define BNX2_COM_CPU_STATE_BAD_INST_HALTED              (1L<<2)
+#define BNX2_COM_CPU_STATE_PAGE_0_DATA_HALTED           (1L<<3)
+#define BNX2_COM_CPU_STATE_PAGE_0_INST_HALTED           (1L<<4)
+#define BNX2_COM_CPU_STATE_BAD_DATA_ADDR_HALTED                 (1L<<5)
+#define BNX2_COM_CPU_STATE_BAD_pc_HALTED                (1L<<6)
+#define BNX2_COM_CPU_STATE_ALIGN_HALTED                         (1L<<7)
+#define BNX2_COM_CPU_STATE_FIO_ABORT_HALTED             (1L<<8)
+#define BNX2_COM_CPU_STATE_SOFT_HALTED                  (1L<<10)
+#define BNX2_COM_CPU_STATE_SPAD_UNDERFLOW               (1L<<11)
+#define BNX2_COM_CPU_STATE_INTERRRUPT                   (1L<<12)
+#define BNX2_COM_CPU_STATE_DATA_ACCESS_STALL            (1L<<14)
+#define BNX2_COM_CPU_STATE_INST_FETCH_STALL             (1L<<15)
+#define BNX2_COM_CPU_STATE_BLOCKED_READ                         (1L<<31)
+
+#define BNX2_COM_CPU_EVENT_MASK                                0x00105008
+#define BNX2_COM_CPU_EVENT_MASK_BREAKPOINT_MASK                 (1L<<0)
+#define BNX2_COM_CPU_EVENT_MASK_BAD_INST_HALTED_MASK    (1L<<2)
+#define BNX2_COM_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK         (1L<<3)
+#define BNX2_COM_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK         (1L<<4)
+#define BNX2_COM_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK       (1L<<5)
+#define BNX2_COM_CPU_EVENT_MASK_BAD_PC_HALTED_MASK      (1L<<6)
+#define BNX2_COM_CPU_EVENT_MASK_ALIGN_HALTED_MASK       (1L<<7)
+#define BNX2_COM_CPU_EVENT_MASK_FIO_ABORT_MASK          (1L<<8)
+#define BNX2_COM_CPU_EVENT_MASK_SOFT_HALTED_MASK        (1L<<10)
+#define BNX2_COM_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK     (1L<<11)
+#define BNX2_COM_CPU_EVENT_MASK_INTERRUPT_MASK          (1L<<12)
+
+#define BNX2_COM_CPU_PROGRAM_COUNTER                   0x0010501c
+#define BNX2_COM_CPU_INSTRUCTION                       0x00105020
+#define BNX2_COM_CPU_DATA_ACCESS                       0x00105024
+#define BNX2_COM_CPU_INTERRUPT_ENABLE                  0x00105028
+#define BNX2_COM_CPU_INTERRUPT_VECTOR                  0x0010502c
+#define BNX2_COM_CPU_INTERRUPT_SAVED_PC                        0x00105030
+#define BNX2_COM_CPU_HW_BREAKPOINT                     0x00105034
+#define BNX2_COM_CPU_HW_BREAKPOINT_DISABLE              (1L<<0)
+#define BNX2_COM_CPU_HW_BREAKPOINT_ADDRESS              (0x3fffffffL<<2)
+
+#define BNX2_COM_CPU_DEBUG_VECT_PEEK                   0x00105038
+#define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_VALUE            (0x7ffL<<0)
+#define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_PEEK_EN          (1L<<11)
+#define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_SEL              (0xfL<<12)
+#define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_VALUE            (0x7ffL<<16)
+#define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_PEEK_EN          (1L<<27)
+#define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_SEL              (0xfL<<28)
+
+#define BNX2_COM_CPU_LAST_BRANCH_ADDR                  0x00105048
+#define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE              (1L<<1)
+#define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE_JUMP                 (0L<<1)
+#define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH       (1L<<1)
+#define BNX2_COM_CPU_LAST_BRANCH_ADDR_LBA               (0x3fffffffL<<2)
+
+#define BNX2_COM_CPU_REG_FILE                          0x00105200
+#define BNX2_COM_COMXQ_FTQ_DATA                                0x00105340
+#define BNX2_COM_COMXQ_FTQ_CMD                         0x00105378
+#define BNX2_COM_COMXQ_FTQ_CMD_OFFSET                   (0x3ffL<<0)
+#define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP                   (1L<<10)
+#define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP_0                         (0L<<10)
+#define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP_1                         (1L<<10)
+#define BNX2_COM_COMXQ_FTQ_CMD_SFT_RESET                (1L<<25)
+#define BNX2_COM_COMXQ_FTQ_CMD_RD_DATA                  (1L<<26)
+#define BNX2_COM_COMXQ_FTQ_CMD_ADD_INTERVEN             (1L<<27)
+#define BNX2_COM_COMXQ_FTQ_CMD_ADD_DATA                         (1L<<28)
+#define BNX2_COM_COMXQ_FTQ_CMD_INTERVENE_CLR            (1L<<29)
+#define BNX2_COM_COMXQ_FTQ_CMD_POP                      (1L<<30)
+#define BNX2_COM_COMXQ_FTQ_CMD_BUSY                     (1L<<31)
+
+#define BNX2_COM_COMXQ_FTQ_CTL                         0x0010537c
+#define BNX2_COM_COMXQ_FTQ_CTL_INTERVENE                (1L<<0)
+#define BNX2_COM_COMXQ_FTQ_CTL_OVERFLOW                         (1L<<1)
+#define BNX2_COM_COMXQ_FTQ_CTL_FORCE_INTERVENE          (1L<<2)
+#define BNX2_COM_COMXQ_FTQ_CTL_MAX_DEPTH                (0x3ffL<<12)
+#define BNX2_COM_COMXQ_FTQ_CTL_CUR_DEPTH                (0x3ffL<<22)
+
+#define BNX2_COM_COMTQ_FTQ_DATA                                0x00105380
+#define BNX2_COM_COMTQ_FTQ_CMD                         0x001053b8
+#define BNX2_COM_COMTQ_FTQ_CMD_OFFSET                   (0x3ffL<<0)
+#define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP                   (1L<<10)
+#define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP_0                         (0L<<10)
+#define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP_1                         (1L<<10)
+#define BNX2_COM_COMTQ_FTQ_CMD_SFT_RESET                (1L<<25)
+#define BNX2_COM_COMTQ_FTQ_CMD_RD_DATA                  (1L<<26)
+#define BNX2_COM_COMTQ_FTQ_CMD_ADD_INTERVEN             (1L<<27)
+#define BNX2_COM_COMTQ_FTQ_CMD_ADD_DATA                         (1L<<28)
+#define BNX2_COM_COMTQ_FTQ_CMD_INTERVENE_CLR            (1L<<29)
+#define BNX2_COM_COMTQ_FTQ_CMD_POP                      (1L<<30)
+#define BNX2_COM_COMTQ_FTQ_CMD_BUSY                     (1L<<31)
+
+#define BNX2_COM_COMTQ_FTQ_CTL                         0x001053bc
+#define BNX2_COM_COMTQ_FTQ_CTL_INTERVENE                (1L<<0)
+#define BNX2_COM_COMTQ_FTQ_CTL_OVERFLOW                         (1L<<1)
+#define BNX2_COM_COMTQ_FTQ_CTL_FORCE_INTERVENE          (1L<<2)
+#define BNX2_COM_COMTQ_FTQ_CTL_MAX_DEPTH                (0x3ffL<<12)
+#define BNX2_COM_COMTQ_FTQ_CTL_CUR_DEPTH                (0x3ffL<<22)
+
+#define BNX2_COM_COMQ_FTQ_DATA                         0x001053c0
+#define BNX2_COM_COMQ_FTQ_CMD                          0x001053f8
+#define BNX2_COM_COMQ_FTQ_CMD_OFFSET                    (0x3ffL<<0)
+#define BNX2_COM_COMQ_FTQ_CMD_WR_TOP                    (1L<<10)
+#define BNX2_COM_COMQ_FTQ_CMD_WR_TOP_0                  (0L<<10)
+#define BNX2_COM_COMQ_FTQ_CMD_WR_TOP_1                  (1L<<10)
+#define BNX2_COM_COMQ_FTQ_CMD_SFT_RESET                         (1L<<25)
+#define BNX2_COM_COMQ_FTQ_CMD_RD_DATA                   (1L<<26)
+#define BNX2_COM_COMQ_FTQ_CMD_ADD_INTERVEN              (1L<<27)
+#define BNX2_COM_COMQ_FTQ_CMD_ADD_DATA                  (1L<<28)
+#define BNX2_COM_COMQ_FTQ_CMD_INTERVENE_CLR             (1L<<29)
+#define BNX2_COM_COMQ_FTQ_CMD_POP                       (1L<<30)
+#define BNX2_COM_COMQ_FTQ_CMD_BUSY                      (1L<<31)
+
+#define BNX2_COM_COMQ_FTQ_CTL                          0x001053fc
+#define BNX2_COM_COMQ_FTQ_CTL_INTERVENE                         (1L<<0)
+#define BNX2_COM_COMQ_FTQ_CTL_OVERFLOW                  (1L<<1)
+#define BNX2_COM_COMQ_FTQ_CTL_FORCE_INTERVENE           (1L<<2)
+#define BNX2_COM_COMQ_FTQ_CTL_MAX_DEPTH                         (0x3ffL<<12)
+#define BNX2_COM_COMQ_FTQ_CTL_CUR_DEPTH                         (0x3ffL<<22)
+
+#define BNX2_COM_SCRATCH                               0x00120000
+
+
+/*
+ *  cp_reg definition
+ *  offset: 0x180000
+ */
+#define BNX2_CP_CPU_MODE                               0x00185000
+#define BNX2_CP_CPU_MODE_LOCAL_RST                      (1L<<0)
+#define BNX2_CP_CPU_MODE_STEP_ENA                       (1L<<1)
+#define BNX2_CP_CPU_MODE_PAGE_0_DATA_ENA                (1L<<2)
+#define BNX2_CP_CPU_MODE_PAGE_0_INST_ENA                (1L<<3)
+#define BNX2_CP_CPU_MODE_MSG_BIT1                       (1L<<6)
+#define BNX2_CP_CPU_MODE_INTERRUPT_ENA                  (1L<<7)
+#define BNX2_CP_CPU_MODE_SOFT_HALT                      (1L<<10)
+#define BNX2_CP_CPU_MODE_BAD_DATA_HALT_ENA              (1L<<11)
+#define BNX2_CP_CPU_MODE_BAD_INST_HALT_ENA              (1L<<12)
+#define BNX2_CP_CPU_MODE_FIO_ABORT_HALT_ENA             (1L<<13)
+#define BNX2_CP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA        (1L<<15)
+
+#define BNX2_CP_CPU_STATE                              0x00185004
+#define BNX2_CP_CPU_STATE_BREAKPOINT                    (1L<<0)
+#define BNX2_CP_CPU_STATE_BAD_INST_HALTED               (1L<<2)
+#define BNX2_CP_CPU_STATE_PAGE_0_DATA_HALTED            (1L<<3)
+#define BNX2_CP_CPU_STATE_PAGE_0_INST_HALTED            (1L<<4)
+#define BNX2_CP_CPU_STATE_BAD_DATA_ADDR_HALTED          (1L<<5)
+#define BNX2_CP_CPU_STATE_BAD_pc_HALTED                         (1L<<6)
+#define BNX2_CP_CPU_STATE_ALIGN_HALTED                  (1L<<7)
+#define BNX2_CP_CPU_STATE_FIO_ABORT_HALTED              (1L<<8)
+#define BNX2_CP_CPU_STATE_SOFT_HALTED                   (1L<<10)
+#define BNX2_CP_CPU_STATE_SPAD_UNDERFLOW                (1L<<11)
+#define BNX2_CP_CPU_STATE_INTERRRUPT                    (1L<<12)
+#define BNX2_CP_CPU_STATE_DATA_ACCESS_STALL             (1L<<14)
+#define BNX2_CP_CPU_STATE_INST_FETCH_STALL              (1L<<15)
+#define BNX2_CP_CPU_STATE_BLOCKED_READ                  (1L<<31)
+
+#define BNX2_CP_CPU_EVENT_MASK                         0x00185008
+#define BNX2_CP_CPU_EVENT_MASK_BREAKPOINT_MASK          (1L<<0)
+#define BNX2_CP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK     (1L<<2)
+#define BNX2_CP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK  (1L<<3)
+#define BNX2_CP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK  (1L<<4)
+#define BNX2_CP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK        (1L<<5)
+#define BNX2_CP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK       (1L<<6)
+#define BNX2_CP_CPU_EVENT_MASK_ALIGN_HALTED_MASK        (1L<<7)
+#define BNX2_CP_CPU_EVENT_MASK_FIO_ABORT_MASK           (1L<<8)
+#define BNX2_CP_CPU_EVENT_MASK_SOFT_HALTED_MASK                 (1L<<10)
+#define BNX2_CP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK      (1L<<11)
+#define BNX2_CP_CPU_EVENT_MASK_INTERRUPT_MASK           (1L<<12)
+
+#define BNX2_CP_CPU_PROGRAM_COUNTER                    0x0018501c
+#define BNX2_CP_CPU_INSTRUCTION                                0x00185020
+#define BNX2_CP_CPU_DATA_ACCESS                                0x00185024
+#define BNX2_CP_CPU_INTERRUPT_ENABLE                   0x00185028
+#define BNX2_CP_CPU_INTERRUPT_VECTOR                   0x0018502c
+#define BNX2_CP_CPU_INTERRUPT_SAVED_PC                 0x00185030
+#define BNX2_CP_CPU_HW_BREAKPOINT                      0x00185034
+#define BNX2_CP_CPU_HW_BREAKPOINT_DISABLE               (1L<<0)
+#define BNX2_CP_CPU_HW_BREAKPOINT_ADDRESS               (0x3fffffffL<<2)
+
+#define BNX2_CP_CPU_DEBUG_VECT_PEEK                    0x00185038
+#define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_VALUE             (0x7ffL<<0)
+#define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN           (1L<<11)
+#define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_SEL               (0xfL<<12)
+#define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_VALUE             (0x7ffL<<16)
+#define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN           (1L<<27)
+#define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_SEL               (0xfL<<28)
+
+#define BNX2_CP_CPU_LAST_BRANCH_ADDR                   0x00185048
+#define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE               (1L<<1)
+#define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP          (0L<<1)
+#define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH        (1L<<1)
+#define BNX2_CP_CPU_LAST_BRANCH_ADDR_LBA                (0x3fffffffL<<2)
+
+#define BNX2_CP_CPU_REG_FILE                           0x00185200
+#define BNX2_CP_CPQ_FTQ_DATA                           0x001853c0
+#define BNX2_CP_CPQ_FTQ_CMD                            0x001853f8
+#define BNX2_CP_CPQ_FTQ_CMD_OFFSET                      (0x3ffL<<0)
+#define BNX2_CP_CPQ_FTQ_CMD_WR_TOP                      (1L<<10)
+#define BNX2_CP_CPQ_FTQ_CMD_WR_TOP_0                    (0L<<10)
+#define BNX2_CP_CPQ_FTQ_CMD_WR_TOP_1                    (1L<<10)
+#define BNX2_CP_CPQ_FTQ_CMD_SFT_RESET                   (1L<<25)
+#define BNX2_CP_CPQ_FTQ_CMD_RD_DATA                     (1L<<26)
+#define BNX2_CP_CPQ_FTQ_CMD_ADD_INTERVEN                (1L<<27)
+#define BNX2_CP_CPQ_FTQ_CMD_ADD_DATA                    (1L<<28)
+#define BNX2_CP_CPQ_FTQ_CMD_INTERVENE_CLR               (1L<<29)
+#define BNX2_CP_CPQ_FTQ_CMD_POP                                 (1L<<30)
+#define BNX2_CP_CPQ_FTQ_CMD_BUSY                        (1L<<31)
+
+#define BNX2_CP_CPQ_FTQ_CTL                            0x001853fc
+#define BNX2_CP_CPQ_FTQ_CTL_INTERVENE                   (1L<<0)
+#define BNX2_CP_CPQ_FTQ_CTL_OVERFLOW                    (1L<<1)
+#define BNX2_CP_CPQ_FTQ_CTL_FORCE_INTERVENE             (1L<<2)
+#define BNX2_CP_CPQ_FTQ_CTL_MAX_DEPTH                   (0x3ffL<<12)
+#define BNX2_CP_CPQ_FTQ_CTL_CUR_DEPTH                   (0x3ffL<<22)
+
+#define BNX2_CP_SCRATCH                                        0x001a0000
+
+
+/*
+ *  mcp_reg definition
+ *  offset: 0x140000
+ */
+#define BNX2_MCP_CPU_MODE                              0x00145000
+#define BNX2_MCP_CPU_MODE_LOCAL_RST                     (1L<<0)
+#define BNX2_MCP_CPU_MODE_STEP_ENA                      (1L<<1)
+#define BNX2_MCP_CPU_MODE_PAGE_0_DATA_ENA               (1L<<2)
+#define BNX2_MCP_CPU_MODE_PAGE_0_INST_ENA               (1L<<3)
+#define BNX2_MCP_CPU_MODE_MSG_BIT1                      (1L<<6)
+#define BNX2_MCP_CPU_MODE_INTERRUPT_ENA                         (1L<<7)
+#define BNX2_MCP_CPU_MODE_SOFT_HALT                     (1L<<10)
+#define BNX2_MCP_CPU_MODE_BAD_DATA_HALT_ENA             (1L<<11)
+#define BNX2_MCP_CPU_MODE_BAD_INST_HALT_ENA             (1L<<12)
+#define BNX2_MCP_CPU_MODE_FIO_ABORT_HALT_ENA            (1L<<13)
+#define BNX2_MCP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA       (1L<<15)
+
+#define BNX2_MCP_CPU_STATE                             0x00145004
+#define BNX2_MCP_CPU_STATE_BREAKPOINT                   (1L<<0)
+#define BNX2_MCP_CPU_STATE_BAD_INST_HALTED              (1L<<2)
+#define BNX2_MCP_CPU_STATE_PAGE_0_DATA_HALTED           (1L<<3)
+#define BNX2_MCP_CPU_STATE_PAGE_0_INST_HALTED           (1L<<4)
+#define BNX2_MCP_CPU_STATE_BAD_DATA_ADDR_HALTED                 (1L<<5)
+#define BNX2_MCP_CPU_STATE_BAD_pc_HALTED                (1L<<6)
+#define BNX2_MCP_CPU_STATE_ALIGN_HALTED                         (1L<<7)
+#define BNX2_MCP_CPU_STATE_FIO_ABORT_HALTED             (1L<<8)
+#define BNX2_MCP_CPU_STATE_SOFT_HALTED                  (1L<<10)
+#define BNX2_MCP_CPU_STATE_SPAD_UNDERFLOW               (1L<<11)
+#define BNX2_MCP_CPU_STATE_INTERRRUPT                   (1L<<12)
+#define BNX2_MCP_CPU_STATE_DATA_ACCESS_STALL            (1L<<14)
+#define BNX2_MCP_CPU_STATE_INST_FETCH_STALL             (1L<<15)
+#define BNX2_MCP_CPU_STATE_BLOCKED_READ                         (1L<<31)
+
+#define BNX2_MCP_CPU_EVENT_MASK                                0x00145008
+#define BNX2_MCP_CPU_EVENT_MASK_BREAKPOINT_MASK                 (1L<<0)
+#define BNX2_MCP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK    (1L<<2)
+#define BNX2_MCP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK         (1L<<3)
+#define BNX2_MCP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK         (1L<<4)
+#define BNX2_MCP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK       (1L<<5)
+#define BNX2_MCP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK      (1L<<6)
+#define BNX2_MCP_CPU_EVENT_MASK_ALIGN_HALTED_MASK       (1L<<7)
+#define BNX2_MCP_CPU_EVENT_MASK_FIO_ABORT_MASK          (1L<<8)
+#define BNX2_MCP_CPU_EVENT_MASK_SOFT_HALTED_MASK        (1L<<10)
+#define BNX2_MCP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK     (1L<<11)
+#define BNX2_MCP_CPU_EVENT_MASK_INTERRUPT_MASK          (1L<<12)
+
+#define BNX2_MCP_CPU_PROGRAM_COUNTER                   0x0014501c
+#define BNX2_MCP_CPU_INSTRUCTION                       0x00145020
+#define BNX2_MCP_CPU_DATA_ACCESS                       0x00145024
+#define BNX2_MCP_CPU_INTERRUPT_ENABLE                  0x00145028
+#define BNX2_MCP_CPU_INTERRUPT_VECTOR                  0x0014502c
+#define BNX2_MCP_CPU_INTERRUPT_SAVED_PC                        0x00145030
+#define BNX2_MCP_CPU_HW_BREAKPOINT                     0x00145034
+#define BNX2_MCP_CPU_HW_BREAKPOINT_DISABLE              (1L<<0)
+#define BNX2_MCP_CPU_HW_BREAKPOINT_ADDRESS              (0x3fffffffL<<2)
+
+#define BNX2_MCP_CPU_DEBUG_VECT_PEEK                   0x00145038
+#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_VALUE            (0x7ffL<<0)
+#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN          (1L<<11)
+#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_SEL              (0xfL<<12)
+#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_VALUE            (0x7ffL<<16)
+#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN          (1L<<27)
+#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_SEL              (0xfL<<28)
+
+#define BNX2_MCP_CPU_LAST_BRANCH_ADDR                  0x00145048
+#define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE              (1L<<1)
+#define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP                 (0L<<1)
+#define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH       (1L<<1)
+#define BNX2_MCP_CPU_LAST_BRANCH_ADDR_LBA               (0x3fffffffL<<2)
+
+#define BNX2_MCP_CPU_REG_FILE                          0x00145200
+#define BNX2_MCP_MCPQ_FTQ_DATA                         0x001453c0
+#define BNX2_MCP_MCPQ_FTQ_CMD                          0x001453f8
+#define BNX2_MCP_MCPQ_FTQ_CMD_OFFSET                    (0x3ffL<<0)
+#define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP                    (1L<<10)
+#define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP_0                  (0L<<10)
+#define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP_1                  (1L<<10)
+#define BNX2_MCP_MCPQ_FTQ_CMD_SFT_RESET                         (1L<<25)
+#define BNX2_MCP_MCPQ_FTQ_CMD_RD_DATA                   (1L<<26)
+#define BNX2_MCP_MCPQ_FTQ_CMD_ADD_INTERVEN              (1L<<27)
+#define BNX2_MCP_MCPQ_FTQ_CMD_ADD_DATA                  (1L<<28)
+#define BNX2_MCP_MCPQ_FTQ_CMD_INTERVENE_CLR             (1L<<29)
+#define BNX2_MCP_MCPQ_FTQ_CMD_POP                       (1L<<30)
+#define BNX2_MCP_MCPQ_FTQ_CMD_BUSY                      (1L<<31)
+
+#define BNX2_MCP_MCPQ_FTQ_CTL                          0x001453fc
+#define BNX2_MCP_MCPQ_FTQ_CTL_INTERVENE                         (1L<<0)
+#define BNX2_MCP_MCPQ_FTQ_CTL_OVERFLOW                  (1L<<1)
+#define BNX2_MCP_MCPQ_FTQ_CTL_FORCE_INTERVENE           (1L<<2)
+#define BNX2_MCP_MCPQ_FTQ_CTL_MAX_DEPTH                         (0x3ffL<<12)
+#define BNX2_MCP_MCPQ_FTQ_CTL_CUR_DEPTH                         (0x3ffL<<22)
+
+#define BNX2_MCP_ROM                                   0x00150000
+#define BNX2_MCP_SCRATCH                               0x00160000
+
+
+#define NUM_MC_HASH_REGISTERS   8
+
+
+/* PHY_ID1: bits 31-16; PHY_ID2: bits 15-0.  */
+#define PHY_BCM5706_PHY_ID                          0x00206160
+
+#define PHY_ID(id)                                  ((id) & 0xfffffff0)
+#define PHY_REV_ID(id)                              ((id) & 0xf)
+
+#define MIN_ETHERNET_PACKET_SIZE       60
+#define MAX_ETHERNET_PACKET_SIZE       1514
+#define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014
+
+#define RX_COPY_THRESH                 92
+
+#define DMA_READ_CHANS 5
+#define DMA_WRITE_CHANS        3
+
+#define BCM_PAGE_BITS  12
+#define BCM_PAGE_SIZE  (1 << BCM_PAGE_BITS)
+
+#define TX_DESC_CNT  (BCM_PAGE_SIZE / sizeof(struct tx_bd))
+#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
+
+#define RX_DESC_CNT  (BCM_PAGE_SIZE / sizeof(struct rx_bd))
+#define MAX_RX_DESC_CNT (RX_DESC_CNT - 1)
+
+#define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) ==                        \
+               (MAX_TX_DESC_CNT - 1)) ?                                \
+       (x) + 2 : (x) + 1
+
+#define TX_RING_IDX(x) ((x) & MAX_TX_DESC_CNT)
+
+#define NEXT_RX_BD(x) (((x) & (MAX_RX_DESC_CNT - 1)) ==                        \
+               (MAX_RX_DESC_CNT - 1)) ?                                \
+       (x) + 2 : (x) + 1
+
+#define RX_RING_IDX(x) ((x) & MAX_RX_DESC_CNT)
+
+
+/* Context size. */
+#define CTX_SHIFT                   7
+#define CTX_SIZE                    (1 << CTX_SHIFT)
+#define CTX_MASK                    (CTX_SIZE - 1)
+#define GET_CID_ADDR(_cid)          ((_cid) << CTX_SHIFT)
+#define GET_CID(_cid_addr)          ((_cid_addr) >> CTX_SHIFT)
+
+#define PHY_CTX_SHIFT               6
+#define PHY_CTX_SIZE                (1 << PHY_CTX_SHIFT)
+#define PHY_CTX_MASK                (PHY_CTX_SIZE - 1)
+#define GET_PCID_ADDR(_pcid)        ((_pcid) << PHY_CTX_SHIFT)
+#define GET_PCID(_pcid_addr)        ((_pcid_addr) >> PHY_CTX_SHIFT)
+
+#define MB_KERNEL_CTX_SHIFT         8
+#define MB_KERNEL_CTX_SIZE          (1 << MB_KERNEL_CTX_SHIFT)
+#define MB_KERNEL_CTX_MASK          (MB_KERNEL_CTX_SIZE - 1)
+#define MB_GET_CID_ADDR(_cid)       (0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT))
+
+#define MAX_CID_CNT                 0x4000
+#define MAX_CID_ADDR                (GET_CID_ADDR(MAX_CID_CNT))
+#define INVALID_CID_ADDR            0xffffffff
+
+#define TX_CID         16
+#define RX_CID         0
+
+#define MB_TX_CID_ADDR MB_GET_CID_ADDR(TX_CID)
+#define MB_RX_CID_ADDR MB_GET_CID_ADDR(RX_CID)
+
+struct sw_bd {
+       struct sk_buff          *skb;
+       DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+/* Buffered flash (Atmel: AT45DB011B) specific information */
+#define SEEPROM_PAGE_BITS                      2
+#define SEEPROM_PHY_PAGE_SIZE                  (1 << SEEPROM_PAGE_BITS)
+#define SEEPROM_BYTE_ADDR_MASK                 (SEEPROM_PHY_PAGE_SIZE-1)
+#define SEEPROM_PAGE_SIZE                      4
+#define SEEPROM_TOTAL_SIZE                     65536
+
+#define BUFFERED_FLASH_PAGE_BITS               9
+#define BUFFERED_FLASH_PHY_PAGE_SIZE           (1 << BUFFERED_FLASH_PAGE_BITS)
+#define BUFFERED_FLASH_BYTE_ADDR_MASK          (BUFFERED_FLASH_PHY_PAGE_SIZE-1)
+#define BUFFERED_FLASH_PAGE_SIZE               264
+#define BUFFERED_FLASH_TOTAL_SIZE              131072
+
+#define SAIFUN_FLASH_PAGE_BITS                 8
+#define SAIFUN_FLASH_PHY_PAGE_SIZE             (1 << SAIFUN_FLASH_PAGE_BITS)
+#define SAIFUN_FLASH_BYTE_ADDR_MASK            (SAIFUN_FLASH_PHY_PAGE_SIZE-1)
+#define SAIFUN_FLASH_PAGE_SIZE                 256
+#define SAIFUN_FLASH_BASE_TOTAL_SIZE           65536
+
+#define NVRAM_TIMEOUT_COUNT                    30000
+
+
+#define FLASH_STRAP_MASK                       (BNX2_NVM_CFG1_FLASH_MODE   | \
+                                                BNX2_NVM_CFG1_BUFFER_MODE  | \
+                                                BNX2_NVM_CFG1_PROTECT_MODE | \
+                                                BNX2_NVM_CFG1_FLASH_SIZE)
+
+struct flash_spec {
+       u32 strapping;
+       u32 config1;
+       u32 config2;
+       u32 config3;
+       u32 write1;
+       u32 buffered;
+       u32 page_bits;
+       u32 page_size;
+       u32 addr_mask;
+       u32 total_size;
+       u8  *name;
+};
+
+struct bnx2 {
+       /* Fields used in the tx and intr/napi performance paths are grouped */
+       /* together in the beginning of the structure. */
+       void __iomem            *regview;
+
+       struct net_device       *dev;
+       struct pci_dev          *pdev;
+
+       atomic_t                intr_sem;
+
+       struct status_block     *status_blk;
+       u32                     last_status_idx;
+
+       atomic_t                tx_avail_bd;
+       struct tx_bd            *tx_desc_ring;
+       struct sw_bd            *tx_buf_ring;
+       u32                     tx_prod_bseq;
+       u16                     tx_prod;
+       u16                     tx_cons;
+
+#ifdef BCM_VLAN 
+       struct                  vlan_group *vlgrp;
+#endif
+
+       u32                     rx_offset;
+       u32                     rx_buf_use_size;        /* useable size */
+       u32                     rx_buf_size;            /* with alignment */
+       struct rx_bd            *rx_desc_ring;
+       struct sw_bd            *rx_buf_ring;
+       u32                     rx_prod_bseq;
+       u16                     rx_prod;
+       u16                     rx_cons;
+
+       u32                     rx_csum;
+
+       /* Only used to synchronize netif_stop_queue/wake_queue when tx */
+       /* ring is full */
+       spinlock_t              tx_lock;
+
+       /* End of fileds used in the performance code paths. */
+
+       char                    *name;
+
+       int                     timer_interval;
+       struct                  timer_list timer;
+       struct work_struct      reset_task;
+
+       /* Used to synchronize phy accesses. */
+       spinlock_t              phy_lock;
+
+       u32                     flags;
+#define PCIX_FLAG                      1
+#define PCI_32BIT_FLAG                 2
+#define ONE_TDMA_FLAG                  4       /* no longer used */
+#define NO_WOL_FLAG                    8
+#define USING_DAC_FLAG                 0x10
+#define USING_MSI_FLAG                 0x20
+
+       u32                     phy_flags;
+#define PHY_SERDES_FLAG                        1
+#define PHY_CRC_FIX_FLAG               2
+#define PHY_PARALLEL_DETECT_FLAG       4
+#define PHY_INT_MODE_MASK_FLAG         0x300
+#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100
+#define PHY_INT_MODE_LINK_READY_FLAG   0x200
+
+       u32                     chip_id;
+       /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
+#define CHIP_NUM(bp)                   (((bp)->chip_id) & 0xffff0000)
+#define CHIP_NUM_5706                  0x57060000
+
+#define CHIP_REV(bp)                   (((bp)->chip_id) & 0x0000f000)
+#define CHIP_REV_Ax                    0x00000000
+#define CHIP_REV_Bx                    0x00001000
+#define CHIP_REV_Cx                    0x00002000
+    
+#define CHIP_METAL(bp)                 (((bp)->chip_id) & 0x00000ff0)
+#define CHIP_BONDING(bp)               (((bp)->chip_id) & 0x0000000f)
+
+#define CHIP_ID(bp)                    (((bp)->chip_id) & 0xfffffff0)
+#define CHIP_ID_5706_A0                        0x57060000
+#define CHIP_ID_5706_A1                        0x57060010
+
+#define CHIP_BOND_ID(bp)               (((bp)->chip_id) & 0xf)
+
+/* A serdes chip will have the first bit of the bond id set. */
+#define CHIP_BOND_ID_SERDES_BIT                0x01
+
+       u32                     phy_addr;
+       u32                     phy_id;
+       
+       u16                     bus_speed_mhz;
+       u8                      wol;
+
+       u8                      fw_timed_out;
+
+       u16                     fw_wr_seq;
+       u16                     fw_drv_pulse_wr_seq;
+
+       int                     tx_ring_size;
+       dma_addr_t              tx_desc_mapping;
+
+
+       int                     rx_ring_size;
+       dma_addr_t              rx_desc_mapping;
+
+       u16                     tx_quick_cons_trip;
+       u16                     tx_quick_cons_trip_int;
+       u16                     rx_quick_cons_trip;
+       u16                     rx_quick_cons_trip_int;
+       u16                     comp_prod_trip;
+       u16                     comp_prod_trip_int;
+       u16                     tx_ticks;
+       u16                     tx_ticks_int;
+       u16                     com_ticks;
+       u16                     com_ticks_int;
+       u16                     cmd_ticks;
+       u16                     cmd_ticks_int;
+       u16                     rx_ticks;
+       u16                     rx_ticks_int;
+
+       u32                     stats_ticks;
+
+       dma_addr_t              status_blk_mapping;
+
+       struct statistics_block *stats_blk;
+       dma_addr_t              stats_blk_mapping;
+
+       u32                     rx_mode;
+
+       u16                     req_line_speed;
+       u8                      req_duplex;
+
+       u8                      link_up;
+
+       u16                     line_speed;
+       u8                      duplex;
+       u8                      flow_ctrl;      /* actual flow ctrl settings */
+                                               /* may be different from     */
+                                               /* req_flow_ctrl if autoneg  */
+#define FLOW_CTRL_TX           1
+#define FLOW_CTRL_RX           2
+
+       u32                     advertising;
+
+       u8                      req_flow_ctrl;  /* flow ctrl advertisement */ 
+                                               /* settings or forced      */
+                                               /* settings                */
+       u8                      autoneg;
+#define AUTONEG_SPEED          1
+#define AUTONEG_FLOW_CTRL      2
+
+       u8                      loopback;
+#define MAC_LOOPBACK           1
+#define PHY_LOOPBACK           2
+
+       u8                      serdes_an_pending;
+#define SERDES_AN_TIMEOUT      (2 * HZ)
+
+       u8                      mac_addr[8];
+
+       u32                     fw_ver;
+
+       int                     pm_cap;
+       int                     pcix_cap;
+
+       struct net_device_stats net_stats;
+
+       struct flash_spec       *flash_info;
+};
+
+static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset);
+static void bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val);
+
+#define REG_RD(bp, offset)                                     \
+       readl(bp->regview + offset)
+
+#define REG_WR(bp, offset, val)                                        \
+       writel(val, bp->regview + offset)
+
+#define REG_WR16(bp, offset, val)                              \
+       writew(val, bp->regview + offset)
+
+#define REG_RD_IND(bp, offset)                                 \
+       bnx2_reg_rd_ind(bp, offset)
+
+#define REG_WR_IND(bp, offset, val)                            \
+       bnx2_reg_wr_ind(bp, offset, val)
+
+/* Indirect context access.  Unlike the MBQ_WR, these macros will not
+ * trigger a chip event. */
+static void bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val);
+
+#define CTX_WR(bp, cid_addr, offset, val)                      \
+       bnx2_ctx_wr(bp, cid_addr, offset, val)
+
+struct cpu_reg {
+       u32 mode;
+       u32 mode_value_halt;
+       u32 mode_value_sstep;
+
+       u32 state;
+       u32 state_value_clear;
+
+       u32 gpr0;
+       u32 evmask;
+       u32 pc;
+       u32 inst;
+       u32 bp;
+
+       u32 spad_base;
+
+       u32 mips_view_base;
+};
+
+struct fw_info {
+       u32 ver_major;
+       u32 ver_minor;
+       u32 ver_fix;
+
+       u32 start_addr;
+
+       /* Text section. */
+       u32 text_addr;
+       u32 text_len;
+       u32 text_index;
+       u32 *text;
+
+       /* Data section. */
+       u32 data_addr;
+       u32 data_len;
+       u32 data_index;
+       u32 *data;
+
+       /* SBSS section. */
+       u32 sbss_addr;
+       u32 sbss_len;
+       u32 sbss_index;
+       u32 *sbss;
+
+       /* BSS section. */
+       u32 bss_addr;
+       u32 bss_len;
+       u32 bss_index;
+       u32 *bss;
+
+       /* Read-only section. */
+       u32 rodata_addr;
+       u32 rodata_len;
+       u32 rodata_index;
+       u32 *rodata;
+};
+
+#define RV2P_PROC1                              0
+#define RV2P_PROC2                              1
+
+
+/* This value (in milliseconds) determines the frequency of the driver
+ * issuing the PULSE message code.  The firmware monitors this periodic
+ * pulse to determine when to switch to an OS-absent mode. */
+#define DRV_PULSE_PERIOD_MS                 250
+
+/* This value (in milliseconds) determines how long the driver should
+ * wait for an acknowledgement from the firmware before timing out.  Once
+ * 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                  50
+
+
+#define BNX2_DRV_RESET_SIGNATURE               0x00000000
+#define BNX2_DRV_RESET_SIGNATURE_MAGIC          0x4841564b /* HAVK */
+//#define DRV_RESET_SIGNATURE_MAGIC             0x47495352 /* RSIG */
+
+#define BNX2_DRV_MB                            0x00000004
+#define BNX2_DRV_MSG_CODE                       0xff000000
+#define BNX2_DRV_MSG_CODE_RESET                         0x01000000
+#define BNX2_DRV_MSG_CODE_UNLOAD                0x02000000
+#define BNX2_DRV_MSG_CODE_SHUTDOWN              0x03000000
+#define BNX2_DRV_MSG_CODE_SUSPEND_WOL           0x04000000
+#define BNX2_DRV_MSG_CODE_FW_TIMEOUT            0x05000000
+#define BNX2_DRV_MSG_CODE_PULSE                         0x06000000
+#define BNX2_DRV_MSG_CODE_DIAG                  0x07000000
+#define BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL        0x09000000
+
+#define BNX2_DRV_MSG_DATA                       0x00ff0000
+#define BNX2_DRV_MSG_DATA_WAIT0                         0x00010000
+#define BNX2_DRV_MSG_DATA_WAIT1                         0x00020000
+#define BNX2_DRV_MSG_DATA_WAIT2                         0x00030000
+#define BNX2_DRV_MSG_DATA_WAIT3                         0x00040000
+        
+#define BNX2_DRV_MSG_SEQ                        0x0000ffff
+
+#define BNX2_FW_MB                             0x00000008
+#define BNX2_FW_MSG_ACK                                 0x0000ffff
+#define BNX2_FW_MSG_STATUS_MASK                         0x00ff0000
+#define BNX2_FW_MSG_STATUS_OK                   0x00000000
+#define BNX2_FW_MSG_STATUS_FAILURE              0x00ff0000
+
+#define BNX2_LINK_STATUS                       0x0000000c
+
+#define BNX2_DRV_PULSE_MB                      0x00000010
+#define BNX2_DRV_PULSE_SEQ_MASK                         0x0000ffff
+
+/* Indicate to the firmware not to go into the
+ * OS absent when it is not getting driver pulse.
+ * This is used for debugging. */
+#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE       0x00010000
+
+#define BNX2_DEV_INFO_SIGNATURE                        0x00000020
+#define BNX2_DEV_INFO_SIGNATURE_MAGIC           0x44564900
+#define BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK      0xffffff00
+#define BNX2_DEV_INFO_FEATURE_CFG_VALID                 0x01
+#define BNX2_DEV_INFO_SECONDARY_PORT            0x80
+#define BNX2_DEV_INFO_DRV_ALWAYS_ALIVE          0x40
+
+#define BNX2_SHARED_HW_CFG_PART_NUM            0x00000024
+
+#define BNX2_SHARED_HW_CFG_POWER_DISSIPATED    0x00000034
+#define BNX2_SHARED_HW_CFG_POWER_STATE_D3_MASK  0xff000000
+#define BNX2_SHARED_HW_CFG_POWER_STATE_D2_MASK  0xff0000
+#define BNX2_SHARED_HW_CFG_POWER_STATE_D1_MASK  0xff00
+#define BNX2_SHARED_HW_CFG_POWER_STATE_D0_MASK  0xff
+
+#define BNX2_SHARED_HW_CFG POWER_CONSUMED      0x00000038
+#define BNX2_SHARED_HW_CFG_CONFIG              0x0000003c
+#define BNX2_SHARED_HW_CFG_DESIGN_NIC           0
+#define BNX2_SHARED_HW_CFG_DESIGN_LOM           0x1
+#define BNX2_SHARED_HW_CFG_PHY_COPPER           0
+#define BNX2_SHARED_HW_CFG_PHY_FIBER            0x2
+#define BNX2_SHARED_HW_CFG_LED_MODE_SHIFT_BITS  8
+#define BNX2_SHARED_HW_CFG_LED_MODE_MASK        0x300
+#define BNX2_SHARED_HW_CFG_LED_MODE_MAC                 0
+#define BNX2_SHARED_HW_CFG_LED_MODE_GPHY1       0x100
+#define BNX2_SHARED_HW_CFG_LED_MODE_GPHY2       0x200
+
+#define BNX2_DEV_INFO_BC_REV                   0x0000004c
+
+#define BNX2_PORT_HW_CFG_MAC_UPPER             0x00000050
+#define BNX2_PORT_HW_CFG_UPPERMAC_MASK          0xffff
+
+#define BNX2_PORT_HW_CFG_MAC_LOWER             0x00000054
+#define BNX2_PORT_HW_CFG_CONFIG                        0x00000058
+
+#define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER       0x00000068
+#define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER       0x0000006c
+#define BNX2_PORT_HW_CFG_IMD_MAC_B_UPPER       0x00000070
+#define BNX2_PORT_HW_CFG_IMD_MAC_B_LOWER       0x00000074
+#define BNX2_PORT_HW_CFG_ISCSI_MAC_UPPER       0x00000078
+#define BNX2_PORT_HW_CFG_ISCSI_MAC_LOWER       0x0000007c
+
+#define BNX2_DEV_INFO_PER_PORT_HW_CONFIG2      0x000000b4
+
+#define BNX2_DEV_INFO_FORMAT_REV               0x000000c4
+#define BNX2_DEV_INFO_FORMAT_REV_MASK           0xff000000
+#define BNX2_DEV_INFO_FORMAT_REV_ID             ('A' << 24)
+
+#define BNX2_SHARED_FEATURE                    0x000000c8
+#define BNX2_SHARED_FEATURE_MASK                0xffffffff
+
+#define BNX2_PORT_FEATURE                      0x000000d8
+#define BNX2_PORT2_FEATURE                     0x00000014c
+#define BNX2_PORT_FEATURE_WOL_ENABLED           0x01000000
+#define BNX2_PORT_FEATURE_MBA_ENABLED           0x02000000
+#define BNX2_PORT_FEATURE_ASF_ENABLED           0x04000000
+#define BNX2_PORT_FEATURE_IMD_ENABLED           0x08000000
+#define BNX2_PORT_FEATURE_BAR1_SIZE_MASK        0xf
+#define BNX2_PORT_FEATURE_BAR1_SIZE_DISABLED    0x0
+#define BNX2_PORT_FEATURE_BAR1_SIZE_64K                 0x1
+#define BNX2_PORT_FEATURE_BAR1_SIZE_128K        0x2
+#define BNX2_PORT_FEATURE_BAR1_SIZE_256K        0x3
+#define BNX2_PORT_FEATURE_BAR1_SIZE_512K        0x4
+#define BNX2_PORT_FEATURE_BAR1_SIZE_1M          0x5
+#define BNX2_PORT_FEATURE_BAR1_SIZE_2M          0x6
+#define BNX2_PORT_FEATURE_BAR1_SIZE_4M          0x7
+#define BNX2_PORT_FEATURE_BAR1_SIZE_8M          0x8
+#define BNX2_PORT_FEATURE_BAR1_SIZE_16M                 0x9
+#define BNX2_PORT_FEATURE_BAR1_SIZE_32M                 0xa
+#define BNX2_PORT_FEATURE_BAR1_SIZE_64M                 0xb
+#define BNX2_PORT_FEATURE_BAR1_SIZE_128M        0xc
+#define BNX2_PORT_FEATURE_BAR1_SIZE_256M        0xd
+#define BNX2_PORT_FEATURE_BAR1_SIZE_512M        0xe
+#define BNX2_PORT_FEATURE_BAR1_SIZE_1G          0xf
+
+#define BNX2_PORT_FEATURE_WOL                  0xdc
+#define BNX2_PORT2_FEATURE_WOL                 0x150
+#define BNX2_PORT_FEATURE_WOL_DEFAULT_SHIFT_BITS        4
+#define BNX2_PORT_FEATURE_WOL_DEFAULT_MASK      0x30
+#define BNX2_PORT_FEATURE_WOL_DEFAULT_DISABLE   0
+#define BNX2_PORT_FEATURE_WOL_DEFAULT_MAGIC     0x10
+#define BNX2_PORT_FEATURE_WOL_DEFAULT_ACPI      0x20
+#define BNX2_PORT_FEATURE_WOL_DEFAULT_MAGIC_AND_ACPI    0x30
+#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_MASK   0xf
+#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_AUTONEG        0
+#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_10HALF         1
+#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_10FULL         2
+#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_100HALF 3
+#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_100FULL 4
+#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_1000HALF       5
+#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_1000FULL       6
+#define BNX2_PORT_FEATURE_WOL_AUTONEG_ADVERTISE_1000    0x40
+#define BNX2_PORT_FEATURE_WOL_RESERVED_PAUSE_CAP 0x400
+#define BNX2_PORT_FEATURE_WOL_RESERVED_ASYM_PAUSE_CAP   0x800
+
+#define BNX2_PORT_FEATURE_MBA                  0xe0
+#define BNX2_PORT2_FEATURE_MBA                 0x154
+#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_SHIFT_BITS        0
+#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK      0x3
+#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_PXE       0
+#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_RPL       1
+#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_BOOTP     2
+#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_SHIFT_BITS     2
+#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_MASK   0x3c
+#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_AUTONEG        0
+#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_10HALF         0x4
+#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_10FULL         0x8
+#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_100HALF        0xc
+#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_100FULL        0x10
+#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_1000HALF       0x14
+#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_1000FULL       0x18
+#define BNX2_PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE       0x40
+#define BNX2_PORT_FEATURE_MBA_HOTKEY_CTRL_S     0
+#define BNX2_PORT_FEATURE_MBA_HOTKEY_CTRL_B     0x80
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT_BITS   8
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_MASK         0xff00
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_DISABLED     0
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_1K   0x100
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_2K   0x200
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_4K   0x300
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_8K   0x400
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_16K  0x500
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_32K  0x600
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_64K  0x700
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_128K         0x800
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_256K         0x900
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_512K         0xa00
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_1M   0xb00
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_2M   0xc00
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_4M   0xd00
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_8M   0xe00
+#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_16M  0xf00
+#define BNX2_PORT_FEATURE_MBA_MSG_TIMEOUT_SHIFT_BITS    16
+#define BNX2_PORT_FEATURE_MBA_MSG_TIMEOUT_MASK  0xf0000
+#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_SHIFT_BITS         20
+#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_MASK       0x300000
+#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_AUTO       0
+#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_BBS        0x100000
+#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT18H     0x200000
+#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT19H     0x300000
+
+#define BNX2_PORT_FEATURE_IMD                  0xe4
+#define BNX2_PORT2_FEATURE_IMD                 0x158
+#define BNX2_PORT_FEATURE_IMD_LINK_OVERRIDE_DEFAULT     0
+#define BNX2_PORT_FEATURE_IMD_LINK_OVERRIDE_ENABLE      1
+
+#define BNX2_PORT_FEATURE_VLAN                 0xe8
+#define BNX2_PORT2_FEATURE_VLAN                        0x15c
+#define BNX2_PORT_FEATURE_MBA_VLAN_TAG_MASK     0xffff
+#define BNX2_PORT_FEATURE_MBA_VLAN_ENABLE       0x10000
+
+#define BNX2_BC_STATE_RESET_TYPE               0x000001c0
+#define BNX2_BC_STATE_RESET_TYPE_SIG            0x00005254
+#define BNX2_BC_STATE_RESET_TYPE_SIG_MASK       0x0000ffff
+#define BNX2_BC_STATE_RESET_TYPE_NONE   (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                         0x00010000)
+#define BNX2_BC_STATE_RESET_TYPE_PCI    (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                         0x00020000)
+#define BNX2_BC_STATE_RESET_TYPE_VAUX   (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                         0x00030000)
+#define BNX2_BC_STATE_RESET_TYPE_DRV_MASK       DRV_MSG_CODE         
+#define BNX2_BC_STATE_RESET_TYPE_DRV_RESET (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                           DRV_MSG_CODE_RESET)
+#define BNX2_BC_STATE_RESET_TYPE_DRV_UNLOAD (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                            DRV_MSG_CODE_UNLOAD)
+#define BNX2_BC_STATE_RESET_TYPE_DRV_SHUTDOWN (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                              DRV_MSG_CODE_SHUTDOWN)
+#define BNX2_BC_STATE_RESET_TYPE_DRV_WOL (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                         DRV_MSG_CODE_WOL)
+#define BNX2_BC_STATE_RESET_TYPE_DRV_DIAG (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                          DRV_MSG_CODE_DIAG)
+#define BNX2_BC_STATE_RESET_TYPE_VALUE(msg) (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                            (msg))
+
+#define BNX2_BC_STATE                          0x000001c4
+#define BNX2_BC_STATE_ERR_MASK                  0x0000ff00
+#define BNX2_BC_STATE_SIGN                      0x42530000
+#define BNX2_BC_STATE_SIGN_MASK                         0xffff0000
+#define BNX2_BC_STATE_BC1_START                         (BNX2_BC_STATE_SIGN | 0x1)
+#define BNX2_BC_STATE_GET_NVM_CFG1              (BNX2_BC_STATE_SIGN | 0x2)
+#define BNX2_BC_STATE_PROG_BAR                  (BNX2_BC_STATE_SIGN | 0x3)
+#define BNX2_BC_STATE_INIT_VID                  (BNX2_BC_STATE_SIGN | 0x4)
+#define BNX2_BC_STATE_GET_NVM_CFG2              (BNX2_BC_STATE_SIGN | 0x5)
+#define BNX2_BC_STATE_APPLY_WKARND              (BNX2_BC_STATE_SIGN | 0x6)
+#define BNX2_BC_STATE_LOAD_BC2                  (BNX2_BC_STATE_SIGN | 0x7)
+#define BNX2_BC_STATE_GOING_BC2                         (BNX2_BC_STATE_SIGN | 0x8)
+#define BNX2_BC_STATE_GOING_DIAG                (BNX2_BC_STATE_SIGN | 0x9)
+#define BNX2_BC_STATE_RT_FINAL_INIT             (BNX2_BC_STATE_SIGN | 0x81)
+#define BNX2_BC_STATE_RT_WKARND                         (BNX2_BC_STATE_SIGN | 0x82)
+#define BNX2_BC_STATE_RT_DRV_PULSE              (BNX2_BC_STATE_SIGN | 0x83)
+#define BNX2_BC_STATE_RT_FIOEVTS                (BNX2_BC_STATE_SIGN | 0x84)
+#define BNX2_BC_STATE_RT_DRV_CMD                (BNX2_BC_STATE_SIGN | 0x85)
+#define BNX2_BC_STATE_RT_LOW_POWER              (BNX2_BC_STATE_SIGN | 0x86)
+#define BNX2_BC_STATE_RT_SET_WOL                (BNX2_BC_STATE_SIGN | 0x87)
+#define BNX2_BC_STATE_RT_OTHER_FW               (BNX2_BC_STATE_SIGN | 0x88)
+#define BNX2_BC_STATE_RT_GOING_D3               (BNX2_BC_STATE_SIGN | 0x89)
+#define BNX2_BC_STATE_ERR_BAD_VERSION           (BNX2_BC_STATE_SIGN | 0x0100)
+#define BNX2_BC_STATE_ERR_BAD_BC2_CRC           (BNX2_BC_STATE_SIGN | 0x0200)
+#define BNX2_BC_STATE_ERR_BC1_LOOP              (BNX2_BC_STATE_SIGN | 0x0300)
+#define BNX2_BC_STATE_ERR_UNKNOWN_CMD           (BNX2_BC_STATE_SIGN | 0x0400)
+#define BNX2_BC_STATE_ERR_DRV_DEAD              (BNX2_BC_STATE_SIGN | 0x0500)
+#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_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 HOST_VIEW_SHMEM_BASE                   0x167c00
+
+#endif
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
new file mode 100644 (file)
index 0000000..35f3a2a
--- /dev/null
@@ -0,0 +1,2468 @@
+/* bnx2_fw.h: Broadcom NX2 network driver.
+ *
+ * Copyright (c) 2004, 2005 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, except as noted below.
+ *
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004, 2005 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
+
+
+static int bnx2_COM_b06FwReleaseMajor = 0x0;
+static int bnx2_COM_b06FwReleaseMinor = 0x0;
+static int bnx2_COM_b06FwReleaseFix = 0x0;
+static u32 bnx2_COM_b06FwStartAddr = 0x080004a0;
+static u32 bnx2_COM_b06FwTextAddr = 0x08000000;
+static int bnx2_COM_b06FwTextLen = 0x4594;
+static u32 bnx2_COM_b06FwDataAddr = 0x080045e0;
+static int bnx2_COM_b06FwDataLen = 0x0;
+static u32 bnx2_COM_b06FwRodataAddr = 0x08004598;
+static int bnx2_COM_b06FwRodataLen = 0x18;
+static u32 bnx2_COM_b06FwBssAddr = 0x08004600;
+static int bnx2_COM_b06FwBssLen = 0x88;
+static u32 bnx2_COM_b06FwSbssAddr = 0x080045e0;
+static int bnx2_COM_b06FwSbssLen = 0x1c;
+static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = {
+       0x0a000128, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x302e362e,
+       0x39000000, 0x00060902, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
+       0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000010, 0x000003e8, 0x0000ea60, 0x00000001, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x0000ffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000002, 0x00000020, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d,
+       0x0000000d, 0x3c020800, 0x244245e0, 0x3c030800, 0x24634688, 0xac400000,
+       0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021,
+       0x3c100800, 0x261004a0, 0x3c1c0800, 0x279c45e0, 0x0e0001f2, 0x00000000,
+       0x0000000d, 0x27bdffe8, 0x3c1a8000, 0x3c020008, 0x0342d825, 0x3c036010,
+       0xafbf0010, 0x8c655000, 0x3c020800, 0x24470ac8, 0x3c040800, 0x24864600,
+       0x2402ff7f, 0x00a22824, 0x34a5380c, 0xac655000, 0x00002821, 0x24020037,
+       0x24030c80, 0xaf420008, 0xaf430024, 0xacc70000, 0x24a50001, 0x2ca20016,
+       0x1440fffc, 0x24c60004, 0x24844600, 0x3c020800, 0x24420ad4, 0x3c030800,
+       0x246309d4, 0xac820004, 0x3c020800, 0x24420618, 0x3c050800, 0x24a50ca0,
+       0xac82000c, 0x3c020800, 0x24423100, 0xac830008, 0x3c030800, 0x246325c8,
+       0xac820014, 0x3c020800, 0x24422b0c, 0xac830018, 0xac83001c, 0x3c030800,
+       0x24630adc, 0xac820024, 0x3c020800, 0x24423040, 0xac83002c, 0x3c030800,
+       0x24633060, 0xac820030, 0x3c020800, 0x24422f6c, 0xac830034, 0x3c030800,
+       0x24632c60, 0xac82003c, 0x3c020800, 0x24420b6c, 0xac850010, 0xac850020,
+       0xac830040, 0x0e000bd6, 0xac820050, 0x8fbf0010, 0x03e00008, 0x27bd0018,
+       0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014, 0x9203000b,
+       0x24020003, 0x1462005b, 0x96110008, 0x32220001, 0x10400009, 0x27430080,
+       0x8e020000, 0x96040014, 0x000211c2, 0x00021040, 0x00621821, 0xa4640000,
+       0x0a0001cb, 0x3c020800, 0x3c020800, 0x8c430020, 0x1060002a, 0x3c030800,
+       0x0e001006, 0x00000000, 0x97420108, 0x8f850018, 0x9743010c, 0x3042003e,
+       0x00021400, 0x00621825, 0xaca30000, 0x8f840018, 0x8f420100, 0xac820004,
+       0x97430116, 0x9742010e, 0x8f840018, 0x00031c00, 0x00431025, 0xac820008,
+       0x97430110, 0x97440112, 0x8f850018, 0x00031c00, 0x00832025, 0xaca4000c,
+       0x97420114, 0x8f840018, 0x3042ffff, 0xac820010, 0x8f830018, 0xac600014,
+       0x8f820018, 0x3c030800, 0xac400018, 0x9462466e, 0x8f840018, 0x3c032000,
+       0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x3c030800, 0x8c620040,
+       0x24420001, 0xac620040, 0x3c020800, 0x8c430044, 0x32240004, 0x24630001,
+       0x10800017, 0xac430044, 0x8f4202b8, 0x04430007, 0x8e020020, 0x3c040800,
+       0x8c830060, 0x24020001, 0x24630001, 0x0a0001ed, 0xac830060, 0x3c060800,
+       0x8cc4005c, 0xaf420280, 0x96030016, 0x00001021, 0xa7430284, 0x8e050004,
+       0x24840001, 0x3c031000, 0xaf450288, 0xaf4302b8, 0x0a0001ed, 0xacc4005c,
+       0x32220002, 0x0a0001ed, 0x0002102b, 0x3c026000, 0xac400808, 0x0000000d,
+       0x00001021, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+       0x27bdffc8, 0xafbf0034, 0xafbe0030, 0xafb7002c, 0xafb60028, 0xafb50024,
+       0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0x0e00013f, 0xafb00010,
+       0x24110020, 0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800,
+       0x3c170800, 0x3c160800, 0x8f820004, 0x3c040800, 0x8c830020, 0x10430004,
+       0x00000000, 0xaf830004, 0x0e00110b, 0x00000000, 0x8f500000, 0x32020007,
+       0x1040fff5, 0x32020001, 0x1040002b, 0x32020002, 0x8f420100, 0xaf420020,
+       0x8f430104, 0xaf4300a8, 0x9342010b, 0x93630000, 0x306300ff, 0x10710005,
+       0x304400ff, 0x10750006, 0x2c820016, 0x0a000227, 0x00000000, 0xaf940000,
+       0x0a000228, 0x2c820016, 0xaf930000, 0x0a000228, 0x00000000, 0xaf800000,
+       0x14400005, 0x00041880, 0x0e0002b2, 0x00000000, 0x0a000234, 0x00000000,
+       0x3c020800, 0x24424600, 0x00621821, 0x8c620000, 0x0040f809, 0x00000000,
+       0x10400005, 0x8fc20034, 0x8f420104, 0x3c016020, 0xac220014, 0x8fc20034,
+       0xaf520138, 0x24420001, 0xafc20034, 0x32020002, 0x10400019, 0x32020004,
+       0x8f420140, 0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000,
+       0x10750006, 0x00000000, 0x0a000250, 0x00000000, 0xaf940000, 0x0a000251,
+       0x00000000, 0xaf930000, 0x0a000251, 0x00000000, 0xaf800000, 0x0e0008b9,
+       0x00000000, 0x8ee20038, 0xaf520178, 0x24420001, 0xaee20038, 0x32020004,
+       0x1040ffad, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff,
+       0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a00026a, 0x00000000,
+       0xaf940000, 0x0a00026b, 0x00000000, 0xaf930000, 0x0a00026b, 0x00000000,
+       0xaf800000, 0x93620000, 0x14510004, 0x8ec2003c, 0x0e000835, 0x00000000,
+       0x8ec2003c, 0xaf5201b8, 0x24420001, 0x0a000206, 0xaec2003c, 0x27bdffe8,
+       0xafbf0010, 0x97420108, 0x24033000, 0x30447000, 0x10830012, 0x28823001,
+       0x10400007, 0x24024000, 0x1080000b, 0x24022000, 0x1082001a, 0x24020001,
+       0x0a000299, 0x00000000, 0x1082000c, 0x24025000, 0x1082000e, 0x00000000,
+       0x0a000299, 0x00000000, 0x0000000d, 0x0a00029b, 0x00001021, 0x0e000300,
+       0x00000000, 0x0a00029b, 0x00001021, 0x0e00048f, 0x00000000, 0x0a00029b,
+       0x00001021, 0x0e000fdf, 0x00000000, 0x0a00029b, 0x00001021, 0x0000000d,
+       0x00001021, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x93620000, 0x24030020,
+       0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0002af,
+       0x00000000, 0x2782000c, 0xaf820000, 0x03e00008, 0x00000000, 0x27820008,
+       0xaf820000, 0x03e00008, 0x00000000, 0xaf800000, 0x03e00008, 0x00000000,
+       0x0000000d, 0x03e00008, 0x00001021, 0x03e00008, 0x00001021, 0x27440100,
+       0x94830008, 0x30620004, 0x10400017, 0x30620002, 0x8f4202b8, 0x04430007,
+       0x8c820020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001, 0x03e00008,
+       0xac830060, 0xaf420280, 0x94830016, 0x3c060800, 0xa7430284, 0x8c850004,
+       0x8cc4005c, 0x00001021, 0x3c031000, 0x24840001, 0xaf450288, 0xaf4302b8,
+       0x03e00008, 0xacc4005c, 0x14400003, 0x3c040800, 0x03e00008, 0x00001021,
+       0x8c830084, 0x24020001, 0x24630001, 0x03e00008, 0xac830084, 0x27450100,
+       0x3c040800, 0x8c820088, 0x94a3000c, 0x24420001, 0x007a1821, 0xac820088,
+       0x8ca40018, 0x90664000, 0xaf440038, 0x8ca2001c, 0x2403fff8, 0x00063600,
+       0x00431024, 0x34420004, 0x3c030005, 0xaf42003c, 0xaf430030, 0x00000000,
+       0x00000000, 0x00000000, 0xaf460404, 0x00000000, 0x00000000, 0x00000000,
+       0x3c020006, 0x34420001, 0xaf420030, 0x00000000, 0x00000000, 0x00000000,
+       0x8f420000, 0x30420010, 0x1040fffd, 0x00001021, 0x03e00008, 0x00000000,
+       0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x1060001e,
+       0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000,
+       0x8f840018, 0x9602000c, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018,
+       0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018,
+       0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e,
+       0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c,
+       0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffc8, 0xafb3001c,
+       0x00009821, 0xafb7002c, 0x0000b821, 0xafbe0030, 0x0000f021, 0xafb50024,
+       0x27550100, 0xafbf0034, 0xafb60028, 0xafb40020, 0xafb20018, 0xafb10014,
+       0xafb00010, 0x96a20008, 0x8f540100, 0x8eb20018, 0x30420001, 0x10400037,
+       0x02a0b021, 0x8f630054, 0x2642ffff, 0x00431023, 0x18400006, 0x00000000,
+       0x0000000d, 0x00000000, 0x24000128, 0x0a000372, 0x00002021, 0x8f62004c,
+       0x02421023, 0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800,
+       0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b,
+       0xac62008c, 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122,
+       0x30420001, 0x00021023, 0x30420005, 0x0a000372, 0x34440004, 0x27660100,
+       0x00041080, 0x00c21021, 0x8c430000, 0x02431823, 0x04600004, 0x24820001,
+       0x30440007, 0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121,
+       0x8c620094, 0x24040005, 0x24420001, 0x0a000372, 0xac620094, 0x24040004,
+       0x00809821, 0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010,
+       0x2c420001, 0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001,
+       0x38820014, 0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012,
+       0x14820002, 0x00001021, 0x24020001, 0x50400007, 0x8eb10020, 0x8ea20020,
+       0x8f630040, 0x00408821, 0x00431023, 0x5c400001, 0x8f710040, 0x9343010b,
+       0x24020004, 0x54620005, 0x36730080, 0x96a20008, 0x36730002, 0x24170001,
+       0x305e0020, 0x2402fffb, 0x02628024, 0x1200002a, 0x3c030800, 0x8c620030,
+       0x02021024, 0x10400026, 0x3c020800, 0x8c430020, 0x10600024, 0x32620004,
+       0x0e001006, 0x00000000, 0x8f830018, 0x8f420100, 0xac620000, 0x8f840018,
+       0x02201821, 0x32620002, 0xac900004, 0x8f840018, 0x50400001, 0x8ec30014,
+       0xac830008, 0x8f830018, 0x8ec20020, 0xac62000c, 0x8f840018, 0x8f620040,
+       0xac820010, 0x8f830018, 0x8ec20018, 0xac620014, 0x8f840018, 0x3c026000,
+       0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024010,
+       0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x32620004, 0x10400076,
+       0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02821025, 0xa360007c,
+       0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
+       0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c,
+       0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff,
+       0x93620023, 0x3042007f, 0xa3620023, 0xaf720064, 0x3c023fff, 0x0a0003f1,
+       0x3442ffff, 0x8f62005c, 0x02421023, 0x04400011, 0x00000000, 0x8f65005c,
+       0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf720064, 0x00a32823,
+       0x00852821, 0x0045102b, 0x10400004, 0x02451021, 0x3c053fff, 0x34a5ffff,
+       0x02451021, 0xaf62005c, 0x24070001, 0xaf72004c, 0x8f620054, 0x16420005,
+       0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a,
+       0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800,
+       0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021,
+       0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074,
+       0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001,
+       0x02821025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
+       0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000,
+       0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+       0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02821025,
+       0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
+       0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x8ea30014, 0x8f620040,
+       0x14430003, 0x00431023, 0x0a000443, 0x00001021, 0x28420001, 0x10400034,
+       0x00000000, 0x8f620040, 0xaf630040, 0x9362003e, 0x30420001, 0x1440000b,
+       0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022, 0x3c020800,
+       0x8c440098, 0x0064182b, 0x1460001e, 0x3c020800, 0x3c029000, 0x34420001,
+       0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+       0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02831825,
+       0x34420001, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd,
+       0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0x24020001, 0xaf4301f8,
+       0xa7620012, 0x0a000476, 0xa3600022, 0x9743007a, 0x9444002a, 0x00641821,
+       0x3063fffe, 0xa7630012, 0x0e000b68, 0x00000000, 0x12e00003, 0x00000000,
+       0x0e000f27, 0x00000000, 0x53c00004, 0x96a20008, 0x0e000c10, 0x00000000,
+       0x96a20008, 0x8fbf0034, 0x8fbe0030, 0x8fb7002c, 0x8fb60028, 0x8fb50024,
+       0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042,
+       0x30420001, 0x03e00008, 0x27bd0038, 0x27bdffe8, 0xafbf0010, 0x97420108,
+       0x2403000b, 0x304400ff, 0x1083004e, 0x2882000c, 0x10400011, 0x24020006,
+       0x1082003e, 0x28820007, 0x10400007, 0x28820008, 0x1080002b, 0x24020001,
+       0x1082002e, 0x3c026000, 0x0a000504, 0x00000000, 0x14400061, 0x2882000a,
+       0x1440002b, 0x00000000, 0x0a0004ec, 0x00000000, 0x2402001c, 0x1082004e,
+       0x2882001d, 0x1040000e, 0x24020019, 0x10820041, 0x2882001a, 0x10400005,
+       0x2402000e, 0x10820036, 0x00000000, 0x0a000504, 0x00000000, 0x2402001b,
+       0x1082003c, 0x00000000, 0x0a000504, 0x00000000, 0x240200c1, 0x10820040,
+       0x288200c2, 0x10400005, 0x24020080, 0x1082001f, 0x00000000, 0x0a000504,
+       0x00000000, 0x240200c2, 0x1082003b, 0x00000000, 0x0a000504, 0x00000000,
+       0x3c026000, 0x0e000c7d, 0xac400808, 0x0a000506, 0x8fbf0010, 0x8c444448,
+       0x3c030800, 0xac640064, 0x0e000c7d, 0x00000000, 0x3c026000, 0x8c444448,
+       0x3c030800, 0x0a000505, 0xac640068, 0x8f440100, 0x0e000508, 0x00000000,
+       0x3c026000, 0x8c444448, 0x3c030800, 0x0a000505, 0xac64006c, 0x0e000cab,
+       0x00000000, 0x0a000506, 0x8fbf0010, 0x8f440100, 0x0e000cd5, 0x00000000,
+       0x0a000506, 0x8fbf0010, 0x0e000d1c, 0x00000000, 0x0a000506, 0x8fbf0010,
+       0x0000000d, 0x0a000506, 0x8fbf0010, 0x0e0005d7, 0x00000000, 0x0a000506,
+       0x8fbf0010, 0x8f440100, 0x0e000d7e, 0x00000000, 0x0a000506, 0x8fbf0010,
+       0x0e000e95, 0x00000000, 0x0a000506, 0x8fbf0010, 0x0e000626, 0x00000000,
+       0x0a000506, 0x8fbf0010, 0x0e000b68, 0x00000000, 0x0a000506, 0x8fbf0010,
+       0x0000000d, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c029000,
+       0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000, 0xafbf0014,
+       0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005,
+       0x34420001, 0xa3620005, 0x8f63004c, 0x8f620054, 0x10620019, 0x3c028000,
+       0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081,
+       0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
+       0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021,
+       0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000,
+       0x34420001, 0x02021025, 0x0e000c7d, 0xaf420020, 0x3c029000, 0x34420001,
+       0x3c038000, 0x02021025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
+       0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02021025, 0xa363007d,
+       0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x8fbf0014, 0xaf5001c0,
+       0x8fb00010, 0x24020002, 0x3c031000, 0xa34201c4, 0xaf4301f8, 0x03e00008,
+       0x27bd0018, 0x27bdffd8, 0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014,
+       0xafb00010, 0x93630005, 0x00809021, 0x24020030, 0x30630030, 0x14620072,
+       0x00a09821, 0x3c020800, 0x8c430020, 0x1060006c, 0x00000000, 0x0e001006,
+       0x00000000, 0x8f820018, 0xac520000, 0x9363003e, 0x9362003f, 0x8f840018,
+       0x00031a00, 0x00431025, 0xac820004, 0x93630081, 0x93620082, 0x8f850018,
+       0x00031e00, 0x00021400, 0x00621825, 0xaca30008, 0x8f840018, 0x8f620040,
+       0xac82000c, 0x8f830018, 0x8f620048, 0xac620010, 0x8f840018, 0x8f62004c,
+       0x3c110800, 0xac820014, 0x8f830018, 0x8f620050, 0x26304660, 0x00002021,
+       0xac620018, 0x9602000e, 0x8f850018, 0x3c03c00b, 0x00431025, 0x0e001044,
+       0xaca2001c, 0x8f830018, 0x8f620054, 0xac620000, 0x8f840018, 0x8f620058,
+       0xac820004, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f840018, 0x8f620060,
+       0xac82000c, 0x8f850018, 0x8f620064, 0xaca20010, 0x97630068, 0x9762006a,
+       0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f830018, 0x00002021,
+       0xac600018, 0x9602000e, 0x8f850018, 0x3c03c00c, 0x00431025, 0x0e001044,
+       0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000, 0x936200c4, 0x30420002,
+       0x10400006, 0x00000000, 0x976200c8, 0x8f830018, 0x3042ffff, 0x0a0005b5,
+       0xac620004, 0x8f820018, 0xac400004, 0x8f830018, 0x8f62006c, 0xac620008,
+       0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018, 0xac600010, 0x93620005,
+       0x8f830018, 0x00021600, 0x00531025, 0xac620014, 0x8f850018, 0x3c026000,
+       0x8c434448, 0x24040001, 0x26224660, 0xaca30018, 0x9443000e, 0x8f850018,
+       0x3c02400d, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x02402021,
+       0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
+       0x27bd0028, 0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014,
+       0x9603000c, 0x240200c1, 0x5462001d, 0x8e040000, 0x3c029000, 0x8f440100,
+       0x34420001, 0x3c038000, 0x00821025, 0xaf420020, 0x8f420020, 0x00431024,
+       0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c058000,
+       0x00831825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00451024,
+       0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0, 0xa34201c4, 0xaf4301f8,
+       0x0a000622, 0x8fbf0018, 0x8f65004c, 0x24060001, 0x0e000db5, 0x2407049f,
+       0x3c020800, 0x8c430020, 0x9611000c, 0x1060001d, 0x8e100000, 0x0e001006,
+       0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004,
+       0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+       0x8f840018, 0x240204a2, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
+       0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019,
+       0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
+       0x03e00008, 0x27bd0020, 0x27bdffb0, 0xafb1002c, 0x27510100, 0xafbf004c,
+       0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038, 0xafb30034,
+       0xafb20030, 0xafb00028, 0x8e350000, 0x9634000c, 0x3c026000, 0x8c434448,
+       0x0000f021, 0xaf630170, 0x8f620040, 0x8e230014, 0x0000b821, 0x00431023,
+       0x044001ec, 0x0000b021, 0x32820010, 0x1040002e, 0x3c026000, 0x9363003f,
+       0x9222000e, 0x10430006, 0x2402000c, 0x9223000f, 0x10620003, 0x24020014,
+       0x14620025, 0x3c026000, 0x32820004, 0x10400007, 0x241e0001, 0x8f620050,
+       0x24420001, 0xaf620050, 0x8f630054, 0x24630001, 0xaf630054, 0x32830102,
+       0x24020002, 0x5462000d, 0x9222000f, 0x8f620040, 0x24420001, 0xaf620040,
+       0x8f630048, 0x8f620040, 0x24630001, 0x54620005, 0x9222000f, 0x8f620048,
+       0x24420001, 0xaf620048, 0x9222000f, 0xa362003f, 0x9223000f, 0x24020012,
+       0x14620007, 0x3c026000, 0x3c030800, 0x8c620074, 0x24420001, 0x0e000f6e,
+       0xac620074, 0x3c026000, 0x8c434448, 0x32820040, 0xaf630174, 0x32830020,
+       0xafa30010, 0x32830080, 0xafa30014, 0x32830001, 0xafa3001c, 0x32830008,
+       0xafa30020, 0x32830100, 0x104000bb, 0xafa30018, 0x8e260010, 0x8f630054,
+       0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000,
+       0x24000128, 0x0a0006b2, 0x00009021, 0x8f62004c, 0x00c21023, 0x18400028,
+       0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff,
+       0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c, 0x3c040800,
+       0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023,
+       0x30420005, 0x0a0006b2, 0x34520004, 0x27670100, 0x00041080, 0x00e21021,
+       0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9,
+       0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24120005,
+       0x24420001, 0x0a0006b2, 0xac620094, 0x24120004, 0x32420001, 0x10400020,
+       0x3c020800, 0x8c430020, 0x8e300000, 0x1060001c, 0x8e330010, 0x0e001006,
+       0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004,
+       0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+       0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+       0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024010, 0x00621825,
+       0x0e001044, 0xaca3001c, 0x32420004, 0x10400060, 0x00003821, 0x3c029000,
+       0x8e260010, 0x34420001, 0x3c038000, 0x02a21025, 0xa360007c, 0xaf420020,
+       0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x30420080,
+       0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064,
+       0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023,
+       0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff, 0x0a000702, 0x3442ffff,
+       0x8f62005c, 0x00c21023, 0x04400011, 0x00000000, 0x8f65005c, 0x8f630064,
+       0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064, 0x00a32823, 0x00852821,
+       0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff, 0x34a5ffff, 0x00c51021,
+       0xaf62005c, 0x24070001, 0xaf66004c, 0x8f620054, 0x14c20005, 0x00000000,
+       0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a, 0x00022880,
+       0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c,
+       0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800,
+       0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe,
+       0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001, 0x02a21025,
+       0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620005, 0x00e0b021,
+       0x0e000f2a, 0x00000000, 0x00403821, 0x00e0b021, 0x8fa20010, 0x10400008,
+       0x00000000, 0x8e220018, 0xaf620018, 0x8e23001c, 0xaf63001c, 0x8e220020,
+       0x24160001, 0xaf620058, 0x13c00036, 0x32820004, 0x10400035, 0x8fa30014,
+       0x93620023, 0x30420040, 0x10400031, 0x3c020800, 0x8c430020, 0x1060001c,
+       0x8e300000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018,
+       0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018,
+       0xac400010, 0x8f830018, 0x24020587, 0xac620014, 0x8f850018, 0x3c026000,
+       0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
+       0x3c024019, 0x00621825, 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001,
+       0x02a21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+       0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001, 0x02a21025,
+       0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30014, 0x10600012, 0x8fa3001c,
+       0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a, 0x1462000b,
+       0x8fa3001c, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b, 0x14400005,
+       0x8fa3001c, 0x0e000f2a, 0x00000000, 0x02c2b025, 0x8fa3001c, 0x3062ffff,
+       0x10400003, 0x32820200, 0x0a000793, 0x24170004, 0x10400003, 0x00000000,
+       0x24170040, 0x24160001, 0x13c0005d, 0x32820002, 0x1040005c, 0x8fa20020,
+       0x9222000a, 0x30420020, 0x10400033, 0x3c100800, 0x93620023, 0x30420040,
+       0x1040002f, 0x8e020020, 0x1040001e, 0x3c029000, 0x0e001006, 0x00000000,
+       0x8f820018, 0xac550000, 0x8f840018, 0x3c02008d, 0xac820004, 0x8f830018,
+       0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018,
+       0x240205bf, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+       0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825,
+       0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02a21025, 0xaf420020,
+       0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
+       0x3c028000, 0x34420001, 0x02a21025, 0x306300bf, 0xa3630023, 0xaf420020,
+       0x8e020020, 0x10400023, 0x8fa20020, 0x0e001006, 0x00000000, 0x8f840018,
+       0x8e230000, 0xac830000, 0x9222000a, 0x8f830018, 0x00021600, 0xac620004,
+       0x8f840018, 0x8f620040, 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c,
+       0x9362003f, 0x8f840018, 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000,
+       0xac600014, 0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
+       0x9443466e, 0x8f850018, 0x3c02401a, 0x00621825, 0x0e001044, 0xaca3001c,
+       0x8fa20020, 0x1040000e, 0x8fa20018, 0x9222000a, 0xa3620082, 0x56e00005,
+       0x36f70008, 0x8fa30018, 0x10600004, 0x00000000, 0x36f70008, 0x0a000801,
+       0x24160001, 0x0e000de1, 0x02a02021, 0x8fa20018, 0x10400003, 0x00000000,
+       0x36f70010, 0x24160001, 0x12c00019, 0x3c029000, 0x34420001, 0x02a21025,
+       0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+       0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02a31825, 0x02e21025,
+       0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
+       0x3c031000, 0xaf5501c0, 0xa34201c4, 0xaf4301f8, 0x9363003f, 0x24020012,
+       0x14620004, 0x3c026000, 0x0e000f6e, 0x00000000, 0x3c026000, 0x8c434448,
+       0xaf630178, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c,
+       0x8fb40038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x03e00008,
+       0x27bd0050, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f500180, 0x97420184,
+       0x30420200, 0x14400015, 0x00000000, 0x8f430188, 0x3c02ff00, 0x00621824,
+       0x3c020200, 0x10620031, 0x0043102b, 0x14400007, 0x3c020300, 0x1060000b,
+       0x3c020100, 0x1062000d, 0x00000000, 0x0a0008b4, 0x00000000, 0x10620027,
+       0x3c020400, 0x1062003e, 0x02002021, 0x0a0008b4, 0x00000000, 0x0e000e1e,
+       0x02002021, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e,
+       0x8fbf0014, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000,
+       0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000,
+       0x34630001, 0x02031825, 0x34420020, 0xa3620005, 0xaf430020, 0x93620005,
+       0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000553,
+       0x24055854, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f,
+       0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020,
+       0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c048000, 0x3c030800,
+       0x304200fe, 0xa3620005, 0x8c620020, 0x34840001, 0x02042025, 0xaf440020,
+       0x1040002d, 0x8fbf0014, 0x0a000894, 0x00000000, 0x00002821, 0x00003021,
+       0x0e000f78, 0x240706a4, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014,
+       0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f,
+       0x8f840018, 0x00031a00, 0x00431025, 0xac820004, 0x8f830018, 0xac600008,
+       0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014,
+       0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
+       0x9443466e, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e001044, 0xaca3001c,
+       0x0a0008b6, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008,
+       0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93420148, 0x2444ffff, 0x2c830005,
+       0x10600047, 0x3c020800, 0x24424598, 0x00041880, 0x00621821, 0x8c640000,
+       0x00800008, 0x00000000, 0x8f430144, 0x8f62000c, 0x14620006, 0x24020001,
+       0xaf62000c, 0x0e000909, 0x00000000, 0x0a000907, 0x8fbf0010, 0x8f62000c,
+       0x0a000900, 0x00000000, 0x97630010, 0x8f420144, 0x14430006, 0x24020001,
+       0xa7620010, 0x0e000eeb, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620010,
+       0x0a000900, 0x00000000, 0x97630012, 0x8f420144, 0x14430006, 0x24020001,
+       0xa7620012, 0x0e000f06, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620012,
+       0x0a000900, 0x00000000, 0x97630014, 0x8f420144, 0x14430006, 0x24020001,
+       0xa7620014, 0x0e000f21, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620014,
+       0x0a000900, 0x00000000, 0x97630016, 0x8f420144, 0x14430006, 0x24020001,
+       0xa7620016, 0x0e000f24, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620016,
+       0x14400006, 0x8fbf0010, 0x3c030800, 0x8c620070, 0x24420001, 0xac620070,
+       0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93620081,
+       0x3c030800, 0x8c640048, 0x0044102b, 0x14400028, 0x3c029000, 0x8f460140,
+       0x34420001, 0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024,
+       0x1440fffd, 0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000,
+       0x24020012, 0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082,
+       0xaf440020, 0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000,
+       0x9362007d, 0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d,
+       0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000,
+       0x0a00096d, 0xaf4601c0, 0x93620081, 0x24420001, 0x0e000f2a, 0xa3620081,
+       0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001, 0x97630068,
+       0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b,
+       0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001,
+       0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c,
+       0x10e0001a, 0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025,
+       0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000,
+       0x9362007d, 0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d,
+       0xaf430020, 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000,
+       0xaf4401c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018,
+       0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024, 0xafb40020, 0xafb20018,
+       0xafb10014, 0xafb00010, 0x96620008, 0x3c140800, 0x8f520100, 0x30420001,
+       0x104000cf, 0x00000000, 0x8e700018, 0x8f630054, 0x2602ffff, 0x00431023,
+       0x18400006, 0x00000000, 0x0000000d, 0x00000000, 0x24000128, 0x0a0009b6,
+       0x00008821, 0x8f62004c, 0x02021023, 0x18400028, 0x00008821, 0x93650120,
+       0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff,
+       0x00803821, 0x1485000b, 0xac62008c, 0x3c040800, 0x8c830090, 0x24630001,
+       0xac830090, 0x93620122, 0x30420001, 0x00021023, 0x30420005, 0x0a0009b6,
+       0x34510004, 0x27660100, 0x00041080, 0x00c21021, 0x8c430000, 0x02031823,
+       0x04600004, 0x24820001, 0x30440007, 0x1485fff9, 0x00041080, 0x10870007,
+       0x3c030800, 0xa3640121, 0x8c620094, 0x24110005, 0x24420001, 0x0a0009b6,
+       0xac620094, 0x24110004, 0x32220001, 0x1040001e, 0x8e820020, 0x1040001d,
+       0x32220004, 0x0e001006, 0x00000000, 0x8f820018, 0xac520000, 0x8f840018,
+       0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
+       0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000,
+       0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
+       0x3c024010, 0x00621825, 0x0e001044, 0xaca3001c, 0x32220004, 0x10400076,
+       0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02421025, 0xa360007c,
+       0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
+       0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c,
+       0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff,
+       0x93620023, 0x3042007f, 0xa3620023, 0xaf700064, 0x3c023fff, 0x0a000a03,
+       0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011, 0x00000000, 0x8f65005c,
+       0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf700064, 0x00a32823,
+       0x00852821, 0x0045102b, 0x10400004, 0x02051021, 0x3c053fff, 0x34a5ffff,
+       0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c, 0x8f620054, 0x16020005,
+       0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a,
+       0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800,
+       0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021,
+       0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074,
+       0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001,
+       0x02421025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
+       0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000,
+       0x34420001, 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+       0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02421025,
+       0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
+       0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b, 0x8e830020,
+       0x27500100, 0x38420006, 0x10600029, 0x2c510001, 0x0e001006, 0x00000000,
+       0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x96020008, 0xac820004,
+       0x8f830018, 0x8e020014, 0xac620008, 0x8f850018, 0x3c026000, 0x8c434448,
+       0xaca3000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f850018, 0x8e030020,
+       0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400, 0x00431025,
+       0xac820018, 0x12200005, 0x3c020800, 0x9443466e, 0x8f840018, 0x0a000a78,
+       0x3c024013, 0x9443466e, 0x8f840018, 0x3c024014, 0x00621825, 0xac83001c,
+       0x0e001044, 0x24040001, 0x8e630014, 0x8f620040, 0x14430003, 0x00431023,
+       0x0a000a83, 0x00001021, 0x28420001, 0x10400034, 0x00000000, 0x8f620040,
+       0xaf630040, 0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022,
+       0x24420001, 0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b,
+       0x1460001e, 0x3c020800, 0x3c029000, 0x34420001, 0x02421025, 0xaf420020,
+       0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000,
+       0x9362007d, 0x34630001, 0x3c048000, 0x02431825, 0x34420001, 0xa362007d,
+       0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000,
+       0xaf5201c0, 0xa34201c4, 0x24020001, 0xaf4301f8, 0xa7620012, 0x0a000ab6,
+       0xa3600022, 0x9743007a, 0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012,
+       0x0e000b68, 0x00000000, 0x97420108, 0x8fbf0024, 0x8fb40020, 0x8fb3001c,
+       0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042, 0x30420001, 0x03e00008,
+       0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020, 0xafb00010,
+       0x27500100, 0xafbf001c, 0x10400046, 0xafb10014, 0x0e001006, 0x00000000,
+       0x8f840018, 0x8e020000, 0xac820000, 0x936300b1, 0x936200c5, 0x8f850018,
+       0x00031e00, 0x00021400, 0x34420100, 0x00621825, 0xaca30004, 0x8f840018,
+       0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048, 0xac62000c, 0x8f840018,
+       0x96020012, 0xac820010, 0x8f830018, 0x8f620040, 0x24040001, 0xac620014,
+       0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800, 0x24514660, 0xaca30018,
+       0x9623000e, 0x8f850018, 0x3c024016, 0x00621825, 0x0e001044, 0xaca3001c,
+       0x96030008, 0x30630010, 0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000,
+       0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018, 0xac600004,
+       0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+       0x8f830018, 0xac600014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001,
+       0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015, 0x00431025, 0x0e001044,
+       0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
+       0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020,
+       0xafb00010, 0x27500100, 0xafbf001c, 0x10400041, 0xafb10014, 0x0e001006,
+       0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x24020100,
+       0xac820004, 0x8f830018, 0x8e02001c, 0xac620008, 0x8f840018, 0x8e020018,
+       0xac82000c, 0x8f830018, 0x96020012, 0xac620010, 0x8f840018, 0x96020008,
+       0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
+       0x24514660, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024017, 0x00621825,
+       0x0e001044, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020,
+       0x1040001a, 0x8e100000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000,
+       0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c,
+       0x8f820018, 0xac400010, 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000,
+       0x8c634448, 0x24040001, 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015,
+       0x00431025, 0x0e001044, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018,
+       0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010,
+       0x936200c4, 0x30420002, 0x10400019, 0x00000000, 0x936200c5, 0x936300b1,
+       0x00431023, 0x304400ff, 0x30830080, 0x10600004, 0x00000000, 0x0000000d,
+       0x00000000, 0x24000a6a, 0x93620004, 0x00441023, 0x304400ff, 0x30830080,
+       0x10600004, 0x2482ffff, 0x8f650024, 0x0a000b82, 0x00000000, 0x00022b00,
+       0x8f620024, 0x0045102b, 0x10400002, 0x00000000, 0x8f650024, 0x8f620048,
+       0x8f630040, 0x00431823, 0x0065202b, 0x10800004, 0x00000000, 0x8f620040,
+       0x00451021, 0xaf620048, 0x9762003c, 0x0062102b, 0x10400041, 0x8fbf0010,
+       0x10a0003f, 0x3c029000, 0x34420001, 0x3c040800, 0x8c830080, 0x8f450100,
+       0x3c068000, 0x24630001, 0x00a21025, 0xac830080, 0xaf420020, 0x8f420020,
+       0x00461024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000,
+       0x00a31825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024,
+       0x1440fffd, 0x24020002, 0x3c030800, 0xaf4501c0, 0xa34201c4, 0x8c640020,
+       0x3c021000, 0xaf4201f8, 0x1080001f, 0x8fbf0010, 0x0e001006, 0x00000000,
+       0x8f830018, 0x8f420100, 0xac620000, 0x8f840018, 0x8f620040, 0xac820004,
+       0x8f850018, 0x8f620048, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018,
+       0xac400010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448,
+       0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c0240c2, 0x00621825,
+       0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018,
+       0x3c020800, 0x24423958, 0xaf82000c, 0x03e00008, 0x00000000, 0x27bdffe8,
+       0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003, 0x3c020800,
+       0x0000000d, 0x3c020800, 0x8c430020, 0x10600026, 0x00001021, 0x0e001006,
+       0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x8e02001c,
+       0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018, 0xac82000c,
+       0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c106000, 0xac600014,
+       0x8f840018, 0x8e024448, 0x3c030800, 0xac820018, 0x9462466e, 0x8f840018,
+       0x3c034012, 0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x8e036800,
+       0x00001021, 0x3c040001, 0x00641825, 0xae036800, 0x0a000c0d, 0x8fbf0014,
+       0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x97430078,
+       0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008, 0xa7630010,
+       0x27450100, 0x8f640048, 0x8ca30018, 0x00641023, 0x18400021, 0x00000000,
+       0xaf630048, 0x8f620040, 0x9763003c, 0x00821023, 0x0043102a, 0x1040001a,
+       0x3c029000, 0x8ca40000, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020,
+       0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d,
+       0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d, 0xaf430020,
+       0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0,
+       0xa34201c4, 0xaf4301f8, 0x03e00008, 0x00001021, 0x8f420100, 0x34420001,
+       0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018, 0xafb10014,
+       0xafb00010, 0x9362007e, 0x30d000ff, 0x16020029, 0x00808821, 0x93620080,
+       0x16020026, 0x00000000, 0x9362007f, 0x16020023, 0x00000000, 0x9362007a,
+       0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x24000771, 0x0e000f49,
+       0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825, 0xa370007a,
+       0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x3c028000, 0x9363007d,
+       0x34420001, 0x3c048000, 0x02221025, 0xa363007d, 0xaf420020, 0x8f4201f8,
+       0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5101c0, 0xa34201c4,
+       0xaf4301f8, 0x0a000c79, 0x8fbf0018, 0x0000000d, 0x00000000, 0x24000781,
+       0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800,
+       0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x10600024, 0xafbf0014,
+       0x0e001006, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+       0x8e020004, 0xac820004, 0x8f830018, 0x8e020018, 0xac620008, 0x8f840018,
+       0x8e03001c, 0xac83000c, 0x9602000c, 0x9203000a, 0x8f840018, 0x00021400,
+       0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
+       0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018,
+       0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014,
+       0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8,
+       0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e001006, 0x00000000,
+       0x8f820018, 0xac400000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008,
+       0x8f830018, 0xac60000c, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400,
+       0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
+       0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018,
+       0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014,
+       0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010, 0x27500100,
+       0xafbf0014, 0x9602000c, 0x10400024, 0x00802821, 0x3c020800, 0x8c430020,
+       0x1060003a, 0x8fbf0014, 0x0e001006, 0x00000000, 0x8f840018, 0x8e030000,
+       0xac830000, 0x9602000c, 0x8f840018, 0x00021400, 0xac820004, 0x8f830018,
+       0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
+       0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
+       0xaca30018, 0x9443466e, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e001044,
+       0xaca3001c, 0x0a000d19, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015,
+       0x3c029000, 0x34420001, 0x00a21025, 0xaf420020, 0x3c038000, 0x8f420020,
+       0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x93620005, 0x34630001,
+       0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000553,
+       0xaf430020, 0x0a000d19, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010,
+       0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010,
+       0x27500100, 0x10600022, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f840018,
+       0x8e020004, 0xac820000, 0x9603000c, 0x9762002c, 0x8f840018, 0x00031c00,
+       0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
+       0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000,
+       0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
+       0x3c02400e, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x8e040000,
+       0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c038000, 0x8f420278,
+       0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf440240, 0xa3420244,
+       0x03e00008, 0xaf430278, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014,
+       0x00808821, 0xafb20018, 0x00c09021, 0xafb00010, 0x30b0ffff, 0x1060001c,
+       0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018,
+       0x00101400, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
+       0x8f830018, 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000,
+       0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024019,
+       0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf001c, 0x8fb20018,
+       0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x27450100,
+       0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620029, 0x00803021, 0x3c029000,
+       0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+       0x1440fffd, 0x3c028000, 0x34420001, 0x3c049000, 0x34840001, 0x3c058000,
+       0x24030012, 0x00c21025, 0x00c42025, 0xa363003f, 0xaf420020, 0xaf440020,
+       0x8f420020, 0x00451024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001,
+       0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020, 0x8f4201f8,
+       0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4,
+       0xaf4301f8, 0x0a000db3, 0x8fbf0010, 0x00c02021, 0x94a5000c, 0x24060001,
+       0x0e000f78, 0x240706d8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
+       0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021, 0xafb20018, 0x00a09021,
+       0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c, 0x0e001006, 0x00000000,
+       0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018,
+       0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
+       0xac520014, 0x8f840018, 0x3c026000, 0x8c434448, 0x3c020800, 0xac830018,
+       0x9443466e, 0x8f840018, 0x3c024010, 0x00621825, 0xac83001c, 0x0e001044,
+       0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
+       0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x93620005, 0x30420001,
+       0x10400033, 0x00808021, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020,
+       0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005,
+       0x3c048000, 0x3c030800, 0x304200fe, 0xa3620005, 0x8c620020, 0x34840001,
+       0x02042025, 0xaf440020, 0x10400020, 0x8fbf0014, 0x0e001006, 0x00000000,
+       0x8f820018, 0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00,
+       0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
+       0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000,
+       0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c02400a,
+       0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0014, 0x8fb00010,
+       0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021,
+       0x9364003f, 0x24030012, 0x00021402, 0x1483001c, 0x304500ff, 0x3c029000,
+       0x34420001, 0x3c038000, 0x00c21025, 0xa3650080, 0xa365007a, 0xaf420020,
+       0x8f420020, 0x00431024, 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001,
+       0x3c048000, 0x00c21025, 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024,
+       0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8,
+       0x0a000e54, 0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x93620080,
+       0x1045000b, 0x00000000, 0xa3650080, 0x8f820000, 0x93660080, 0x8f440180,
+       0x8f65004c, 0x8c430000, 0x0060f809, 0x00000000, 0x0a000e54, 0x8fbf0010,
+       0xa3650080, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020,
+       0x27bdffe0, 0xafb10014, 0x00808821, 0xafb20018, 0x00a09021, 0xafb00010,
+       0x30d000ff, 0x1060002f, 0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018,
+       0xac510000, 0x8f830018, 0xac700004, 0x8f820018, 0xac520008, 0x8f830018,
+       0xac60000c, 0x8f820018, 0xac400010, 0x9763006a, 0x00032880, 0x50a00001,
+       0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821,
+       0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050,
+       0x00c4182b, 0x54600001, 0x00c02021, 0x8f830018, 0x2402fffe, 0x00822824,
+       0x3c026000, 0xac650014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018,
+       0x9443466e, 0x8f840018, 0x3c024011, 0x00621825, 0xac83001c, 0x0e001044,
+       0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
+       0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f440100, 0x27500100,
+       0x8f650050, 0x0e000c45, 0x9206001b, 0x3c020800, 0x8c430020, 0x1060001d,
+       0x8e100018, 0x0e001006, 0x00000000, 0x8f840018, 0x8f420100, 0xac820000,
+       0x8f830018, 0xac700004, 0x8f840018, 0x8f620050, 0xac820008, 0x8f830018,
+       0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0x3c026000, 0xac600014,
+       0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e,
+       0x8f850018, 0x3c02401c, 0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0014,
+       0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c029000, 0x8f460140, 0x34420001,
+       0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
+       0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000, 0x24020012,
+       0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082, 0xaf440020,
+       0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000, 0x9362007d,
+       0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020,
+       0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0,
+       0xa34201c4, 0x03e00008, 0xaf4301f8, 0x8f430238, 0x3c020800, 0x04610013,
+       0x8c44009c, 0x2406fffe, 0x3c050800, 0x3c038000, 0x2484ffff, 0x14800009,
+       0x00000000, 0x97420078, 0x8ca3007c, 0x24420001, 0x00461024, 0x24630001,
+       0xa7620010, 0x03e00008, 0xaca3007c, 0x8f420238, 0x00431024, 0x1440fff3,
+       0x2484ffff, 0x8f420140, 0x3c031000, 0xaf420200, 0x03e00008, 0xaf430238,
+       0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020,
+       0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d,
+       0x34630001, 0x3c058000, 0x00831825, 0x34420001, 0xa362007d, 0xaf430020,
+       0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0,
+       0xa34201c4, 0x03e00008, 0xaf4301f8, 0x0000000d, 0x03e00008, 0x00000000,
+       0x0000000d, 0x03e00008, 0x00000000, 0x24020001, 0x03e00008, 0xa7620010,
+       0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001,
+       0x00621825, 0x14600003, 0x24020012, 0x14820003, 0x00000000, 0x03e00008,
+       0x00001021, 0x9363007e, 0x9362007a, 0x14620006, 0x00000000, 0x9363007e,
+       0x24020001, 0x24630001, 0x03e00008, 0xa363007e, 0x9363007e, 0x93620080,
+       0x14620004, 0x24020001, 0xa362000b, 0x03e00008, 0x24020001, 0x03e00008,
+       0x00001021, 0x9362000b, 0x10400021, 0x00001021, 0xa360000b, 0x9362003f,
+       0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825,
+       0x14600015, 0x00001821, 0x24020012, 0x10820012, 0x00000000, 0x9363007e,
+       0x9362007a, 0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001,
+       0xa362007e, 0x03e00008, 0x00601021, 0x9363007e, 0x93620080, 0x14620004,
+       0x00001821, 0x24020001, 0xa362000b, 0x24030001, 0x03e00008, 0x00601021,
+       0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc, 0x8f6200cc,
+       0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008, 0xa7640016,
+       0x27bdffd8, 0xafb00010, 0x00808021, 0xafb3001c, 0x00c09821, 0xafbf0020,
+       0xafb20018, 0xafb10014, 0x93620023, 0x00e09021, 0x30420040, 0x10400020,
+       0x30b1ffff, 0x3c020800, 0x8c430020, 0x1060001c, 0x00000000, 0x0e001006,
+       0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004,
+       0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+       0x8f820018, 0xac520014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+       0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825,
+       0x0e001044, 0xaca3001c, 0x93620023, 0x30420020, 0x14400003, 0x3c020800,
+       0x52600020, 0x3c029000, 0x8c430020, 0x1060001d, 0x3c029000, 0x0e001006,
+       0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004,
+       0x8f830018, 0xac720008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+       0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+       0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c02401b, 0x00621825,
+       0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020,
+       0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
+       0x3c028000, 0x34420001, 0x02021025, 0x8fbf0020, 0x8fb3001c, 0x8fb20018,
+       0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023, 0xaf420020, 0x03e00008,
+       0x27bd0028, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100,
+       0x1060001d, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020004,
+       0xac620000, 0x8f840018, 0x8e020018, 0xac820004, 0x8f850018, 0x8e020000,
+       0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018,
+       0xac600014, 0x8f820018, 0xac400018, 0x96030008, 0x3c020800, 0x9444466e,
+       0x8f850018, 0x00031c00, 0x00641825, 0x24040001, 0x0e001044, 0xaca3001c,
+       0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c060800, 0x24c54660,
+       0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a, 0x00441023, 0x00021400,
+       0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d, 0x00000000, 0x2400005a,
+       0x0a00101b, 0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021,
+       0x24020001, 0x304200ff, 0x1040001c, 0x274a0400, 0x3c07000a, 0x3c020800,
+       0x24454660, 0x94a9000a, 0x8f880014, 0x03471021, 0x94430006, 0x00402021,
+       0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023, 0x00021400, 0x00021403,
+       0x04410006, 0x0048102b, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001036,
+       0x24020001, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1440ffec,
+       0x03471021, 0x24c44660, 0x8c820010, 0xaf420038, 0x8c830014, 0x3c020005,
+       0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018, 0x03e00008, 0x00000000,
+       0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800, 0x24e84660, 0xafbf001c,
+       0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a, 0x8d060014, 0x00009021,
+       0x309000ff, 0x00e08821, 0x24420001, 0x24a50020, 0x24630001, 0xaf820010,
+       0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000, 0x04c10007, 0xad030014,
+       0x00621024, 0x14400005, 0x26224660, 0x8d020010, 0x24420001, 0xad020010,
+       0x26224660, 0x9444000a, 0x94450018, 0x0010102b, 0x00a41826, 0x2c630001,
+       0x00621825, 0x1060001c, 0x3c030006, 0x8f820010, 0x24120001, 0x00021140,
+       0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27450400,
+       0x8f420000, 0x30420010, 0x1040fffd, 0x26224660, 0x9444000a, 0x94430018,
+       0xaf800010, 0xaf850018, 0x14830012, 0x26274660, 0x0e0010d2, 0x00000000,
+       0x1600000e, 0x26274660, 0x0e001006, 0x00000000, 0x0a00108f, 0x26274660,
+       0x00041c00, 0x00031c03, 0x00051400, 0x00021403, 0x00621823, 0x18600002,
+       0x3c026000, 0xac400808, 0x26274660, 0x94e2000e, 0x94e3000c, 0x24420001,
+       0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e, 0x12000005, 0x3c02000a,
+       0x94e2000a, 0xa74200a2, 0x0a0010cc, 0x02401021, 0x03421821, 0x94640006,
+       0x94e2000a, 0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4e40006,
+       0x0000000d, 0x00000000, 0x2400005a, 0x0a0010ae, 0x24020001, 0x8f820014,
+       0x0062102b, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001b,
+       0x3c020800, 0x3c06000a, 0x24454660, 0x94a8000a, 0x8f870014, 0x03461021,
+       0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01021023,
+       0x00021400, 0x00021403, 0x04410006, 0x0047102b, 0x0000000d, 0x00000000,
+       0x2400005a, 0x0a0010c8, 0x24020001, 0x14400002, 0x00001021, 0x24020001,
+       0x304200ff, 0x1440ffec, 0x03461021, 0x02401021, 0x8fbf001c, 0x8fb20018,
+       0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x24454660,
+       0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0, 0x00832021, 0xaf44003c,
+       0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008, 0xaf420030, 0x00000000,
+       0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x00000000,
+       0x8f430400, 0x24c64660, 0xacc30010, 0x8f420404, 0x3c030020, 0xacc20014,
+       0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a, 0x94c5001e, 0x00832021,
+       0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002, 0xa4c40018, 0xa4c0001a,
+       0x03e00008, 0x00000000, 0x8f820010, 0x3c030006, 0x00021140, 0x00431025,
+       0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27430400, 0x8f420000,
+       0x30420010, 0x1040fffd, 0x00000000, 0xaf800010, 0xaf830018, 0x03e00008,
+       0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800, 0x26104660, 0x3c05000a,
+       0x02002021, 0x03452821, 0xafbf0014, 0x0e001128, 0x2406000a, 0x96020002,
+       0x9603001e, 0x3042000f, 0x24420003, 0x00431804, 0x24027fff, 0x0043102b,
+       0xaf830014, 0x10400004, 0x00000000, 0x0000000d, 0x00000000, 0x24000043,
+       0x0e0010d2, 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
+       0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000,
+       0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a001137, 0x00a01021,
+       0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008,
+       0x00000000, 0x3c036000, 0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582,
+       0x00042302, 0x308403ff, 0x00052d82, 0x00441026, 0x0002102b, 0x0005282b,
+       0x00451025, 0x1440000d, 0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c,
+       0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd,
+       0x3c020020, 0xaf420030, 0x0000000d, 0x03e00008, 0x00000000, 0x3c020050,
+       0x34420004, 0xaf440038, 0xaf45003c, 0xaf420030, 0x00000000, 0x00000000,
+       0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008,
+       0x00000000, 0x00000000 };
+
+static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_COM_b06FwRodata[(0x18/4) + 1] = {
+       0x08002318, 0x08002348, 0x08002378, 0x080023a8, 0x080023d8, 0x00000000,
+       0x00000000 };
+
+static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x00000000 };
+static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x00000000 };
+
+static int bnx2_RXP_b06FwReleaseMajor = 0x0;
+static int bnx2_RXP_b06FwReleaseMinor = 0x0;
+static int bnx2_RXP_b06FwReleaseFix = 0x0;
+static u32 bnx2_RXP_b06FwStartAddr = 0x08000060;
+static u32 bnx2_RXP_b06FwTextAddr = 0x08000000;
+static int bnx2_RXP_b06FwTextLen = 0x20b8;
+static u32 bnx2_RXP_b06FwDataAddr = 0x080020e0;
+static int bnx2_RXP_b06FwDataLen = 0x0;
+static u32 bnx2_RXP_b06FwRodataAddr = 0x00000000;
+static int bnx2_RXP_b06FwRodataLen = 0x0;
+static u32 bnx2_RXP_b06FwBssAddr = 0x08002100;
+static int bnx2_RXP_b06FwBssLen = 0x239c;
+static u32 bnx2_RXP_b06FwSbssAddr = 0x080020e0;
+static int bnx2_RXP_b06FwSbssLen = 0x14;
+
+static u32 bnx2_RXP_b06FwText[(0x20b8/4) + 1] = {
+       0x0a000018, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x302e362e,
+       0x39000000, 0x00060903, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
+       0x244220e0, 0x3c030800, 0x2463449c, 0xac400000, 0x0043202b, 0x1480fffd,
+       0x24420004, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100060,
+       0x3c1c0800, 0x279c20e0, 0x0e000329, 0x00000000, 0x0000000d, 0x8f870008,
+       0x2ce20080, 0x10400018, 0x3c030800, 0x24633490, 0x8f460100, 0x00072140,
+       0x00831021, 0xac460000, 0x8f450104, 0x00641021, 0xac450004, 0x8f460108,
+       0xac460008, 0x8f45010c, 0xac45000c, 0x8f460114, 0xac460010, 0x8f450118,
+       0xac450014, 0x8f460124, 0xac460018, 0x8f450128, 0x00641821, 0x24e20001,
+       0xaf820008, 0xac65001c, 0x03e00008, 0x00000000, 0x00804021, 0x8f830000,
+       0x24070001, 0x3c020001, 0x00621024, 0x10400037, 0x00603021, 0x9742010e,
+       0x3c038000, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
+       0xa342018b, 0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c,
+       0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000069, 0x00021400,
+       0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+       0x24020003, 0x30838000, 0x1060000d, 0xa7420188, 0x93420116, 0x304200fc,
+       0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600005, 0x00000000,
+       0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c,
+       0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
+       0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x30c21000,
+       0x1040000f, 0x00000000, 0x9742010c, 0x3042fc00, 0x5440000b, 0x24070005,
+       0x3c021000, 0x00c21024, 0x10400007, 0x3c030dff, 0x3463ffff, 0x3c020e00,
+       0x00c21024, 0x0062182b, 0x54600001, 0x24070005, 0x8f82000c, 0x30434000,
+       0x10600016, 0x00404821, 0x3c020f00, 0x00c21024, 0x14400012, 0x00000000,
+       0x93420116, 0x34424000, 0x03421821, 0x94650002, 0x2ca21389, 0x1040000b,
+       0x3c020800, 0x24422100, 0x00051942, 0x00031880, 0x00621821, 0x30a5001f,
+       0x8c640000, 0x24020001, 0x00a21004, 0x00822024, 0x01044025, 0x11000037,
+       0x3c021000, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, 0x3045ffff,
+       0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004,
+       0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005, 0xa745018e,
+       0x9743011c, 0x9742011e, 0x0a0000cd, 0x00021400, 0x9743011e, 0x9742011c,
+       0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c,
+       0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000,
+       0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c,
+       0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff,
+       0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008,
+       0x00001021, 0x00c21024, 0x104000ba, 0x3c020800, 0x8c430030, 0x1060003e,
+       0x31224000, 0x1040003c, 0x3c030f00, 0x00c31824, 0x3c020100, 0x0043102b,
+       0x14400038, 0x3c030800, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004,
+       0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b,
+       0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005,
+       0xa745018e, 0x9743011c, 0x9742011e, 0x0a000110, 0x00021400, 0x9743011e,
+       0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000,
+       0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
+       0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
+       0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
+       0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
+       0x03e00008, 0x00001021, 0x3c030800, 0x8c620024, 0x30420008, 0x1040003d,
+       0x34e80002, 0x3c020f00, 0x00c21024, 0x5440003a, 0x3107ffff, 0x9742010c,
+       0x30420200, 0x50400036, 0x3107ffff, 0x9742010e, 0x30e6fffb, 0x3c038000,
+       0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
+       0xa342018b, 0x8f840004, 0x24020180, 0x24030002, 0xaf420180, 0xa743018c,
+       0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000153, 0x00021400,
+       0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+       0x30828000, 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021,
+       0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+       0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
+       0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+       0xaf4201b8, 0x3107ffff, 0x8f820000, 0x3c068000, 0x9743010e, 0x00021442,
+       0x30440780, 0x24630004, 0x3065ffff, 0x8f4201b8, 0x00461024, 0x1440fffd,
+       0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf440180, 0xa742018c,
+       0x10600005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000189, 0x00021400,
+       0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+       0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
+       0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+       0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
+       0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+       0xaf4201b8, 0x03e00008, 0x00001021, 0x8f424000, 0x30420100, 0x104000ef,
+       0x3c020800, 0x8c440024, 0x24030001, 0x14830036, 0x00404021, 0x9742010e,
+       0x34e50002, 0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024,
+       0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180,
+       0xa742018c, 0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0001c6,
+       0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
+       0x8f84000c, 0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc,
+       0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
+       0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104,
+       0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
+       0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x30820001, 0x10400035,
+       0x30e90004, 0x9742010e, 0x30e6fffb, 0x3c038000, 0x24420004, 0x3044ffff,
+       0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004,
+       0x24020002, 0xaf400180, 0xa742018c, 0x10600005, 0xa744018e, 0x9743011c,
+       0x9742011e, 0x0a0001fe, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400,
+       0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188,
+       0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff,
+       0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e,
+       0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825,
+       0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x30c7ffff, 0x8d020024,
+       0x30420004, 0x10400037, 0x8d020024, 0x9742010e, 0x30e6fffb, 0x3c038000,
+       0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
+       0xa342018b, 0x8f840004, 0x24020100, 0x24030002, 0xaf420180, 0xa743018c,
+       0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000237, 0x00021400,
+       0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+       0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
+       0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+       0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
+       0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+       0xaf4201b8, 0x30c7ffff, 0x8d020024, 0x30420008, 0x10400034, 0x00000000,
+       0x9742010e, 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024,
+       0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004, 0x24020180, 0x24030002,
+       0xaf420180, 0xa743018c, 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e,
+       0x0a00026f, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825,
+       0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116,
+       0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004,
+       0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c,
+       0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
+       0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x15200046, 0x00001021, 0x3c038000,
+       0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0x24032000, 0xa342018b,
+       0xa7430188, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x3c030800,
+       0x8c620024, 0x30420001, 0x10400035, 0x00001021, 0x9742010e, 0x34e50002,
+       0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+       0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180, 0xa742018c,
+       0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0002b5, 0x00021400,
+       0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+       0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc, 0x005a1021,
+       0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+       0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
+       0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+       0xaf4201b8, 0x00001021, 0x03e00008, 0x00000000, 0x27bdffe0, 0xafbf0018,
+       0xafb10014, 0xafb00010, 0x8f420140, 0xaf420020, 0x8f430148, 0x3c027000,
+       0x00621824, 0x3c024000, 0x1062000c, 0x0043102b, 0x14400006, 0x3c025000,
+       0x3c023000, 0x1062000b, 0x3c024000, 0x0a00031f, 0x00000000, 0x10620034,
+       0x3c024000, 0x0a00031f, 0x00000000, 0x0e00067c, 0x00000000, 0x0a00031f,
+       0x3c024000, 0x8f420148, 0x24030002, 0x3044ffff, 0x00021402, 0x305000ff,
+       0x1203000c, 0x27510180, 0x2a020003, 0x10400005, 0x24020003, 0x0600001d,
+       0x36053000, 0x0a00030a, 0x3c038000, 0x12020007, 0x00000000, 0x0a000317,
+       0x00000000, 0x0e000423, 0x00000000, 0x0a000308, 0x00402021, 0x0e000435,
+       0x00000000, 0x00402021, 0x36053000, 0x3c038000, 0x8f4201b8, 0x00431024,
+       0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, 0xa6240010, 0x8f420144,
+       0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00031f, 0x3c024000, 0x0000000d,
+       0x00000000, 0x240001c3, 0x0a00031f, 0x3c024000, 0x0e0007f7, 0x00000000,
+       0x3c024000, 0xaf420178, 0x00000000, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
+       0x03e00008, 0x27bd0020, 0x24020800, 0x03e00008, 0xaf4201b8, 0x27bdffe8,
+       0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f,
+       0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008,
+       0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001,
+       0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400,
+       0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980,
+       0x34420200, 0xae021980, 0x8f500000, 0x32020003, 0x1040fffd, 0x32020001,
+       0x10400004, 0x32020002, 0x0e0003bd, 0x00000000, 0x32020002, 0x1040fff6,
+       0x00000000, 0x0e0002d4, 0x00000000, 0x0a00034a, 0x00000000, 0x27bdffe8,
+       0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f,
+       0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008,
+       0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001,
+       0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400,
+       0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980,
+       0x8fbf0014, 0x34420200, 0xae021980, 0x8fb00010, 0x03e00008, 0x27bd0018,
+       0x30a5ffff, 0x30c6ffff, 0x30e7ffff, 0x3c038000, 0x8f4201b8, 0x00431024,
+       0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0xaf440180, 0xa745018c,
+       0x10600005, 0xa746018e, 0x9743011c, 0x9742011e, 0x0a000393, 0x00021400,
+       0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+       0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
+       0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+       0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
+       0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+       0xaf4201b8, 0x03e00008, 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024,
+       0x1440fffd, 0x24020002, 0x24032000, 0xa342018b, 0xa7430188, 0x3c021000,
+       0xaf4201b8, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafbf0010, 0x8f460128,
+       0xaf460020, 0x8f420104, 0x8f450100, 0x24030800, 0x3c040010, 0xaf820000,
+       0x00441024, 0xaf85000c, 0xaf4301b8, 0x14400005, 0x3c02001f, 0x3c030800,
+       0x8c620020, 0x0a0003d5, 0x00002021, 0x3442ff00, 0x14c20009, 0x2402bfff,
+       0x3c030800, 0x8c620020, 0x24040001, 0x24420001, 0x0e00004c, 0xac620020,
+       0x0a0003e4, 0x00000000, 0x00a21024, 0x14400006, 0x00000000, 0xaf400048,
+       0x0e000448, 0xaf400040, 0x0a0003e4, 0x00000000, 0x0e000783, 0x00000000,
+       0x10400005, 0x3c024000, 0x8f430124, 0x3c026020, 0xac430014, 0x3c024000,
+       0xaf420138, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0,
+       0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002, 0x3044ffff,
+       0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, 0x10400005,
+       0x24020003, 0x0600001d, 0x36053000, 0x0a00040e, 0x3c038000, 0x12020007,
+       0x00000000, 0x0a00041b, 0x00000000, 0x0e000423, 0x00000000, 0x0a00040c,
+       0x00402021, 0x0e000435, 0x00000000, 0x00402021, 0x36053000, 0x3c038000,
+       0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b,
+       0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00041f,
+       0x8fbf0018, 0x0000000d, 0x00000000, 0x240001c3, 0x8fbf0018, 0x8fb10014,
+       0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, 0x1040000d,
+       0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821,
+       0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, 0x03e00008,
+       0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, 0x1040000e,
+       0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821,
+       0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, 0x00832024,
+       0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x27bdffb0, 0x3c026000,
+       0xafbf0048, 0x8c434448, 0xaf630140, 0x93620005, 0x30420001, 0x14400005,
+       0x00000000, 0x0e0007ed, 0x00000000, 0x0a00067a, 0x8fbf0048, 0x93420116,
+       0x93430112, 0x8f430104, 0x3c040020, 0x34424000, 0x00641824, 0x1060000d,
+       0x03426021, 0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x24040008,
+       0x240340c1, 0xa4430008, 0x24030002, 0xa043000b, 0x3c031000, 0x0a000563,
+       0xa044000a, 0x8f420104, 0x3c030040, 0x00431024, 0x10400007, 0x00000000,
+       0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x0a00055c, 0x24040010,
+       0xaf400048, 0xaf400054, 0xaf400040, 0x8f630048, 0x8f620040, 0x00624823,
+       0x05210004, 0x00000000, 0x0000000d, 0x00000000, 0x24000132, 0x9742011a,
+       0x3046ffff, 0x10c00004, 0x8d880004, 0x01061021, 0x0a000487, 0x2445ffff,
+       0x01002821, 0x918a000d, 0xa7a00020, 0xafa00028, 0x9364003f, 0x3c026000,
+       0x8c434448, 0x308700ff, 0x31420004, 0x10400033, 0xaf630144, 0x24090012,
+       0x14e90006, 0x3c040800, 0x8c830028, 0x24020001, 0x24630001, 0x0a00054e,
+       0xac830028, 0x8f620044, 0x15020012, 0x97a20020, 0x27a60010, 0x27450180,
+       0x3442001a, 0xa7a20020, 0x8f630040, 0x3c048000, 0x24020020, 0xa3a70022,
+       0xa3a90023, 0xa3a2001a, 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd,
+       0x00000000, 0x0a000533, 0x00000000, 0x8f620044, 0x01021023, 0x0440009e,
+       0x24020001, 0x8f620048, 0x01021023, 0x0441009a, 0x24020001, 0x97a20020,
+       0x27a60010, 0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000,
+       0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533,
+       0x00000000, 0x3c026000, 0x8c424448, 0xaf620148, 0x8f630040, 0x00685823,
+       0x19600013, 0x00cb102a, 0x54400007, 0x314a00fe, 0x5566000c, 0x010b4021,
+       0x31420001, 0x54400009, 0x010b4021, 0x314a00fe, 0x24020001, 0xa7a20020,
+       0x8f630040, 0x00c05821, 0x00003021, 0x0a0004dd, 0xafa30028, 0x00cb1023,
+       0x0a0004dd, 0x3046ffff, 0x00005821, 0x8f620048, 0x2442ffff, 0x00a21823,
+       0x18600019, 0x0066102a, 0x14400013, 0x24020001, 0xa7a20020, 0x8f630040,
+       0xafa30028, 0x8f620040, 0x55020005, 0x27a60010, 0x55200003, 0x27a60010,
+       0x0a0004f6, 0x00c01821, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024,
+       0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x8f650048, 0x00c31023,
+       0x3046ffff, 0x314a00f6, 0x3c046000, 0x8c824448, 0x31430002, 0x1060001e,
+       0xaf62014c, 0x8f620044, 0x1502000e, 0x97a20020, 0x27a60010, 0x34420200,
+       0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028, 0x8f4201b8,
+       0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x27a60010,
+       0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028,
+       0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000,
+       0x3c026000, 0x8c424448, 0x31430010, 0xaf620150, 0x54600003, 0x8d890008,
+       0x0a00054e, 0x24020001, 0x8f630054, 0x2522ffff, 0x00431023, 0x1840002a,
+       0x24020001, 0x27a60010, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000,
+       0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x8f420128,
+       0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, 0x90c4000a,
+       0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, 0x90c30012,
+       0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, 0x8cc20024,
+       0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001, 0x3c031000,
+       0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a00067a, 0x8fbf0048,
+       0x3c026000, 0x8c424448, 0x31430020, 0x10600019, 0xaf620154, 0x8f430128,
+       0x27420180, 0xac430000, 0x8f650040, 0x24040004, 0x240340c1, 0xa4430008,
+       0x24030002, 0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010,
+       0xa0400012, 0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c,
+       0xac450018, 0x0e0007ed, 0xaf4301b8, 0x0a00067a, 0x8fbf0048, 0x8f430104,
+       0x8c824448, 0x38e3000a, 0x2c630001, 0xaf620158, 0x38e2000c, 0x2c420001,
+       0x00621825, 0x14600003, 0x2402000e, 0x14e2002a, 0x00000000, 0x50c00008,
+       0x9584000e, 0x10c00004, 0xa7a60040, 0x01061021, 0x0a000583, 0x2445ffff,
+       0x01002821, 0x9584000e, 0x93630035, 0x8f62004c, 0x00642004, 0x00892021,
+       0x00821023, 0x1840001f, 0x3c026000, 0x8f620018, 0x01021023, 0x1c40000f,
+       0x97a20020, 0x8f620018, 0x15020018, 0x3c026000, 0x8f62001c, 0x01221023,
+       0x1c400008, 0x97a20020, 0x8f62001c, 0x15220011, 0x3c026000, 0x8f620058,
+       0x00821023, 0x1840000c, 0x97a20020, 0xafa50028, 0xafa80034, 0xafa90038,
+       0xafa4003c, 0x34420020, 0x0a0005a8, 0xa7a20020, 0x8f680040, 0x00003021,
+       0x8f640058, 0x01002821, 0x3c026000, 0x8c434448, 0xaf63015c, 0x8f62004c,
+       0x01221023, 0x18400009, 0x00000000, 0x8f620054, 0x01221023, 0x1c400005,
+       0x97a20020, 0xafa50028, 0xafa90024, 0x0a0005c3, 0x34420040, 0x9742011a,
+       0x1440000c, 0x24020014, 0x8f620058, 0x14820009, 0x24020014, 0x8f63004c,
+       0x8f620054, 0x10620004, 0x97a20020, 0xafa50028, 0x34420080, 0xa7a20020,
+       0x24020014, 0x10e2000a, 0x28e20015, 0x10400005, 0x2402000c, 0x10e20006,
+       0x3c026000, 0x0a000600, 0x00000000, 0x24020016, 0x14e20031, 0x3c026000,
+       0x8f620054, 0x24420001, 0x1522002d, 0x3c026000, 0x24020014, 0x10e2001e,
+       0x28e20015, 0x10400005, 0x2402000c, 0x10e20008, 0x3c026000, 0x0a000600,
+       0x00000000, 0x24020016, 0x10e2000c, 0x97a20020, 0x0a000600, 0x3c026000,
+       0x97a30020, 0x2402000e, 0xafa50028, 0xa3a70022, 0xa3a20023, 0xafa90024,
+       0x34630054, 0x0a0005ff, 0xa7a30020, 0x24030010, 0x24040002, 0xafa50028,
+       0xa3a70022, 0xa3a30023, 0xa3a4001a, 0xafa90024, 0x0a0005fe, 0x3442005d,
+       0x97a20020, 0x24030012, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023,
+       0xa3a4001a, 0xafa90024, 0x3042fffe, 0x3442005c, 0xa7a20020, 0x3c026000,
+       0x8c434448, 0x31420001, 0xaf630160, 0x1040002c, 0x2402000c, 0x10e20014,
+       0x28e2000d, 0x10400005, 0x2402000a, 0x10e20008, 0x97a20020, 0x0a000631,
+       0x3c026000, 0x2402000e, 0x10e20018, 0x3c026000, 0x0a000631, 0x00000000,
+       0x24030008, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a,
+       0x0a00062f, 0x34420013, 0x97a30020, 0x30620004, 0x1440000b, 0x97a20020,
+       0x3462001b, 0xa7a20020, 0x24020016, 0x24030002, 0xafa50028, 0xa3a70022,
+       0xa3a20023, 0x0a000630, 0xa3a3001a, 0x97a20020, 0x24030010, 0x24040002,
+       0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a, 0x3442001b, 0xa7a20020,
+       0x3c026000, 0x8c434448, 0x31420009, 0x0002102b, 0x00021023, 0x30420007,
+       0x34440003, 0xaf630164, 0x10c00016, 0x24030800, 0x8f820010, 0x27450180,
+       0x24420001, 0xaf820010, 0x24020004, 0xaf4301b8, 0xa4a40008, 0xa0a2000b,
+       0x93440120, 0x3c031000, 0xa4a6000e, 0xaca90024, 0xaca80028, 0x008b2021,
+       0xa4a4000c, 0xaf4301b8, 0x97a20020, 0x00003021, 0x3042ffbf, 0x0a000650,
+       0xa7a20020, 0x24060001, 0x3c026000, 0x8c434448, 0xaf630168, 0x97a20020,
+       0x10400020, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
+       0x00000000, 0x8f420128, 0xaca20000, 0x8fa30028, 0x240240c1, 0xa4a20008,
+       0xaca30018, 0x93a4001a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x97a20020,
+       0xa4a20010, 0x93a30022, 0xa0a30012, 0x93a20023, 0xa0a20013, 0x8fa30024,
+       0xaca30014, 0x8fa20034, 0xaca20024, 0x8fa30038, 0xaca30028, 0x8fa2003c,
+       0x3c031000, 0xaca2002c, 0xaf4301b8, 0x3c026000, 0x8c434448, 0x00c01021,
+       0xaf63016c, 0x8fbf0048, 0x03e00008, 0x27bd0050, 0x8f460140, 0x8f470148,
+       0x3c028000, 0x00e24024, 0x00072c02, 0x30a300ff, 0x2402000b, 0x1062008f,
+       0x27440180, 0x2862000c, 0x10400011, 0x24020006, 0x1062005a, 0x28620007,
+       0x10400007, 0x24020008, 0x10600024, 0x24020001, 0x10620037, 0x00000000,
+       0x0a00077e, 0x00000000, 0x106200a9, 0x24020009, 0x106200bb, 0x00071c02,
+       0x0a00077e, 0x00000000, 0x2402001b, 0x106200c7, 0x2862001c, 0x10400007,
+       0x2402000e, 0x106200b1, 0x24020019, 0x106200c2, 0x00071c02, 0x0a00077e,
+       0x00000000, 0x24020080, 0x10620060, 0x28620081, 0x10400005, 0x2402001c,
+       0x10620094, 0x00071c02, 0x0a00077e, 0x00000000, 0x240200c2, 0x106200c5,
+       0x00a01821, 0x0a00077e, 0x00000000, 0x00a01821, 0x3c058000, 0x8f4201b8,
+       0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac860000,
+       0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144, 0x3c021000,
+       0xac800028, 0xac830024, 0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808,
+       0x11000009, 0x00a01821, 0x3c020800, 0x24030002, 0xa0434490, 0x24424490,
+       0xac460008, 0x8f430144, 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8,
+       0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 0xac860004, 0xa4830008,
+       0xa082000a, 0xa082000b, 0xa4870010, 0xac800024, 0x8f420144, 0x3c031000,
+       0xac820028, 0x3c026000, 0xaf4301b8, 0x03e00008, 0xac400808, 0x00a01821,
+       0x3c080800, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x00000000,
+       0xac860000, 0x91024490, 0x00002821, 0x10400002, 0x25064490, 0x8cc50008,
+       0xac850004, 0xa4830008, 0x91034490, 0x24020002, 0xa082000b, 0xa4870010,
+       0x34630001, 0xa083000a, 0x8f420144, 0xac820024, 0x91034490, 0x10600002,
+       0x00001021, 0x8cc20004, 0xac820028, 0x3c021000, 0xaf4201b8, 0x3c026000,
+       0xa1004490, 0x03e00008, 0xac400808, 0x00a01821, 0x3c058000, 0x8f4201b8,
+       0x00451024, 0x1440fffd, 0x24020002, 0xa082000b, 0xa4830008, 0xa4870010,
+       0x8f420144, 0x3c031000, 0xa4820012, 0x03e00008, 0xaf4301b8, 0x30e2ffff,
+       0x14400028, 0x00071c02, 0x93620005, 0x30420004, 0x14400020, 0x3c029000,
+       0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+       0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, 0x34630001, 0x00c31825,
+       0x34420004, 0xa3620005, 0xaf430020, 0x93620005, 0x30420004, 0x14400003,
+       0x3c038000, 0x0000000d, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
+       0x24020005, 0x3c031000, 0xac860000, 0xa082000b, 0xaf4301b8, 0x0a00073d,
+       0x00071c02, 0x0000000d, 0x03e00008, 0x00000000, 0x00071c02, 0x3c058000,
+       0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002,
+       0xac860000, 0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144,
+       0x3c021000, 0xac800028, 0xac830024, 0x03e00008, 0xaf4201b8, 0x00071c02,
+       0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac800000,
+       0xac860004, 0xa4830008, 0xa082000a, 0xa082000b, 0xa4870010, 0xac800024,
+       0x8f420144, 0x3c031000, 0xac820028, 0x03e00008, 0xaf4301b8, 0x00071c02,
+       0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008,
+       0x24030002, 0xa082000a, 0x3c021000, 0xac860000, 0xac800004, 0xa083000b,
+       0xa4870010, 0xac800024, 0xac800028, 0x03e00008, 0xaf4201b8, 0x3c058000,
+       0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac860000, 0xac800004,
+       0xa4830008, 0xa080000a, 0x0a000748, 0xa082000b, 0x0000000d, 0x03e00008,
+       0x00000000, 0x03e00008, 0x00000000, 0x8f420100, 0x3042003e, 0x14400011,
+       0x24020001, 0xaf400048, 0x8f420100, 0x304207c0, 0x10400005, 0x00000000,
+       0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001, 0xaf400054, 0xaf400040,
+       0x8f420100, 0x30423800, 0x54400001, 0xaf400044, 0x24020001, 0x03e00008,
+       0x00000000, 0x3c029000, 0x34420001, 0x00822025, 0xaf440020, 0x3c038000,
+       0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x03e00008, 0x00000000,
+       0x3c028000, 0x34420001, 0x00822025, 0x03e00008, 0xaf440020, 0x8f430128,
+       0x27420180, 0xac430000, 0x8f650040, 0x240340c1, 0xa4430008, 0x24030002,
+       0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010, 0xa0400012,
+       0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c, 0xac450018,
+       0x03e00008, 0xaf4301b8, 0x24020001, 0xacc40000, 0x03e00008, 0xa4e50000,
+       0x03e00008, 0x24020001, 0x24020001, 0xaf400044, 0x03e00008, 0xaf400050,
+       0x00803021, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
+       0x00000000, 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008,
+       0xaca30018, 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010,
+       0xa4a20010, 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014,
+       0xaca30014, 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc2002c,
+       0x3c031000, 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, 0x03e00008,
+       0xaf400050, 0x27bdffe8, 0xafbf0010, 0x0e000326, 0x00000000, 0x00002021,
+       0x0e00004c, 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f460148,
+       0x27450180, 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, 0x00431024,
+       0x1440fffd, 0x00000000, 0x8f440140, 0x00061202, 0x304200ff, 0x00061c02,
+       0xaca20004, 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, 0xaca30024,
+       0x10e0000a, 0xaca40000, 0x28e20004, 0x14400005, 0x24020001, 0x24020005,
+       0x54e20005, 0xa0a0000a, 0x24020001, 0x0a000816, 0xa0a2000a, 0xa0a0000a,
+       0x3c021000, 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, 0x10c00007,
+       0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb,
+       0x24840004, 0x03e00008, 0x00000000, 0x0a00082a, 0x00a01021, 0xac860000,
+       0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008, 0x00000000,
+       0x00000000 }; 
+
+static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_RXP_b06FwBss[(0x239c/4) + 1] = { 0x00000000 };
+static u32 bnx2_RXP_b06FwSbss[(0x14/4) + 1] = { 0x00000000 };
+
+static u32 bnx2_rv2p_proc1[] = {
+       0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004,
+       0x00000010, 0x20bf002c, 0x00000010, 0x203f0143, 0x00000018, 0x8000fffd,
+       0x00000010, 0xb1b8b017, 0x0000000b, 0x2fdf0002, 0x00000000, 0x03d80000,
+       0x00000000, 0x2c380000, 0x00000008, 0x2c800000, 0x00000008, 0x2d000000,
+       0x00000010, 0x91d40000, 0x00000008, 0x2d800108, 0x00000008, 0x02000002,
+       0x00000010, 0x91de0000, 0x0000000f, 0x42e0001c, 0x00000010, 0x91840a08,
+       0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, 0x00000008, 0x2d800150,
+       0x00000000, 0x00000000, 0x00000010, 0x91de0000, 0x00000010, 0x2c620002,
+       0x00000018, 0x80000012, 0x0000000b, 0x2fdf0002, 0x0000000c, 0x1f800002,
+       0x00000000, 0x2c070000, 0x00000018, 0x8000ffe6, 0x00000008, 0x02000002,
+       0x0000000f, 0x42e0001c, 0x00000010, 0x91840a08, 0x00000008, 0x2c8000b0,
+       0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800108,
+       0x00000000, 0x00000000, 0x00000010, 0x91de0000, 0x00000018, 0x80000004,
+       0x0000000c, 0x1f800002, 0x00000000, 0x00000000, 0x00000018, 0x8000ffd9,
+       0x0000000c, 0x29800002, 0x0000000c, 0x1f800002, 0x00000000, 0x2adf0000,
+       0x00000008, 0x2a000005, 0x00000018, 0x8000ffd4, 0x00000008, 0x02240030,
+       0x00000018, 0x00040000, 0x00000018, 0x80000015, 0x00000018, 0x80000017,
+       0x00000018, 0x8000001b, 0x00000018, 0x8000004c, 0x00000018, 0x8000008c,
+       0x00000018, 0x8000000f, 0x00000018, 0x8000000e, 0x00000018, 0x8000000d,
+       0x00000018, 0x8000000c, 0x00000018, 0x800000c2, 0x00000018, 0x8000000a,
+       0x00000018, 0x80000009, 0x00000018, 0x80000008, 0x00000018, 0x800000fd,
+       0x00000018, 0x80000006, 0x00000018, 0x80000005, 0x00000018, 0x800000ff,
+       0x00000018, 0x80000104, 0x00000018, 0x80000002, 0x00000018, 0x80000098,
+       0x00000018, 0x80000000, 0x0000000c, 0x1f800001, 0x00000000, 0x00000000,
+       0x00000018, 0x8000ffba, 0x00000010, 0x91d40000, 0x0000000c, 0x29800001,
+       0x0000000c, 0x1f800001, 0x00000008, 0x2a000002, 0x00000018, 0x8000ffb5,
+       0x00000010, 0xb1a0b012, 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c200000,
+       0x00000008, 0x2c800000, 0x00000008, 0x2d000000, 0x00000010, 0x91d40000,
+       0x00000008, 0x2d80011c, 0x00000000, 0x00000000, 0x00000010, 0x91de0000,
+       0x0000000f, 0x47600008, 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000,
+       0x00000000, 0x0f580000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000,
+       0x00000000, 0x0b660000, 0x00000000, 0x0d610000, 0x00000018, 0x80000013,
+       0x0000000f, 0x47600008, 0x0000000b, 0x2fdf0002, 0x00000008, 0x2c800000,
+       0x00000008, 0x2d000000, 0x00000010, 0x91d40000, 0x00000008, 0x2d80011c,
+       0x0000000f, 0x060e0001, 0x00000010, 0x001f0000, 0x00000000, 0x0f580000,
+       0x00000010, 0x91de0000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000,
+       0x00000000, 0x0b660000, 0x00000000, 0x0d610000, 0x00000000, 0x02620000,
+       0x0000000b, 0x2fdf0002, 0x00000000, 0x309a0000, 0x00000000, 0x31040000,
+       0x00000000, 0x0c961800, 0x00000009, 0x0c99ffff, 0x00000004, 0xcc993400,
+       0x00000010, 0xb1963202, 0x00000008, 0x0f800000, 0x0000000c, 0x29800001,
+       0x00000010, 0x00220002, 0x0000000c, 0x29520001, 0x0000000c, 0x29520000,
+       0x00000008, 0x22000001, 0x0000000c, 0x1f800001, 0x00000000, 0x2adf0000,
+       0x00000008, 0x2a000003, 0x00000018, 0x8000ff83, 0x00000010, 0xb1a0b01d,
+       0x0000000b, 0x2fdf0002, 0x00000000, 0x2c200000, 0x00000008, 0x2c8000b0,
+       0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800150,
+       0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800000,
+       0x00000008, 0x2d000000, 0x00000008, 0x2d800108, 0x00000000, 0x00000000,
+       0x00000010, 0x91de0000, 0x0000000f, 0x47600008, 0x00000000, 0x060e0000,
+       0x00000010, 0x001f0000, 0x00000000, 0x0f580000, 0x00000010, 0x91de0000,
+       0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, 0x00000000, 0x0b670000,
+       0x00000000, 0x0d620000, 0x00000000, 0x0ce71800, 0x00000009, 0x0c99ffff,
+       0x00000004, 0xcc993400, 0x00000010, 0xb1963220, 0x00000008, 0x0f800000,
+       0x00000018, 0x8000001e, 0x0000000f, 0x47600008, 0x0000000b, 0x2fdf0002,
+       0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, 0x00000010, 0x91d40000,
+       0x00000008, 0x2d80012c, 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000,
+       0x00000000, 0x0f580000, 0x00000010, 0x91de0000, 0x00000000, 0x0a640000,
+       0x00000000, 0x0ae50000, 0x00000000, 0x0b670000, 0x00000000, 0x0d620000,
+       0x00000000, 0x02630000, 0x0000000f, 0x47620010, 0x00000000, 0x0ce71800,
+       0x0000000b, 0x2fdf0002, 0x00000000, 0x311a0000, 0x00000000, 0x31840000,
+       0x0000000b, 0xc20000ff, 0x00000002, 0x42040000, 0x00000001, 0x31620800,
+       0x0000000f, 0x020e0010, 0x00000002, 0x31620800, 0x00000009, 0x0c99ffff,
+       0x00000004, 0xcc993400, 0x00000010, 0xb1963202, 0x00000008, 0x0f800000,
+       0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x0000000c, 0x61420006,
+       0x00000008, 0x22000008, 0x00000000, 0x2adf0000, 0x00000008, 0x2a000004,
+       0x00000018, 0x8000ff42, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008,
+       0x00000010, 0x91a0b008, 0x00000010, 0x91d40000, 0x0000000c, 0x31620018,
+       0x00000008, 0x2d800001, 0x00000000, 0x00000000, 0x00000010, 0x91de0000,
+       0x00000008, 0xac000001, 0x00000018, 0x8000000e, 0x00000000, 0x0380b000,
+       0x0000000b, 0x2fdf0002, 0x00000000, 0x2c004000, 0x00000010, 0x91d40000,
+       0x00000008, 0x2d800101, 0x00000000, 0x00000000, 0x00000010, 0x91de0000,
+       0x0000000c, 0x31620018, 0x00000008, 0x2d800001, 0x00000000, 0x00000000,
+       0x00000010, 0x91de0000, 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c000e00,
+       0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000008, 0x2a000007,
+       0x00000018, 0x8000ff27, 0x00000010, 0xb1a0b016, 0x0000000b, 0x2fdf0002,
+       0x00000000, 0x03d80000, 0x00000000, 0x2c200000, 0x00000008, 0x2c8000b0,
+       0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800150,
+       0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800000,
+       0x00000008, 0x2d000000, 0x00000008, 0x2d800108, 0x00000008, 0x07000001,
+       0x00000010, 0xb5de1c00, 0x00000010, 0x2c620002, 0x00000018, 0x8000000a,
+       0x0000000b, 0x2fdf0002, 0x00000000, 0x2c070000, 0x0000000c, 0x1f800001,
+       0x00000010, 0x91de0000, 0x00000018, 0x8000ff11, 0x00000008, 0x2c8000b0,
+       0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800108,
+       0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000010, 0x91de0000,
+       0x00000000, 0x2adf0000, 0x00000008, 0x2a00000a, 0x00000018, 0x8000ff07,
+       0x00000000, 0x82265600, 0x0000000f, 0x47220008, 0x00000009, 0x070e000f,
+       0x00000008, 0x070e0008, 0x00000008, 0x02800001, 0x00000007, 0x02851c00,
+       0x00000008, 0x82850001, 0x00000000, 0x02840a00, 0x00000007, 0x42851c00,
+       0x00000003, 0xc3aa5200, 0x00000000, 0x03b10e00, 0x00000010, 0x001f0000,
+       0x0000000f, 0x0f280007, 0x00000007, 0x4b071c00, 0x00000000, 0x00000000,
+       0x0000000f, 0x0a960003, 0x00000000, 0x0a955c00, 0x00000000, 0x4a005a00,
+       0x00000000, 0x0c960a00, 0x00000009, 0x0c99ffff, 0x00000008, 0x0d00ffff,
+       0x00000010, 0xb1963202, 0x00000008, 0x0f800005, 0x00000010, 0x00220020,
+       0x00000000, 0x02a70000, 0x00000010, 0xb1850002, 0x00000008, 0x82850200,
+       0x00000000, 0x02000000, 0x00000000, 0x03a60000, 0x00000018, 0x8000004e,
+       0x00000000, 0x072b0000, 0x00000001, 0x878c1c00, 0x00000000, 0x870e1e00,
+       0x00000000, 0x860c1e00, 0x00000000, 0x03061e00, 0x00000010, 0xb18e0003,
+       0x00000018, 0x80000047, 0x00000018, 0x8000fffa, 0x00000010, 0x918c0003,
+       0x00000010, 0xb1870002, 0x00000018, 0x80000043, 0x00000010, 0x91d40000,
+       0x0000000c, 0x29800001, 0x00000000, 0x2a860000, 0x00000000, 0x230c0000,
+       0x00000000, 0x2b070000, 0x00000010, 0xb187000e, 0x00000008, 0x2a000008,
+       0x00000018, 0x8000003b, 0x00000010, 0x91d40000, 0x00000000, 0x28d18c00,
+       0x00000000, 0x2a860000, 0x00000000, 0x230c0000, 0x00000000, 0x2b070000,
+       0x00000018, 0x8000fff8, 0x00000010, 0x91d40000, 0x0000000c, 0x29800001,
+       0x00000000, 0x2aab0000, 0x00000000, 0xa3265600, 0x00000000, 0x2b000000,
+       0x0000000c, 0x1f800001, 0x00000008, 0x2a000008, 0x00000018, 0x8000fec8,
+       0x00000010, 0x91d40000, 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001,
+       0x00000008, 0x2a000009, 0x00000018, 0x8000fec3, 0x00000010, 0x91d40000,
+       0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000000, 0x29420000,
+       0x00000008, 0x2a000002, 0x00000018, 0x8000febd, 0x00000018, 0x8000febc,
+       0x00000010, 0xb1bcb016, 0x0000000b, 0x2fdf0002, 0x00000000, 0x03d80000,
+       0x00000000, 0x2c3c0000, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008,
+       0x00000010, 0x91d40000, 0x00000008, 0x2d800150, 0x00000000, 0x00000000,
+       0x00000010, 0x205f0000, 0x00000008, 0x2c800000, 0x00000008, 0x2d000000,
+       0x00000008, 0x2d800108, 0x00000008, 0x07000001, 0x00000010, 0xb5de1c00,
+       0x00000010, 0x2c620002, 0x00000018, 0x8000000a, 0x0000000b, 0x2fdf0002,
+       0x00000000, 0x2c070000, 0x0000000c, 0x1f800000, 0x00000010, 0x91de0000,
+       0x00000018, 0x8000fea6, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008,
+       0x00000010, 0x91d40000, 0x00000008, 0x2d800108, 0x0000000c, 0x29800000,
+       0x0000000c, 0x1f800000, 0x00000010, 0x91de0000, 0x00000000, 0x2adf0000,
+       0x00000008, 0x2a000006, 0x00000018, 0x8000fe9c, 0x00000008, 0x03050004,
+       0x00000006, 0x83040c00, 0x00000008, 0x02850200, 0x00000000, 0x86050c00,
+       0x00000001, 0x860c0e00, 0x00000008, 0x02040004, 0x00000000, 0x02041800,
+       0x00000000, 0x83871800, 0x00000018, 0x00020000 };
+
+static u32 bnx2_rv2p_proc2[] = {
+       0x00000000, 0x2a000000, 0x00000010, 0xb1d40000, 0x00000008, 0x02540003,
+       0x00000018, 0x00040000, 0x00000018, 0x8000000a, 0x00000018, 0x8000000a,
+       0x00000018, 0x8000000e, 0x00000018, 0x80000056, 0x00000018, 0x800001b9,
+       0x00000018, 0x800001e1, 0x00000018, 0x8000019b, 0x00000018, 0x800001f9,
+       0x00000018, 0x8000019f, 0x00000018, 0x800001a6, 0x00000018, 0x80000000,
+       0x0000000c, 0x29800001, 0x00000000, 0x2a000000, 0x0000000c, 0x29800000,
+       0x00000010, 0x20530000, 0x00000018, 0x8000ffee, 0x0000000c, 0x29800001,
+       0x00000010, 0x91de0000, 0x00000010, 0x001f0000, 0x00000000, 0x2f80aa00,
+       0x00000000, 0x2a000000, 0x00000000, 0x0d610000, 0x00000000, 0x03620000,
+       0x00000000, 0x2c400000, 0x00000000, 0x02638c00, 0x00000000, 0x26460000,
+       0x00000010, 0x00420002, 0x00000008, 0x02040012, 0x00000010, 0xb9060836,
+       0x00000000, 0x0f580000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000,
+       0x00000000, 0x0b660000, 0x00000000, 0x0c000000, 0x00000000, 0x0b800000,
+       0x00000010, 0x00420009, 0x00000008, 0x0cc60012, 0x00000008, 0x0f800003,
+       0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000008, 0x27110012,
+       0x00000000, 0x66900000, 0x00000008, 0xa31b0012, 0x00000018, 0x80000008,
+       0x00000000, 0x0cc60000, 0x00000008, 0x0f800003, 0x00000000, 0x00000000,
+       0x00000010, 0x009f0000, 0x00000000, 0x27110000, 0x00000000, 0x66900000,
+       0x00000000, 0x231b0000, 0x00000010, 0xb197320e, 0x00000000, 0x25960000,
+       0x00000000, 0x021b0000, 0x00000010, 0x001f0000, 0x00000008, 0x0f800003,
+       0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000000, 0x22c50800,
+       0x00000010, 0x009f0000, 0x00000000, 0x27002200, 0x00000000, 0x26802000,
+       0x00000000, 0x231b0000, 0x0000000c, 0x69520001, 0x00000018, 0x8000fff3,
+       0x00000010, 0x01130002, 0x00000010, 0xb1980003, 0x00000010, 0x001f0000,
+       0x00000008, 0x0f800004, 0x00000008, 0x22000003, 0x00000008, 0x2c80000c,
+       0x00000008, 0x2d00000c, 0x00000010, 0x009f0000, 0x00000000, 0x25960000,
+       0x0000000c, 0x29800000, 0x00000000, 0x32140000, 0x00000000, 0x32950000,
+       0x00000000, 0x33160000, 0x00000000, 0x31e32e00, 0x00000008, 0x2d800010,
+       0x00000010, 0x20530000, 0x00000018, 0x8000ffac, 0x00000000, 0x23000000,
+       0x00000000, 0x25e60000, 0x00000008, 0x2200000b, 0x0000000c, 0x69520000,
+       0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000018, 0x8000ffa5,
+       0x0000000c, 0x29800001, 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000,
+       0x00000010, 0x001f0000, 0x00000000, 0x02700000, 0x00000000, 0x0d620000,
+       0x00000000, 0xbb630800, 0x00000000, 0x2a000000, 0x00000009, 0x076000ff,
+       0x0000000f, 0x2c0e0007, 0x00000008, 0x2c800000, 0x00000008, 0x2d000064,
+       0x00000008, 0x2d80011c, 0x00000009, 0x06420002, 0x0000000c, 0x61420001,
+       0x00000000, 0x0f400000, 0x00000000, 0x02d08c00, 0x00000000, 0x23000000,
+       0x00000004, 0x826da000, 0x00000000, 0x8304a000, 0x00000000, 0x22c50c00,
+       0x00000000, 0x03760000, 0x00000004, 0x83860a00, 0x00000000, 0x83870c00,
+       0x00000010, 0x91de0000, 0x00000000, 0x037c0000, 0x00000000, 0x837b0c00,
+       0x00000001, 0x83060e00, 0x00000000, 0x83870c00, 0x00000000, 0x82850e00,
+       0x00000010, 0xb1860016, 0x0000000f, 0x47610018, 0x00000000, 0x068e0000,
+       0x0000000f, 0x47670010, 0x0000000f, 0x47e20010, 0x00000000, 0x870e1e00,
+       0x00000010, 0xb70e1a10, 0x00000010, 0x0ce7000e, 0x00000008, 0x22000009,
+       0x00000000, 0x286d0000, 0x0000000f, 0x65680010, 0x00000003, 0xf66c9400,
+       0x00000010, 0xb972a003, 0x0000000c, 0x73e70019, 0x0000000c, 0x21420004,
+       0x00000018, 0x8000023f, 0x00000000, 0x37ed0000, 0x0000000c, 0x73e7001a,
+       0x00000010, 0x20530000, 0x00000008, 0x22000008, 0x0000000c, 0x61420004,
+       0x00000000, 0x02f60000, 0x00000004, 0x82840a00, 0x00000010, 0xb1840a2b,
+       0x00000010, 0x2d67000a, 0x00000010, 0xb96d0804, 0x00000004, 0xb6ed0a00,
+       0x00000000, 0x37ed0000, 0x00000018, 0x80000029, 0x0000000c, 0x61420000,
+       0x00000000, 0x37040000, 0x00000000, 0x37850000, 0x0000000c, 0x33e7001a,
+       0x00000018, 0x80000024, 0x00000010, 0xb96d0809, 0x00000004, 0xb6ed0a00,
+       0x00000000, 0x036d0000, 0x00000004, 0xb76e0c00, 0x00000010, 0x91ee0c1f,
+       0x0000000c, 0x73e7001a, 0x00000004, 0xb6ef0c00, 0x00000000, 0x37ed0000,
+       0x00000018, 0x8000001b, 0x0000000c, 0x61420000, 0x00000010, 0xb7ee0a05,
+       0x00000010, 0xb96f0815, 0x00000003, 0xb76e0800, 0x00000004, 0xb7ef0a00,
+       0x00000018, 0x80000015, 0x00000010, 0x0ce7000c, 0x00000008, 0x22000009,
+       0x00000000, 0x286d0000, 0x0000000f, 0x65680010, 0x00000003, 0xf66c9400,
+       0x00000010, 0xb972a003, 0x0000000c, 0x73e70019, 0x0000000c, 0x21420004,
+       0x00000018, 0x80000215, 0x00000010, 0x20530000, 0x00000008, 0x22000008,
+       0x0000000c, 0x61420004, 0x00000000, 0x37040000, 0x00000000, 0x37850000,
+       0x00000000, 0x036d0000, 0x00000003, 0xb8f10c00, 0x00000018, 0x80000004,
+       0x00000000, 0x02840000, 0x00000002, 0x21421800, 0x0000000c, 0x61420000,
+       0x00000000, 0x286d0000, 0x0000000f, 0x65ed0010, 0x00000009, 0x266dffff,
+       0x00000000, 0x23000000, 0x00000010, 0xb1840a3d, 0x00000010, 0x01420002,
+       0x00000004, 0xb8f10a00, 0x00000003, 0x83760a00, 0x00000010, 0xb8040c39,
+       0x00000010, 0xb7e6080a, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000,
+       0x00000009, 0x0c68ffff, 0x00000009, 0x0b67ffff, 0x00000000, 0x0be60000,
+       0x00000000, 0x0c840000, 0x00000010, 0xb197320c, 0x00000008, 0x0f800002,
+       0x00000018, 0x8000000a, 0x00000000, 0x0a6a0000, 0x00000000, 0x0aeb0000,
+       0x00000000, 0x0c000000, 0x00000009, 0x0b6cffff, 0x00000000, 0x0be90000,
+       0x00000000, 0x0c840000, 0x00000010, 0xb1973203, 0x00000008, 0x0f800002,
+       0x00000018, 0x80000001, 0x00000010, 0x001f0000, 0x00000000, 0x0c860000,
+       0x00000000, 0x06980000, 0x00000008, 0x0f800003, 0x00000000, 0x00000000,
+       0x00000010, 0x009f0000, 0x00000010, 0xb1973210, 0x00000000, 0x231b0000,
+       0x00000000, 0x02043600, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010,
+       0x00000009, 0x2607ffff, 0x00000000, 0x27111a00, 0x00000000, 0x66900000,
+       0x0000000c, 0x29000000, 0x00000018, 0x800001de, 0x00000000, 0x06980000,
+       0x00000010, 0x20530000, 0x00000000, 0x22c58c00, 0x00000010, 0x001f0000,
+       0x00000008, 0x0f800003, 0x00000018, 0x8000fff0, 0x00000000, 0x02043600,
+       0x00000000, 0x231b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010,
+       0x00000009, 0x2607ffff, 0x00000000, 0x27111a00, 0x00000000, 0x66900000,
+       0x0000000c, 0x29000000, 0x00000010, 0x91840a02, 0x00000002, 0x21421800,
+       0x00000000, 0x32140000, 0x00000000, 0x32950000, 0x00000005, 0x73e72c00,
+       0x00000005, 0x74683000, 0x00000000, 0x33170000, 0x00000018, 0x80000138,
+       0x00000010, 0x91c60004, 0x00000008, 0x07000004, 0x00000010, 0xb1c41c02,
+       0x00000010, 0x91840a04, 0x00000018, 0x800001c3, 0x00000010, 0x20530000,
+       0x00000000, 0x22c58c00, 0x00000010, 0xb1840a8e, 0x0000000c, 0x21420006,
+       0x00000010, 0x0ce7001a, 0x0000000f, 0x43680010, 0x00000000, 0x03f30c00,
+       0x00000010, 0x91870850, 0x0000000f, 0x46ec0010, 0x00000010, 0xb68d0c4e,
+       0x00000000, 0x838d0c00, 0x00000000, 0xa3050800, 0x00000001, 0xa3460e00,
+       0x00000000, 0x02048c00, 0x00000010, 0x91840a02, 0x00000002, 0x21421800,
+       0x00000010, 0x001f0000, 0x00000008, 0x22000008, 0x00000003, 0x8384a000,
+       0x0000000f, 0x65870010, 0x00000009, 0x2607ffff, 0x00000000, 0x27750c00,
+       0x00000000, 0x66f40000, 0x0000000c, 0x29000000, 0x00000018, 0x800001aa,
+       0x00000000, 0x03068c00, 0x00000003, 0xf4680c00, 0x00000010, 0x20530000,
+       0x00000000, 0x22c58c00, 0x00000018, 0x8000ffe5, 0x00000000, 0x39760000,
+       0x00000000, 0x39840000, 0x0000000c, 0x33e70019, 0x00000010, 0x001f0000,
+       0x00000000, 0x031e0000, 0x00000000, 0x0760fe00, 0x0000000f, 0x0f0e0007,
+       0x00000000, 0x83850800, 0x00000000, 0x0a7d0000, 0x00000000, 0x0afe0000,
+       0x00000000, 0x0b7f0000, 0x00000000, 0x0d7a0000, 0x00000000, 0x0c000000,
+       0x00000000, 0x0bfc0000, 0x00000000, 0x0c970e00, 0x00000008, 0x0f800003,
+       0x0000000f, 0x47670010, 0x00000008, 0x070e0001, 0x0000000b, 0xc38000ff,
+       0x00000002, 0x43870000, 0x00000001, 0x33e70e00, 0x0000000f, 0x038e0010,
+       0x00000002, 0x33e70e00, 0x00000000, 0x28f30000, 0x00000010, 0x009f0000,
+       0x00000000, 0x02043600, 0x00000010, 0x91840a02, 0x00000002, 0x21421800,
+       0x00000008, 0x22000006, 0x00000000, 0x231b0000, 0x00000000, 0x23ff0000,
+       0x00000000, 0x241b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010,
+       0x00000009, 0x2607ffff, 0x00000000, 0x27110000, 0x00000000, 0x26900000,
+       0x0000000c, 0x29000000, 0x00000018, 0x8000017e, 0x00000003, 0xf4683600,
+       0x00000000, 0x3a100000, 0x00000000, 0x3a910000, 0x00000003, 0xf66c2400,
+       0x00000010, 0x001f0000, 0x00000010, 0xb1923604, 0x00000008, 0x0f800004,
+       0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000000, 0x3e170000,
+       0x00000000, 0x3e940000, 0x00000000, 0x3f150000, 0x00000000, 0x3f960000,
+       0x00000010, 0x001f0000, 0x00000000, 0x0f060000, 0x00000010, 0x20530000,
+       0x00000000, 0x22c53600, 0x00000018, 0x8000ffac, 0x00000010, 0x001f0000,
+       0x00000000, 0x031e0000, 0x00000000, 0x83850800, 0x00000009, 0x076000ff,
+       0x0000000f, 0x0f0e0007, 0x00000000, 0x0c000000, 0x00000000, 0x0a7d0000,
+       0x00000000, 0x0afe0000, 0x00000000, 0x0b7f0000, 0x00000000, 0x0d7a0000,
+       0x00000000, 0x0bfc0000, 0x00000000, 0x0c970e00, 0x00000008, 0x0f800003,
+       0x0000000f, 0x47670010, 0x00000008, 0x070e0001, 0x0000000b, 0xc38000ff,
+       0x00000002, 0x43870000, 0x00000001, 0x33e70e00, 0x0000000f, 0x038e0010,
+       0x00000002, 0x33e70e00, 0x00000000, 0x39840000, 0x00000003, 0xb9720800,
+       0x00000000, 0x28f30000, 0x0000000f, 0x65680010, 0x00000010, 0x009f0000,
+       0x00000000, 0x02043600, 0x00000010, 0x91840a02, 0x00000002, 0x21421800,
+       0x00000008, 0x22000007, 0x00000000, 0x231b0000, 0x00000000, 0x23ff0000,
+       0x00000000, 0x241b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010,
+       0x00000009, 0x2607ffff, 0x00000000, 0x27110000, 0x00000000, 0x26900000,
+       0x0000000c, 0x29000000, 0x00000018, 0x80000145, 0x00000003, 0xf4683600,
+       0x00000000, 0x3a100000, 0x00000000, 0x3a910000, 0x00000003, 0xf66c2400,
+       0x00000010, 0x001f0000, 0x00000010, 0xb1923604, 0x00000008, 0x0f800004,
+       0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000000, 0x3e170000,
+       0x00000000, 0x3e940000, 0x00000000, 0x3f150000, 0x00000000, 0x3f960000,
+       0x00000010, 0x001f0000, 0x00000000, 0x0f060000, 0x00000010, 0x20530000,
+       0x00000000, 0x22c53600, 0x00000018, 0x8000ff73, 0x00000010, 0x0ce70005,
+       0x00000008, 0x2c80000c, 0x00000008, 0x2d000070, 0x00000008, 0x2d800010,
+       0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000018, 0x8000011d,
+       0x00000000, 0x2c1e0000, 0x00000008, 0x2c8000b8, 0x00000008, 0x2d000010,
+       0x00000008, 0x2d800048, 0x00000000, 0x00000000, 0x00000010, 0x91de0000,
+       0x00000018, 0x8000fe5d, 0x0000000c, 0x29800001, 0x00000000, 0x2a000000,
+       0x00000010, 0x001f0000, 0x00000000, 0x0f008000, 0x00000008, 0x0f800007,
+       0x00000018, 0x80000006, 0x0000000c, 0x29800001, 0x00000000, 0x2a000000,
+       0x00000010, 0x001f0000, 0x0000000f, 0x0f470007, 0x00000008, 0x0f800008,
+       0x00000018, 0x80000119, 0x00000010, 0x20530000, 0x00000018, 0x8000fe4f,
+       0x0000000c, 0x29800001, 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000,
+       0x00000000, 0x2a000000, 0x00000009, 0x0261ffff, 0x0000000d, 0x70e10001,
+       0x00000018, 0x80000101, 0x00000000, 0x2c400000, 0x00000008, 0x2c8000c4,
+       0x00000008, 0x2d00001c, 0x00000008, 0x2d800001, 0x00000005, 0x70e10800,
+       0x00000010, 0x91de0000, 0x00000018, 0x8000fe41, 0x0000000c, 0x29800001,
+       0x00000010, 0x91de0000, 0x00000000, 0x2fd50000, 0x00000010, 0x001f0000,
+       0x00000000, 0x02700000, 0x00000000, 0x0d620000, 0x00000000, 0xbb630800,
+       0x00000000, 0x2a000000, 0x00000000, 0x0f400000, 0x00000000, 0x2c400000,
+       0x0000000c, 0x73e7001b, 0x00000010, 0x0ce7000e, 0x00000000, 0x286d0000,
+       0x0000000f, 0x65ed0010, 0x00000009, 0x266dffff, 0x00000018, 0x80000069,
+       0x00000008, 0x02000004, 0x00000010, 0x91c40803, 0x00000018, 0x800000f6,
+       0x00000010, 0x20530000, 0x00000018, 0x800000e5, 0x00000008, 0x2c8000b8,
+       0x00000008, 0x2d000010, 0x00000008, 0x2d800048, 0x00000018, 0x80000005,
+       0x00000008, 0x2c8000c4, 0x00000008, 0x2d00001c, 0x00000008, 0x2d800001,
+       0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800048,
+       0x00000008, 0x2d000068, 0x00000008, 0x2d800104, 0x00000000, 0x00000000,
+       0x00000010, 0x91de0000, 0x00000000, 0x27f60000, 0x00000010, 0xb87a9e04,
+       0x00000008, 0x2200000d, 0x00000018, 0x800000e2, 0x00000010, 0x20530000,
+       0x00000018, 0x8000fe18, 0x0000000c, 0x29800001, 0x00000010, 0x91de0000,
+       0x00000000, 0x2fd50000, 0x00000010, 0x001f0000, 0x00000000, 0x02700000,
+       0x00000000, 0x0d620000, 0x00000000, 0xbb630800, 0x00000000, 0x2a000000,
+       0x00000010, 0x0e670011, 0x00000000, 0x286d0000, 0x0000000f, 0x65ed0010,
+       0x00000009, 0x266dffff, 0x00000004, 0xb8f1a000, 0x00000000, 0x0f400000,
+       0x0000000c, 0x73e7001c, 0x00000018, 0x80000040, 0x00000008, 0x02000004,
+       0x00000010, 0x91c40802, 0x00000018, 0x800000cd, 0x00000000, 0x2c1e0000,
+       0x00000008, 0x2c8000b8, 0x00000008, 0x2d000010, 0x00000008, 0x2d800048,
+       0x00000010, 0x20530000, 0x00000010, 0x91de0000, 0x00000018, 0x8000fdfe,
+       0x0000000c, 0x29800001, 0x00000000, 0x03550000, 0x00000000, 0x06460000,
+       0x00000000, 0x03d60000, 0x00000000, 0x2a000000, 0x0000000f, 0x0f480007,
+       0x00000010, 0xb18c0027, 0x0000000f, 0x47420008, 0x00000009, 0x070e000f,
+       0x00000008, 0x070e0008, 0x00000010, 0x001f0000, 0x00000008, 0x09000001,
+       0x00000007, 0x09121c00, 0x00000003, 0xcbca9200, 0x00000000, 0x0b97a200,
+       0x00000007, 0x4b171c00, 0x0000000f, 0x0a960003, 0x00000000, 0x0a959c00,
+       0x00000000, 0x4a009a00, 0x00000008, 0x82120001, 0x00000001, 0x0c170800,
+       0x00000000, 0x02180000, 0x00000000, 0x0c971800, 0x00000008, 0x0d00ffff,
+       0x00000008, 0x0f800006, 0x0000000c, 0x29000000, 0x00000008, 0x22000001,
+       0x00000000, 0x22c50c00, 0x00000010, 0x009f0000, 0x00000010, 0xb197320b,
+       0x00000000, 0x231b0000, 0x00000000, 0x27110800, 0x00000000, 0x66900000,
+       0x00000018, 0x800000a4, 0x00000000, 0x02180000, 0x00000010, 0x20530000,
+       0x00000000, 0x22c53600, 0x00000010, 0x001f0000, 0x00000008, 0x0f800006,
+       0x00000018, 0x8000fff5, 0x00000010, 0x91870002, 0x00000008, 0x2200000a,
+       0x00000000, 0x231b0000, 0x00000000, 0x27110800, 0x00000000, 0x66900000,
+       0x00000018, 0x80000098, 0x00000008, 0x0200000a, 0x00000010, 0x91c40804,
+       0x00000010, 0x02c20003, 0x00000010, 0x001f0000, 0x00000008, 0x0f800008,
+       0x00000010, 0x20530000, 0x00000018, 0x8000fdc9, 0x00000000, 0x06820000,
+       0x00000010, 0x001f0000, 0x00000010, 0x0ce70028, 0x00000000, 0x03720000,
+       0x00000000, 0xa8760c00, 0x00000000, 0x0cf60000, 0x00000010, 0xb8723224,
+       0x00000000, 0x03440000, 0x00000008, 0x22000010, 0x00000000, 0x03ca0000,
+       0x0000000f, 0x65680010, 0x00000000, 0x0bcf0000, 0x00000000, 0x27f20000,
+       0x00000010, 0xb7ef3203, 0x0000000c, 0x21420004, 0x0000000c, 0x73e70019,
+       0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x00000018, 0x8000007e,
+       0x00000004, 0xb9723200, 0x00000010, 0x20530000, 0x00000000, 0x22060000,
+       0x0000000c, 0x61420004, 0x00000000, 0x25070000, 0x00000000, 0x27970000,
+       0x00000000, 0x290e0000, 0x00000010, 0x0ce70010, 0x00000010, 0xb873320f,
+       0x0000000f, 0x436c0010, 0x00000000, 0x03f30c00, 0x00000000, 0x03f30000,
+       0x00000000, 0x83990e00, 0x00000001, 0x83860e00, 0x00000000, 0x83060e00,
+       0x00000003, 0xf66c0c00, 0x00000000, 0x39f30e00, 0x00000000, 0x3af50e00,
+       0x00000000, 0x7a740000, 0x0000000f, 0x43680010, 0x00000001, 0x83860e00,
+       0x00000000, 0x83060e00, 0x00000003, 0xf4680c00, 0x00000000, 0x286d0000,
+       0x00000000, 0x03690000, 0x00000010, 0xb1f60c54, 0x00000000, 0x0a6a0000,
+       0x00000000, 0x0aeb0000, 0x00000009, 0x0b6cffff, 0x00000000, 0x0c000000,
+       0x00000000, 0x0be90000, 0x00000003, 0x8cf6a000, 0x0000000c, 0x09800002,
+       0x00000010, 0x009f0000, 0x00000010, 0xb8173209, 0x00000000, 0x35140000,
+       0x00000000, 0x35950000, 0x00000005, 0x766c2c00, 0x00000000, 0x34970000,
+       0x00000004, 0xb8f12e00, 0x00000010, 0x001f0000, 0x00000008, 0x0f800004,
+       0x00000018, 0x8000fff7, 0x00000000, 0x03e90000, 0x00000010, 0xb8f6a01a,
+       0x00000010, 0x20130019, 0x00000010, 0xb1f10e18, 0x00000000, 0x83973200,
+       0x00000000, 0x38700e00, 0x00000000, 0xbb760e00, 0x00000000, 0x37d00000,
+       0x0000000c, 0x73e7001a, 0x00000003, 0xb8f1a000, 0x00000000, 0x32140000,
+       0x00000000, 0x32950000, 0x00000005, 0x73e72c00, 0x00000000, 0x33190000,
+       0x00000005, 0x74680000, 0x00000010, 0x0ce7000d, 0x00000008, 0x22000009,
+       0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x0000000c, 0x73e70019,
+       0x0000000f, 0x65680010, 0x0000000c, 0x21420004, 0x00000018, 0x8000003c,
+       0x00000010, 0x20530000, 0x0000000c, 0x61420004, 0x00000000, 0x290e0000,
+       0x00000018, 0x80000002, 0x00000010, 0x91973206, 0x00000000, 0x35140000,
+       0x00000000, 0x35950000, 0x00000005, 0x766c2c00, 0x00000000, 0x34990000,
+       0x00000004, 0xb8f13200, 0x00000000, 0x83690c00, 0x00000010, 0xb1860013,
+       0x00000000, 0x28e90000, 0x00000008, 0x22000004, 0x00000000, 0x23ec0000,
+       0x00000000, 0x03690000, 0x00000010, 0xb8660c07, 0x00000009, 0x036cffff,
+       0x00000000, 0x326a0000, 0x00000000, 0x32eb0000, 0x00000005, 0x73e70c00,
+       0x00000000, 0x33690000, 0x00000005, 0x74680000, 0x0000000c, 0x73e7001c,
+       0x00000000, 0x03690000, 0x00000010, 0xb1f60c12, 0x00000010, 0xb1d00c11,
+       0x0000000c, 0x21420005, 0x0000000c, 0x33e7001c, 0x00000018, 0x8000000e,
+       0x00000010, 0x2e67000d, 0x00000000, 0x03690000, 0x00000010, 0xb1f60c0b,
+       0x00000010, 0xb1d00c0a, 0x00000000, 0x03440000, 0x00000008, 0x2200000c,
+       0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x00000018, 0x80000015,
+       0x0000000c, 0x33e7001c, 0x00000010, 0x20530000, 0x00000000, 0x22060000,
+       0x00000000, 0x290e0000, 0x00000018, 0x000d0000, 0x00000000, 0x06820000,
+       0x00000010, 0x2de7000d, 0x00000010, 0x0ce7000c, 0x00000000, 0x27f20000,
+       0x00000010, 0xb96d9e0a, 0x00000000, 0xa86d9e00, 0x00000009, 0x0361ffff,
+       0x00000010, 0xb7500c07, 0x00000008, 0x2200000f, 0x0000000f, 0x65680010,
+       0x00000000, 0x29000000, 0x00000018, 0x80000004, 0x0000000c, 0x33e7001b,
+       0x00000010, 0x20530000, 0x00000018, 0x000d0000, 0x00000000, 0x2b820000,
+       0x00000010, 0x20d2002f, 0x00000010, 0x0052002e, 0x00000009, 0x054e0007,
+       0x00000010, 0xb18a002c, 0x00000000, 0x050a8c00, 0x00000008, 0x850a0008,
+       0x00000010, 0x918a0029, 0x00000003, 0xc5008800, 0x00000008, 0xa3460001,
+       0x00000010, 0xb1c60007, 0x00000008, 0x22000001, 0x0000000c, 0x29800000,
+       0x00000010, 0x20530000, 0x00000000, 0x274e8c00, 0x00000000, 0x66cd0000,
+       0x00000000, 0x22c58c00, 0x00000008, 0x22000014, 0x00000003, 0x22c58e00,
+       0x00000003, 0x23c58e00, 0x00000003, 0x22c58e00, 0x00000003, 0x26cd9e00,
+       0x00000003, 0x27cd9e00, 0x00000003, 0x26cd9e00, 0x00000003, 0x274ea000,
+       0x00000003, 0x284ea000, 0x00000003, 0x274ea000, 0x0000000c, 0x69520000,
+       0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000003, 0x22c58e00,
+       0x00000003, 0x23c58e00, 0x00000003, 0x22c58e00, 0x00000003, 0x26cd9e00,
+       0x00000003, 0x27cd9e00, 0x00000003, 0x26cd9e00, 0x00000003, 0x274ea000,
+       0x00000003, 0x284ea000, 0x00000003, 0x274ea000, 0x00000000, 0xa2c58c00,
+       0x00000000, 0xa74e8c00, 0x00000000, 0xe6cd0000, 0x0000000f, 0x620a0010,
+       0x00000008, 0x23460001, 0x0000000c, 0x29800000, 0x00000010, 0x20530000,
+       0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000,
+       0x00000018, 0x00570000 };
+
+static int bnx2_TPAT_b06FwReleaseMajor = 0x0;
+static int bnx2_TPAT_b06FwReleaseMinor = 0x0;
+static int bnx2_TPAT_b06FwReleaseFix = 0x0;
+static u32 bnx2_TPAT_b06FwStartAddr = 0x08000858;
+static u32 bnx2_TPAT_b06FwTextAddr = 0x08000800;
+static int bnx2_TPAT_b06FwTextLen = 0x1314;
+static u32 bnx2_TPAT_b06FwDataAddr = 0x08001b40;
+static int bnx2_TPAT_b06FwDataLen = 0x0;
+static u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000;
+static int bnx2_TPAT_b06FwRodataLen = 0x0;
+static u32 bnx2_TPAT_b06FwBssAddr = 0x08001b90;
+static int bnx2_TPAT_b06FwBssLen = 0x80;
+static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001b40;
+static int bnx2_TPAT_b06FwSbssLen = 0x48;
+
+static u32 bnx2_TPAT_b06FwText[(0x1314/4) + 1] = {
+       0x0a000216, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20302e36,
+       0x2e390000, 0x00060901, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000003,
+       0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24421b40, 0x3c030800,
+       0x24631c10, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800,
+       0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100858, 0x3c1c0800, 0x279c1b40,
+       0x0e00051f, 0x00000000, 0x0000000d, 0x8f820024, 0x27bdffe8, 0xafbf0014,
+       0x10400004, 0xafb00010, 0x0000000d, 0x00000000, 0x2400015f, 0x8f82001c,
+       0x8c450008, 0x24030800, 0xaf430178, 0x97430104, 0x3c020008, 0xaf420140,
+       0x8f820034, 0x30420001, 0x10400006, 0x3070ffff, 0x24020002, 0x2603fffe,
+       0xa7420146, 0x0a000246, 0xa7430148, 0xa7400146, 0x8f850034, 0x30a20020,
+       0x0002102b, 0x00021023, 0x30460009, 0x30a30c00, 0x24020400, 0x14620002,
+       0x34c40001, 0x34c40005, 0xa744014a, 0x3c020800, 0x8c440820, 0x3c030048,
+       0x24020002, 0x00832025, 0x30a30006, 0x1062000d, 0x2c620003, 0x50400005,
+       0x24020004, 0x10600012, 0x3c020001, 0x0a000271, 0x00000000, 0x10620007,
+       0x24020006, 0x1462000f, 0x3c020111, 0x0a000269, 0x00821025, 0x0a000268,
+       0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030,
+       0x0a000271, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x8f830030, 0x1060003f, 0x3c048000,
+       0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039, 0x00000000,
+       0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000, 0x97421014,
+       0x14400031, 0x00000000, 0x97421008, 0x8f84001c, 0x24420006, 0x00024082,
+       0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001, 0x10400004,
+       0x00000000, 0x0000000d, 0x0a0002b0, 0x00081080, 0x5460000f, 0x30a5ffff,
+       0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b, 0x00621824,
+       0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fc, 0x8ce20000,
+       0x0a0002af, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b, 0x00621824,
+       0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000206, 0x8ce20000,
+       0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000, 0x8c620840,
+       0x24420001, 0xac620840, 0x8f820008, 0x10400003, 0x00000000, 0x0e000660,
+       0x00000000, 0x8f840028, 0x02002821, 0x24820008, 0x30421fff, 0x24434000,
+       0x0343d821, 0x30a30007, 0xaf840018, 0xaf820028, 0xaf420084, 0x10600002,
+       0x24a20007, 0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c,
+       0x0064102b, 0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044,
+       0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021, 0x03421821, 0x3c021000,
+       0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008, 0x27bd0018, 0x8f820024,
+       0x27bdffe8, 0xafbf0014, 0x10400004, 0xafb00010, 0x0000000d, 0x00000000,
+       0x24000249, 0x8f85001c, 0x24020001, 0xaf820024, 0x8ca70008, 0xa3800023,
+       0x8f620004, 0x3c100800, 0x26041b90, 0x00021402, 0xa3820010, 0x304600ff,
+       0x24c60005, 0x0e00064a, 0x00063082, 0x8f640004, 0x8f430108, 0x3c021000,
+       0x00621824, 0xa7840020, 0x10600008, 0x00000000, 0x97420104, 0x93830023,
+       0x2442ffec, 0x34630002, 0xa3830023, 0x0a000304, 0x3045ffff, 0x97420104,
+       0x2442fff0, 0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x14400004,
+       0x00000000, 0x93820023, 0x34420001, 0xa3820023, 0x93830023, 0x24020001,
+       0x10620009, 0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003,
+       0x1062000a, 0x00000000, 0x0a000325, 0x00000000, 0x8f82001c, 0x8c43000c,
+       0x3c04ffff, 0x00641824, 0x00651825, 0x0a000325, 0xac43000c, 0x8f82001c,
+       0x8c430010, 0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004,
+       0x3042ffff, 0x24420002, 0x00021083, 0xa3820038, 0x304500ff, 0x8f82001c,
+       0x3c04ffff, 0x00052880, 0x00a22821, 0x8ca70000, 0x97820020, 0x97430104,
+       0x00e42024, 0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x93840038,
+       0x26061b90, 0x00041080, 0x00461021, 0x90430000, 0x3063000f, 0x00832021,
+       0xa3840022, 0x308200ff, 0x3c04fff6, 0x24420003, 0x00021080, 0x00461021,
+       0x8c450000, 0x93830022, 0x8f82001c, 0x3484ffff, 0x00a43824, 0x00031880,
+       0x00621821, 0xaf850000, 0xac67000c, 0x93820022, 0x93830022, 0x8f84001c,
+       0x24420003, 0x00021080, 0x00461021, 0x24630004, 0x00031880, 0xac470000,
+       0x93820022, 0x00661821, 0x94670002, 0x00021080, 0x00441021, 0xac670000,
+       0x24030010, 0xac470010, 0xa7430140, 0x24030002, 0xa7400142, 0xa7400144,
+       0xa7430146, 0x97420104, 0x8f840034, 0x24030001, 0x2442fffe, 0x30840006,
+       0xa7420148, 0x24020002, 0xa743014a, 0x1082000d, 0x2c820003, 0x10400005,
+       0x24020004, 0x10800011, 0x3c020009, 0x0a000383, 0x00000000, 0x10820007,
+       0x24020006, 0x1482000d, 0x3c020119, 0x0a00037d, 0x24030001, 0x0a00037c,
+       0x3c020109, 0x3c020019, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000383,
+       0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x93820010, 0x24030008, 0x8f840030, 0x24420002, 0x30420007,
+       0x00621823, 0x30630007, 0xaf83000c, 0x10800005, 0x3c038000, 0x8f421000,
+       0x00431024, 0x1040fffd, 0x00000000, 0x8f820028, 0xaf820018, 0x24420010,
+       0x30421fff, 0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821,
+       0x3063ffff, 0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044,
+       0x8f840004, 0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002,
+       0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010,
+       0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178,
+       0x03e00008, 0x27bd0018, 0x8f820024, 0x27bdffe8, 0xafbf0014, 0x14400004,
+       0xafb00010, 0x0000000d, 0x00000000, 0x240002db, 0x8f620004, 0x04410009,
+       0x3c050800, 0x93820022, 0x8f830000, 0x24a41b90, 0xaf800024, 0x24420003,
+       0x00021080, 0x00441021, 0xac430000, 0x93820038, 0x24a51b90, 0x93860010,
+       0x3c040001, 0x27700008, 0x24420001, 0x00021080, 0x00451021, 0x8c430000,
+       0x24c60005, 0x00063082, 0x00641821, 0x02002021, 0x0e00064a, 0xac430000,
+       0x93840022, 0x3c057fff, 0x8f620004, 0x00042080, 0x00902021, 0x8c830004,
+       0x34a5ffff, 0x00451024, 0x00621821, 0xac830004, 0x93850038, 0x3c07ffff,
+       0x93840010, 0x00052880, 0x00b02821, 0x8ca30000, 0x97420104, 0x97860020,
+       0x00671824, 0x00441021, 0x00461023, 0x3042ffff, 0x00621825, 0xaca30000,
+       0x93830023, 0x24020001, 0x10620009, 0x28620002, 0x1440001a, 0x24020002,
+       0x10620018, 0x24020003, 0x1062000d, 0x00000000, 0x0a000411, 0x00000000,
+       0x93820010, 0x97430104, 0x8e04000c, 0x00621821, 0x2463fff2, 0x3063ffff,
+       0x00872024, 0x00832025, 0x0a000411, 0xae04000c, 0x93820010, 0x97430104,
+       0x8e040010, 0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025,
+       0xae040010, 0x9783000e, 0x8f840034, 0x2402000a, 0xa7420140, 0xa7430142,
+       0x93820010, 0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001,
+       0xa7430148, 0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005,
+       0x24020004, 0x10800011, 0x3c020041, 0x0a000437, 0x00000000, 0x10820007,
+       0x24020006, 0x1482000d, 0x3c020151, 0x0a000431, 0x24030001, 0x0a000430,
+       0x3c020141, 0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000437,
+       0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x8f820030, 0x93840010, 0x8f850028, 0x10400005, 0x3c038000,
+       0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x2483000a, 0x30620007,
+       0x10400002, 0x24620007, 0x304303f8, 0x00a31021, 0x30421fff, 0xaf850018,
+       0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff,
+       0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044, 0x8f840004,
+       0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002, 0x00641023,
+       0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021,
+       0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008,
+       0x27bd0018, 0x3c026000, 0x8c444448, 0x3c030800, 0xac64082c, 0x8f620000,
+       0x97430104, 0x3c048000, 0x3046ffff, 0x3067ffff, 0x8f420178, 0x00441024,
+       0x1440fffd, 0x2402000a, 0x30c30007, 0xa7420140, 0x24020008, 0x00431023,
+       0x30420007, 0x24c3fffe, 0xa7420142, 0xa7430144, 0xa7400146, 0xa7470148,
+       0x8f420108, 0x3c036000, 0x8f850034, 0x30420020, 0x0002102b, 0x00021023,
+       0x30420009, 0x34420001, 0xa742014a, 0x8c644448, 0x3c020800, 0x30a50006,
+       0xac440830, 0x24020002, 0x10a2000d, 0x2ca20003, 0x10400005, 0x24020004,
+       0x10a00011, 0x3c020041, 0x0a0004a8, 0x00000000, 0x10a20007, 0x24020006,
+       0x14a2000d, 0x3c020151, 0x0a0004a2, 0x24030001, 0x0a0004a1, 0x3c020141,
+       0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a0004a8, 0x00000000,
+       0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x8f820030, 0x24c30008, 0x10400006, 0x30e6ffff, 0x3c048000, 0x8f421000,
+       0x00441024, 0x1040fffd, 0x00000000, 0x3c026000, 0x8c444448, 0x3065ffff,
+       0x3c020800, 0x30a30007, 0x10600003, 0xac440834, 0x24a20007, 0x3045fff8,
+       0x8f840028, 0x00851021, 0x30421fff, 0x24434000, 0x0343d821, 0x30c30007,
+       0xaf840018, 0xaf820028, 0xaf420084, 0x10600002, 0x24c20007, 0x3046fff8,
+       0x8f820044, 0x8f840004, 0x00461821, 0xaf82002c, 0x0064102b, 0xaf830044,
+       0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x3c030800,
+       0x8c650844, 0x00821021, 0x03421821, 0xaf83001c, 0xaf440080, 0x10a00006,
+       0x2402000e, 0x93830043, 0x14620004, 0x3c021000, 0x2402043f, 0xa7420148,
+       0x3c021000, 0x3c036000, 0xaf420178, 0x8c644448, 0x3c020800, 0x03e00008,
+       0xac440838, 0x8f820034, 0x30424000, 0x10400005, 0x24020800, 0x0000000d,
+       0x00000000, 0x24000405, 0x24020800, 0xaf420178, 0x97440104, 0x3c030008,
+       0xaf430140, 0x8f820034, 0x30420001, 0x10400006, 0x3085ffff, 0x24020002,
+       0x24a3fffe, 0xa7420146, 0x0a0004ff, 0xa7430148, 0xa7400146, 0x8f840028,
+       0x2402000d, 0xa742014a, 0x24830008, 0x30631fff, 0x24624000, 0x0342d821,
+       0x30a20007, 0xaf840018, 0xaf830028, 0xaf430084, 0x10400002, 0x24a20007,
+       0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c, 0x0064102b,
+       0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000,
+       0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0x03e00008,
+       0xaf420178, 0x27bdffe8, 0x3c046008, 0xafbf0014, 0xafb00010, 0x8c825000,
+       0x3c1a8000, 0x2403ff7f, 0x375b4000, 0x00431024, 0x3442380c, 0xac825000,
+       0x8f430008, 0x3c100800, 0x37428000, 0x34630001, 0xaf430008, 0xaf82001c,
+       0x3c02601c, 0xaf800028, 0xaf400080, 0xaf400084, 0x8c450008, 0x3c036000,
+       0x8c620808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0, 0x38420010,
+       0x2c420001, 0xaf850004, 0xaf820008, 0x0e00062f, 0x00000000, 0x8f420000,
+       0x30420001, 0x1040fffb, 0x00000000, 0x8f440108, 0x30822000, 0xaf840034,
+       0x10400004, 0x8e02083c, 0x24420001, 0x0a00059d, 0xae02083c, 0x30820200,
+       0x10400027, 0x00000000, 0x97420104, 0x1040001c, 0x30824000, 0x14400005,
+       0x00000000, 0x0e00022d, 0x00000000, 0x0a000592, 0x00000000, 0x8f620008,
+       0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007, 0x28620031,
+       0x14400031, 0x24020040, 0x10620007, 0x00000000, 0x0a000592, 0x00000000,
+       0x0e0002dd, 0x00000000, 0x0a000592, 0x00000000, 0x0e0003b8, 0x00000000,
+       0x0a000592, 0x00000000, 0x30820040, 0x1440002d, 0x00000000, 0x0000000d,
+       0x00000000, 0x240004a6, 0x0a00059d, 0x00000000, 0x8f430100, 0x24020d00,
+       0x1462000f, 0x30820006, 0x97420104, 0x10400005, 0x30820040, 0x0e0004e9,
+       0x00000000, 0x0a000592, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d,
+       0x00000000, 0x240004b8, 0x0a00059d, 0x00000000, 0x1040000e, 0x30821000,
+       0x10400005, 0x00000000, 0x0e00065d, 0x00000000, 0x0a000592, 0x00000000,
+       0x0e00046b, 0x00000000, 0x8f820040, 0x24420001, 0xaf820040, 0x0a00059d,
+       0x00000000, 0x30820040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000,
+       0x240004cf, 0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a00053f,
+       0x00000000, 0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000,
+       0x00621824, 0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c,
+       0x34420001, 0xaf420008, 0x37428000, 0xaf800028, 0xaf82001c, 0xaf400080,
+       0xaf400084, 0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820,
+       0x3042fff0, 0x38420010, 0x2c420001, 0xaf860004, 0xaf820008, 0x03e00008,
+       0x00000000, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8,
+       0x8f820028, 0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf820018,
+       0xaf830028, 0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002,
+       0x24820007, 0x3044fff8, 0x8f820044, 0x8f830004, 0x00442021, 0xaf82002c,
+       0x0083102b, 0xaf840044, 0x14400002, 0x00831023, 0xaf820044, 0x8f820044,
+       0x34038000, 0x00431821, 0x03432021, 0xaf84001c, 0x03e00008, 0xaf420080,
+       0x8f830034, 0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005,
+       0x24020004, 0x10600012, 0x3c020001, 0x0a000601, 0x00000000, 0x10620007,
+       0x24020006, 0x1462000f, 0x3c020111, 0x0a0005f9, 0x00821025, 0x0a0005f8,
+       0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030,
+       0x0a000601, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000,
+       0x00000000, 0x00000000, 0x03e00008, 0x00000000, 0x8f820030, 0x10400005,
+       0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008,
+       0x00000000, 0x8f820034, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010,
+       0x0e00022d, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x8f620008, 0x8f630000,
+       0x24020030, 0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d,
+       0x8fbf0010, 0x24020040, 0x10620007, 0x00000000, 0x0a00062d, 0x00000000,
+       0x0e0002dd, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x0e0003b8, 0x00000000,
+       0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f84003c, 0x1080000f, 0x3c026000,
+       0x8c430c3c, 0x30630fff, 0xaf830014, 0x14600011, 0x3082000f, 0x10400005,
+       0x308200f0, 0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d,
+       0x00000000, 0x2400050e, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000,
+       0x24000513, 0x03e00008, 0x00000000, 0xaf83003c, 0x03e00008, 0x00000000,
+       0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000,
+       0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000659, 0x00a01021,
+       0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008,
+       0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x3c040800, 0x8c82084c,
+       0x54400007, 0xac80084c, 0x8f820034, 0x24030400, 0x30420c00, 0x1443005b,
+       0x00000000, 0xac80084c, 0x0000000d, 0x00000000, 0x2400003c, 0x3c026000,
+       0x8c444448, 0x3c030800, 0xac640850, 0x24000043, 0x97420104, 0x3045ffff,
+       0x000530c2, 0x24a2007f, 0x000239c2, 0x2400004e, 0x3c046020, 0x24030020,
+       0xac830000, 0x8c820000, 0x30420020, 0x10400005, 0x3c036020, 0x8c620000,
+       0x30420020, 0x1440fffd, 0x00000000, 0x3c026020, 0x8c430010, 0x24040001,
+       0x0087102b, 0x30ea007f, 0x24abfffe, 0x10400010, 0x00034240, 0x3c056020,
+       0x24090020, 0xaca90000, 0x8ca20000, 0x30420020, 0x10400006, 0x24840001,
+       0x3c036020, 0x8c620000, 0x30420020, 0x1440fffd, 0x00000000, 0x0087102b,
+       0x1440fff4, 0x00000000, 0x8f85001c, 0x3c026020, 0x8c430010, 0x3c046020,
+       0x34848000, 0x006a1825, 0x01034025, 0x2400006b, 0x10c0000b, 0x00000000,
+       0x8ca30000, 0x24a50004, 0x8ca20000, 0x24a50004, 0x24c6ffff, 0xac820000,
+       0x24840004, 0xac830000, 0x14c0fff7, 0x24840004, 0x24000077, 0x3c020007,
+       0x34427700, 0x3c036000, 0xac6223c8, 0xac6b23cc, 0xac6823e4, 0x24000086,
+       0x3c046000, 0x3c038000, 0x8c8223f8, 0x00431024, 0x1440fffd, 0x3c021000,
+       0x3c056000, 0x24030019, 0xaca223f8, 0xa743014a, 0x8ca44448, 0x3c020800,
+       0xac440854, 0x03e00008, 0x00000000, 0x00000000 };
+
+static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_TPAT_b06FwBss[(0x80/4) + 1] = { 0x00000000 };
+static u32 bnx2_TPAT_b06FwSbss[(0x48/4) + 1] = { 0x00000000 };
+
+static int bnx2_TXP_b06FwReleaseMajor = 0x0;
+static int bnx2_TXP_b06FwReleaseMinor = 0x0;
+static int bnx2_TXP_b06FwReleaseFix = 0x0;
+static u32 bnx2_TXP_b06FwStartAddr = 0x08002090;
+static u32 bnx2_TXP_b06FwTextAddr = 0x08000000;
+static int bnx2_TXP_b06FwTextLen = 0x3ffc;
+static u32 bnx2_TXP_b06FwDataAddr = 0x08004020;
+static int bnx2_TXP_b06FwDataLen = 0x0;
+static u32 bnx2_TXP_b06FwRodataAddr = 0x00000000;
+static int bnx2_TXP_b06FwRodataLen = 0x0;
+static u32 bnx2_TXP_b06FwBssAddr = 0x08004060;
+static int bnx2_TXP_b06FwBssLen = 0x194;
+static u32 bnx2_TXP_b06FwSbssAddr = 0x08004020;
+static int bnx2_TXP_b06FwSbssLen = 0x34;
+static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = {
+       0x0a000824, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x302e362e,
+       0x39000000, 0x00060900, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d,
+       0x0000000d, 0x3c020800, 0x24424020, 0x3c030800, 0x246341f4, 0xac400000,
+       0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021,
+       0x3c100800, 0x26102090, 0x3c1c0800, 0x279c4020, 0x0e000a0e, 0x00000000,
+       0x0000000d, 0x8f840014, 0x27bdffe8, 0xafb00010, 0x8f460104, 0x8f830008,
+       0x8c8500ac, 0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12,
+       0x8c8200ac, 0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0xa7420e16,
+       0x8f430e18, 0x00005021, 0x00c53023, 0x10c001a3, 0xaf430e1c, 0x240f0800,
+       0x3c0e1000, 0x2419fff8, 0x24100010, 0x3c188100, 0x93620008, 0x10400009,
+       0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000, 0x97620010,
+       0x3042ffff, 0x0a000862, 0xaf420e00, 0xaf460e00, 0x8f420000, 0x30420008,
+       0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff, 0x30820001,
+       0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a0009e6, 0x00000000,
+       0x0000000d, 0x3083a040, 0x24020040, 0x14620049, 0x3082a000, 0x8f87000c,
+       0x30880036, 0x30890008, 0xaf4f0178, 0x00e01821, 0x9742008a, 0x00431023,
+       0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa, 0x00000000, 0x8f830018,
+       0x00a05021, 0x00c53023, 0x24e24000, 0x03422821, 0x306b00ff, 0x24630001,
+       0xaf830018, 0x93840012, 0x000b1400, 0x3c030100, 0x00431025, 0xaca20000,
+       0x8f820018, 0x30840007, 0x00042240, 0x34870001, 0x00e83825, 0x1120000f,
+       0xaca20004, 0x97430e0a, 0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825,
+       0xaf430160, 0x25430006, 0x24840008, 0x30841fff, 0xa742015a, 0xa7430158,
+       0xaf84000c, 0x0a0008a9, 0x00000000, 0x8f83000c, 0x25420002, 0xa7420158,
+       0x24630008, 0x30631fff, 0xaf83000c, 0x54c0000c, 0x8f420e14, 0x97420e10,
+       0x97430e12, 0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014,
+       0x8f420e18, 0x34e70040, 0xaca200ac, 0x8f420e14, 0x8f430e1c, 0xaf420144,
+       0xaf430148, 0xa34b0152, 0xaf470154, 0x0a0009f1, 0xaf4e0178, 0x10400128,
+       0x00000000, 0x97620010, 0x00a2102b, 0x10400003, 0x30820040, 0x10400122,
+       0x00000000, 0xafa60008, 0xa7840010, 0xaf850004, 0x93620008, 0x1440005e,
+       0x27ac0008, 0xaf60000c, 0x97820010, 0x30424000, 0x10400002, 0x2403000e,
+       0x24030016, 0xa363000a, 0x24034007, 0xaf630014, 0x93820012, 0x8f630014,
+       0x30420007, 0x00021240, 0x00621825, 0xaf630014, 0x97820010, 0x8f630014,
+       0x30420010, 0x00621825, 0xaf630014, 0x97820010, 0x30420008, 0x5040000e,
+       0x00002821, 0x8f620014, 0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e,
+       0x00781825, 0xaf630004, 0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004,
+       0x0a0008f2, 0xa363000a, 0xaf600004, 0xa3600002, 0x97820010, 0x9363000a,
+       0x30421f00, 0x00021182, 0x24420028, 0x00621821, 0xa3630009, 0x97420e0c,
+       0xa7620010, 0x93630009, 0x24020008, 0x24630002, 0x30630007, 0x00431023,
+       0x30420007, 0xa362000b, 0x93640009, 0x97620010, 0x8f890004, 0x97830010,
+       0x00441021, 0x00a21021, 0x30630040, 0x10600006, 0x3045ffff, 0x15250005,
+       0x0125102b, 0x3c068000, 0x0a000925, 0x00005821, 0x0125102b, 0x144000c8,
+       0x00005021, 0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c,
+       0xaf420e18, 0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000,
+       0x97420e08, 0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001,
+       0xaf830004, 0x97620010, 0x0a000936, 0x304dffff, 0x8f890004, 0x97820010,
+       0x30420040, 0x10400004, 0x01206821, 0x3c068000, 0x0a000936, 0x00005821,
+       0x97630010, 0x8f820004, 0x144300a7, 0x00005021, 0x00003021, 0x240b0001,
+       0x8d820000, 0x00491023, 0x1440000d, 0xad820000, 0x8f620014, 0x34420040,
+       0xaf620014, 0x97430e10, 0x97420e12, 0x8f840014, 0x00031c00, 0x00431025,
+       0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003f,
+       0x00000000, 0x25260002, 0x8f84000c, 0x9743008a, 0x3063ffff, 0xafa30000,
+       0x8fa20000, 0x00441023, 0x2442ffff, 0x30421fff, 0x2c420010, 0x1440fff7,
+       0x00000000, 0x8f82000c, 0x8f830018, 0x00021082, 0x00021080, 0x24424000,
+       0x03422821, 0x00605021, 0x24630001, 0x314200ff, 0x00021400, 0xaf830018,
+       0x3c033200, 0x00431025, 0xaca20000, 0x93630009, 0x9362000a, 0x00031c00,
+       0x00431025, 0xaca20004, 0x8f830018, 0xaca30008, 0x97820010, 0x30420008,
+       0x10400002, 0x00c04021, 0x25280006, 0x97430e14, 0x93640002, 0x8f450e1c,
+       0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144, 0x97420e16,
+       0xa7420146, 0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a,
+       0xaf460160, 0xa7480158, 0xaf470154, 0xaf4e0178, 0x00501021, 0x30421fff,
+       0xaf82000c, 0x0a0009c5, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c,
+       0x2463000a, 0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff,
+       0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b,
+       0x1440fff7, 0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080,
+       0x24424000, 0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009,
+       0x310200ff, 0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025,
+       0xaca40000, 0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002,
+       0x8f450e1c, 0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144,
+       0x97420e16, 0x308400ff, 0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c,
+       0x25420007, 0x00591024, 0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154,
+       0xaf4e0178, 0x00621821, 0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005,
+       0x00000000, 0x8f620014, 0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c,
+       0x004d1021, 0xaf62000c, 0x93630008, 0x14600008, 0x00000000, 0x11600006,
+       0x00000000, 0x8f630014, 0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014,
+       0xa36b0008, 0x01205021, 0x15400016, 0x8fa60008, 0x97420e14, 0x97430e16,
+       0x8f850014, 0x00021400, 0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c,
+       0x0a0009f3, 0xac8200ac, 0x97420e14, 0x97430e16, 0x8f840014, 0x00021400,
+       0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c, 0x00005021, 0x0a0009f3,
+       0xaca200ac, 0x14c0fe64, 0x00000000, 0x55400018, 0x8fb00010, 0x3c038000,
+       0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97430e14, 0x8f440e1c,
+       0x24020800, 0xaf420178, 0x3063ffff, 0xa7430144, 0x97420e16, 0x3c031000,
+       0xa7420146, 0x24020240, 0xaf440148, 0xa3400152, 0xa740015a, 0xaf400160,
+       0xa7400158, 0xaf420154, 0xaf430178, 0x8fb00010, 0x03e00008, 0x27bd0018,
+       0x27bdffd8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821,
+       0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014,
+       0xaf440e00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00, 0x8c835000, 0x24130d00,
+       0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c, 0x24020009,
+       0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000,
+       0x0e000a96, 0x00000000, 0x3c020800, 0x24504080, 0x8f420000, 0x30420001,
+       0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020, 0x93430108,
+       0xa3830012, 0x93820012, 0x30420001, 0x10400008, 0x00000000, 0x93820012,
+       0x30420006, 0x00021100, 0x0e00083b, 0x0050d821, 0x0a000a52, 0x00000000,
+       0x14930005, 0x00000000, 0x0e00083b, 0x265b4100, 0x0a000a52, 0x00000000,
+       0x0e000ba3, 0x00000000, 0xaf510138, 0x0a000a36, 0x00000000, 0x27bdfff8,
+       0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c, 0x9743008a, 0x3063ffff,
+       0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b,
+       0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082, 0x00021080, 0x24424000,
+       0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff, 0x8f82000c, 0x24840007,
+       0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c, 0x03e00008, 0x00000000,
+       0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821,
+       0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00,
+       0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c, 0x24030009, 0xac825000,
+       0xaf430008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000, 0x0e000a96,
+       0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c02000a,
+       0x03421821, 0x3c040800, 0x24844120, 0x24050018, 0xafbf0010, 0xaf830024,
+       0x0e000fad, 0x00003021, 0x3c050800, 0x3c020800, 0x24423d60, 0xaca24180,
+       0x24a54180, 0x3c020800, 0x24423e18, 0x3c030800, 0x24633e2c, 0x3c040800,
+       0xaca20004, 0x3c020800, 0x24423d68, 0xaca30008, 0xac824190, 0x24844190,
+       0x3c020800, 0x24423da4, 0x3c070800, 0x24e73de4, 0x3c060800, 0x24c63e40,
+       0x3c050800, 0x24a52b28, 0x3c030800, 0xac820004, 0x3c020800, 0x24423e48,
+       0xac870008, 0xac86000c, 0xac850010, 0xac6241b0, 0x246341b0, 0x8fbf0010,
+       0x3c020800, 0x24423e60, 0xac620004, 0xac670008, 0xac66000c, 0xac650010,
+       0x03e00008, 0x27bd0018, 0x27bdffc8, 0x3c020800, 0x24424120, 0xafbf0030,
+       0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x90470021, 0x8c510008,
+       0x8c45001c, 0x8f900020, 0x3c060800, 0x3c038000, 0x8f420178, 0x00431024,
+       0x1440fffd, 0x8cc2414c, 0x24c3414c, 0x2473ffd4, 0xaf420144, 0x8e620030,
+       0x30b22000, 0xaf420148, 0x3c021000, 0xaf50014c, 0xa3470152, 0xa7510158,
+       0xaf450154, 0xaf420178, 0x12400004, 0x3c030800, 0x8c620030, 0x24420001,
+       0xac620030, 0x93420109, 0x9344010a, 0x00111c00, 0xafa30018, 0x00071a00,
+       0xafa50014, 0x8cc5414c, 0x00021600, 0x00042400, 0x00441025, 0x00431025,
+       0xafa20010, 0x8f440100, 0x8e660030, 0x0e000fe1, 0x02003821, 0x1640000e,
+       0x8fbf0030, 0x8f820000, 0x8e630030, 0x8c44017c, 0x02031823, 0x00711823,
+       0x00641823, 0x2c630002, 0x14600006, 0x8fb3002c, 0x0000000d, 0x00000000,
+       0x240000ca, 0x8fbf0030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
+       0x03e00008, 0x27bd0038, 0x974309da, 0x00804021, 0xad030000, 0x8f4209dc,
+       0xad020004, 0x8f4309e0, 0xad030008, 0x934409d9, 0x24020001, 0x30840003,
+       0x1082001f, 0x30a900ff, 0x28820002, 0x10400005, 0x24020002, 0x10800009,
+       0x3c0a0800, 0x0a000b64, 0x93420934, 0x1082000b, 0x24020003, 0x10820026,
+       0x3c0a0800, 0x0a000b64, 0x93420934, 0x974209e4, 0x00021400, 0x34420800,
+       0xad02000c, 0x0a000b63, 0x25080010, 0x974209e4, 0x00021400, 0x34428100,
+       0xad02000c, 0x974309e8, 0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010,
+       0x0a000b63, 0x25080014, 0x974409e4, 0x3c050800, 0x24a24120, 0x94430018,
+       0x94460010, 0x9447000c, 0x00a05021, 0x24020800, 0xad000010, 0xad020014,
+       0x00042400, 0x00661821, 0x00671823, 0x2463fff2, 0x00832025, 0xad04000c,
+       0x0a000b63, 0x25080018, 0x974209e4, 0x3c050800, 0x00021400, 0x34428100,
+       0xad02000c, 0x974409e8, 0x24a24120, 0x94430018, 0x94460010, 0x9447000c,
+       0x00a05021, 0x24020800, 0xad000014, 0xad020018, 0x00042400, 0x00661821,
+       0x00671823, 0x2463ffee, 0x00832025, 0xad040010, 0x2508001c, 0x93420934,
+       0x93450921, 0x3c074000, 0x25444120, 0x94830014, 0x94860010, 0x00021082,
+       0x00021600, 0x00052c00, 0x00a72825, 0x00451025, 0x00661821, 0x00431025,
+       0xad020000, 0x97830028, 0x974209ea, 0x00621821, 0x00031c00, 0xad030004,
+       0x97820028, 0x24420001, 0x30427fff, 0xa7820028, 0x93430920, 0x3c020006,
+       0x00031e00, 0x00621825, 0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930,
+       0xad030010, 0x8f440938, 0x25080014, 0xad040000, 0x8f820020, 0x11200004,
+       0xad020004, 0x8f420940, 0x0a000b8d, 0x2442ffff, 0x8f420940, 0xad020008,
+       0x8f440948, 0x8f420940, 0x93430936, 0x00822823, 0x00652806, 0x3402ffff,
+       0x0045102b, 0x54400001, 0x3405ffff, 0x93420937, 0x25444120, 0x90830020,
+       0xad000010, 0x00021700, 0x34630010, 0x00031c00, 0x00431025, 0x00451025,
+       0xad02000c, 0x03e00008, 0x25020014, 0x27bdffb0, 0x3c020008, 0x03421821,
+       0xafbf004c, 0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038,
+       0xafb30034, 0xafb20030, 0xafb1002c, 0xafb00028, 0xaf830000, 0x24020040,
+       0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954, 0x8f45095c,
+       0xaf820030, 0xaf830020, 0xaf84001c, 0xaf85002c, 0x93430900, 0x24020020,
+       0x10620005, 0x24020030, 0x10620022, 0x3c030800, 0x0a000bf1, 0x8c62002c,
+       0x24020088, 0xaf420818, 0x3c020800, 0x24424180, 0xafa20020, 0x93430109,
+       0x3c020800, 0x10600009, 0x24574190, 0x3c026000, 0x24030100, 0xac43081c,
+       0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x2400031d, 0x9342010a,
+       0x30420080, 0x1440001c, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c,
+       0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000324, 0x0a000bf4,
+       0x00000000, 0x93430109, 0x3063007f, 0x00031140, 0x000318c0, 0x00431021,
+       0x24430088, 0xaf430818, 0x0000000d, 0x3c020800, 0x244241d0, 0x3c030800,
+       0x247741e0, 0x0a000bf4, 0xafa20020, 0x24420001, 0x0a000f4c, 0xac62002c,
+       0x8f840000, 0x8f850020, 0x24020800, 0xaf420178, 0x8f4209a4, 0x8c83017c,
+       0x00a21023, 0x00431023, 0x2c420002, 0x14400004, 0x00000000, 0x0000000d,
+       0x00000000, 0x24000349, 0x8f420104, 0x8f430988, 0x00431023, 0x58400005,
+       0x8f4209a0, 0x0000000d, 0x00000000, 0x2400034d, 0x8f4209a0, 0x3c100800,
+       0xae02414c, 0x8f4309a4, 0x2604414c, 0x2491ffd4, 0xae230030, 0x8f420104,
+       0xae250024, 0x00431023, 0xac82ffd4, 0x8fa30020, 0x8c620000, 0x0040f809,
+       0x0200b021, 0x00409021, 0x32440010, 0x32420002, 0x10400007, 0xafa40024,
+       0x8e22001c, 0x32500040, 0x2403ffbf, 0x00431024, 0x0a000f13, 0xae22001c,
+       0x32420020, 0x10400002, 0x3c020800, 0x245741b0, 0x32420001, 0x14400007,
+       0x00000000, 0x8f820008, 0xaf420080, 0x8ec3414c, 0xaf430e10, 0x8e220030,
+       0xaf420e18, 0x9343010b, 0x93420905, 0x30420008, 0x1040003c, 0x307400ff,
+       0x8f820000, 0x8c430074, 0x0460000a, 0x00000000, 0x3c026000, 0x24030100,
+       0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000384,
+       0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32500040, 0x24072000,
+       0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c,
+       0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100, 0xaf420148,
+       0x24020047, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158,
+       0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001,
+       0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600,
+       0x00031c00, 0x00431025, 0x34424700, 0xafa20010, 0x8f440100, 0x0e000fe1,
+       0x3c070100, 0x3c030800, 0x24624120, 0x0a000d01, 0x8c43001c, 0x32820002,
+       0x10400047, 0x3c039000, 0x34630001, 0x8f820008, 0x32500040, 0x3c048000,
+       0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
+       0x8f830000, 0x90620005, 0x3c058000, 0x34420008, 0xa0620005, 0x8f860000,
+       0x34a50001, 0x8f840008, 0x8cc20074, 0x3c038000, 0x00852025, 0x00431025,
+       0xacc20074, 0xaf440020, 0x90c3007b, 0x9342010a, 0x14620028, 0x3c040800,
+       0x24072000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
+       0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100,
+       0xaf420148, 0x24020046, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000,
+       0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030,
+       0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018,
+       0x00021600, 0x00031c00, 0x00431025, 0x34424600, 0xafa20010, 0x8f440100,
+       0x0e000fe1, 0x3c070100, 0x3c040800, 0x24824120, 0x0a000d01, 0x8c43001c,
+       0x93420108, 0x30420010, 0x50400050, 0x9343093f, 0x8f860000, 0x90c3007f,
+       0x90c2007e, 0x90c40080, 0x306800ff, 0x00021600, 0x00081c00, 0x00431025,
+       0x00042200, 0x90c3007a, 0x90c5000a, 0x00441025, 0x11050028, 0x00623825,
+       0xa0c8000a, 0x24086000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
+       0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030,
+       0x00001821, 0xaf420148, 0x24020052, 0xaf47014c, 0xa3420152, 0x3c021000,
+       0xa7430158, 0xaf480154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030,
+       0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa80014, 0xafa00018,
+       0x00021600, 0x00031c00, 0x00431025, 0x34425200, 0xafa20010, 0x0e000fe1,
+       0x8f440100, 0x0a000cfb, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c,
+       0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003cd, 0x16800009,
+       0x3c040800, 0x3c030800, 0x24624120, 0x8c43001c, 0x32500040, 0x2404ffbf,
+       0x00641824, 0x0a000f13, 0xac43001c, 0x8c824120, 0x10400005, 0x3c030800,
+       0x8c620034, 0xac804120, 0x24420001, 0xac620034, 0x9343093f, 0x24020012,
+       0x1462000f, 0x329e0038, 0x17c0000c, 0x3c030800, 0x8f830000, 0x8c62004c,
+       0xac62005c, 0x3c020800, 0x24444120, 0x8c82001c, 0x32500040, 0x2403ffbf,
+       0x00431024, 0x0a000f13, 0xac82001c, 0xac604120, 0x97420908, 0x000211c0,
+       0xaf420024, 0x97420908, 0x3c030080, 0x34630003, 0x000211c0, 0xaf42080c,
+       0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa7820028, 0x3c020800, 0x24444120,
+       0xac830028, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830014,
+       0x934209d8, 0x00621821, 0xa4830016, 0x934209d8, 0x93430934, 0x00809821,
+       0x00431021, 0x24420010, 0xa4820012, 0x0000a821, 0x24020006, 0x13c00003,
+       0xae62001c, 0x0a000d82, 0x24120008, 0x8f420958, 0x8f830020, 0x8f84002c,
+       0x00431023, 0x00832023, 0x04800003, 0xae620004, 0x04410003, 0x0082102b,
+       0x0a000d4e, 0xae600004, 0x54400001, 0xae640004, 0x8ee20000, 0x0040f809,
+       0x00000000, 0x00409021, 0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008,
+       0x1060002b, 0x3c02c000, 0x00621025, 0xaf420e00, 0x8f420000, 0x30420008,
+       0x1040fffd, 0x00000000, 0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008,
+       0xaf830004, 0x8f840004, 0x0044102b, 0x1040000b, 0x24150001, 0x24020100,
+       0x3c016000, 0xac22081c, 0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d,
+       0x00000000, 0x24000449, 0x24150001, 0x8ee20004, 0x0040f809, 0x00000000,
+       0x02429025, 0x32420002, 0x5040001d, 0x8f470940, 0x12a00006, 0x8ec2414c,
+       0x8f830000, 0xac6200a8, 0x8f840000, 0x8e620030, 0xac8200ac, 0x32420004,
+       0x50400013, 0x8f470940, 0x3c020800, 0x3283007d, 0x106000fe, 0x245741b0,
+       0x32820001, 0x50400006, 0x36520002, 0x8f830030, 0x8f420940, 0x106200f7,
+       0x00000000, 0x36520002, 0x24020008, 0xa660000c, 0xa662000e, 0xae600008,
+       0xa2600020, 0x8f470940, 0x3c030800, 0x24684120, 0x8d020028, 0x8d050008,
+       0x9504000c, 0x9506000a, 0x95030022, 0x00451021, 0x00862021, 0x00641821,
+       0xaf870030, 0xad020028, 0x32820030, 0x10400006, 0xa5030010, 0x91020020,
+       0x32910040, 0x34420004, 0x0a000dd4, 0xa1020020, 0x93420923, 0x30420040,
+       0x10400029, 0x32910040, 0x8f830000, 0x8f840020, 0x8c620084, 0x00441023,
+       0x0442000a, 0x3c039000, 0x95020010, 0x8c630084, 0x00821021, 0x00621823,
+       0x1c600004, 0x3c039000, 0x91020020, 0x34420001, 0xa1020020, 0x34630001,
+       0x8f820008, 0x32910040, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020,
+       0x00441024, 0x1440fffd, 0x00000000, 0x8f840000, 0x9083003f, 0x2402000a,
+       0x10620005, 0x2402000c, 0x9083003f, 0x24020008, 0x14620002, 0x24020014,
+       0xa082003f, 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020,
+       0x3c040800, 0x24904120, 0x9602000c, 0x96030016, 0x9604000e, 0x00431021,
+       0x00442021, 0x24840002, 0x3084ffff, 0x0e000a55, 0xa6020018, 0x8f850018,
+       0x00a01821, 0xa2030021, 0x8ee60008, 0x00402021, 0x24a50001, 0xaf850018,
+       0x00c0f809, 0x00000000, 0x00402021, 0x0e000b12, 0x02202821, 0x8ee3000c,
+       0x0060f809, 0x00402021, 0x96040018, 0x9602000e, 0x00822021, 0x24840002,
+       0x0e000a6b, 0x3084ffff, 0x3c030800, 0x8c624120, 0x8e030008, 0x3c040800,
+       0x00431023, 0x14400012, 0xac824120, 0x54600006, 0x8e02001c, 0x3243004a,
+       0x24020002, 0x14620005, 0x00000000, 0x8e02001c, 0x34420040, 0x0a000e0b,
+       0xae02001c, 0x52a00006, 0x36520002, 0x8e02002c, 0xaf420e10, 0x8e030030,
+       0xaf430e18, 0x36520002, 0x52a00008, 0x96670010, 0x8f830000, 0x8f420e10,
+       0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670010, 0x92680020,
+       0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821, 0x00621023,
+       0xaf830020, 0x58400005, 0x8f42095c, 0x8f820000, 0xaf83001c, 0xac430054,
+       0x8f42095c, 0x31030008, 0xaf82002c, 0x1060001a, 0x00000000, 0x8f840000,
+       0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007, 0x24020007,
+       0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122, 0x8f850000,
+       0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001, 0x30630007,
+       0xac440000, 0x0a000e40, 0xa0a30120, 0x90820122, 0x34420001, 0xa0820122,
+       0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000, 0x8c43000c,
+       0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008, 0x34420001,
+       0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd,
+       0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018, 0x00000000,
+       0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068, 0x90e40081,
+       0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
+       0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001, 0x00c02021,
+       0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c, 0x8f830008,
+       0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f830020, 0x3c020800,
+       0x24504120, 0xae030024, 0x8ee20010, 0x0040f809, 0x00000000, 0x12a00005,
+       0x00000000, 0x8f420e10, 0xae02002c, 0x8f430e18, 0xae030030, 0x1220feba,
+       0x0000a821, 0x8f870024, 0x97860028, 0x8f830000, 0x8f820030, 0x8f840020,
+       0x8f85001c, 0x32500040, 0xa4e6002c, 0xac620044, 0x32420008, 0xac640050,
+       0xac650054, 0x1040007a, 0x32820020, 0x10400027, 0x32910010, 0x24072000,
+       0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c,
+       0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030400, 0xaf420148,
+       0x24020041, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158,
+       0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001,
+       0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600,
+       0x00031c00, 0x00431025, 0x34424100, 0xafa20010, 0x8f440100, 0x0e000fe1,
+       0x3c070400, 0x12200028, 0x24072000, 0x3c090800, 0x3c038000, 0x8f420178,
+       0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144,
+       0x8c820030, 0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0x00001821,
+       0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c,
+       0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a,
+       0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424e00,
+       0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070300, 0x0a000f0b, 0x8fa30024,
+       0x32820008, 0x10400026, 0x3c090800, 0x24072000, 0x3c038000, 0x8f420178,
+       0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144,
+       0x8c820030, 0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0x00001821,
+       0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c,
+       0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a,
+       0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424b00,
+       0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070200, 0x8fa30024, 0x14600004,
+       0x8fa40020, 0x32420010, 0x10400004, 0x00000000, 0x8c820004, 0x0040f809,
+       0x00000000, 0x12000006, 0x8fa30020, 0x8c620008, 0x0040f809, 0x00000000,
+       0x0a000f4d, 0x8fbf004c, 0x3c030800, 0x8c62413c, 0x30420040, 0x1440002f,
+       0x8fbf004c, 0x24040040, 0x8f910020, 0x3c038000, 0x8f420178, 0x00431024,
+       0x1440fffd, 0x8ec2414c, 0x26d0414c, 0x2610ffd4, 0xaf420144, 0x8e020030,
+       0x00001821, 0xaf420148, 0x24020049, 0xaf51014c, 0xa3420152, 0x3c021000,
+       0xa7430158, 0xaf440154, 0xaf420178, 0x8ec5414c, 0x8e060030, 0x93420109,
+       0x9343010a, 0xafa40014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025,
+       0x34424900, 0xafa20010, 0x8f440100, 0x0e000fe1, 0x02203821, 0x8f830000,
+       0x8e020030, 0x8c64017c, 0x02221023, 0x00441023, 0x2c420002, 0x14400005,
+       0x8fbf004c, 0x0000000d, 0x00000000, 0x240000ca, 0x8fbf004c, 0x8fbe0048,
+       0x8fb70044, 0x8fb60040, 0x8fb5003c, 0x8fb40038, 0x8fb30034, 0x8fb20030,
+       0x8fb1002c, 0x8fb00028, 0x03e00008, 0x27bd0050, 0x03e00008, 0x00001021,
+       0x3c030800, 0x24654120, 0x8ca40004, 0x8c634120, 0x0064102b, 0x54400001,
+       0x00602021, 0x9743093c, 0x0083102b, 0x54400001, 0x00801821, 0x00001021,
+       0xaca30008, 0x03e00008, 0xa4a00022, 0x8f850004, 0x97840010, 0x3c030800,
+       0x24634120, 0x24020008, 0xa462000e, 0x8f820004, 0xa460000c, 0x000420c2,
+       0x30840008, 0x2c420001, 0x00021023, 0x30420006, 0xac650008, 0x03e00008,
+       0xa0640020, 0x3c020800, 0x24424120, 0x90450021, 0x94430018, 0x3c021100,
+       0xac800004, 0x00052c00, 0x24630002, 0x00621825, 0x00a32825, 0x24820008,
+       0x03e00008, 0xac850000, 0x0000000d, 0x00000000, 0x2400016f, 0x03e00008,
+       0x00000000, 0x0000000d, 0x00000000, 0x2400017b, 0x03e00008, 0x00000000,
+       0x03e00008, 0x00000000, 0x3c020800, 0x24424120, 0xac400008, 0xa4400022,
+       0x03e00008, 0x24020001, 0x3c020800, 0x24424120, 0x24030008, 0xac400008,
+       0xa440000c, 0xa443000e, 0xa0400020, 0x03e00008, 0x24020004, 0x03e00008,
+       0x00001021, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004,
+       0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000fb2,
+       0x00a01021, 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff,
+       0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068, 0x3c050800, 0x24a51090,
+       0x00093140, 0x00c51021, 0xac440000, 0x8f440e04, 0x00a61021, 0xac440004,
+       0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00, 0x00431025, 0xac820008,
+       0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14, 0xac440010, 0x8f430e18,
+       0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff, 0x25290001, 0xac470018,
+       0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000, 0x24630001, 0xace3006c,
+       0x8c434448, 0x3129007f, 0x00a62821, 0xad490068, 0x00042600, 0x00681824,
+       0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010, 0x8fad0014, 0x8fae0018,
+       0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080078, 0x000a4940, 0x01281021,
+       0x01091821, 0xac440000, 0x00601021, 0xac650004, 0xac460008, 0xac67000c,
+       0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018, 0x8c654448, 0x3c040800,
+       0x8c820064, 0x254a0001, 0x314a007f, 0x01094021, 0xad6a0060, 0x24420001,
+       0xac820064, 0x03e00008, 0xad05001c, 0x00000000 };
+
+static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
+static u32 bnx2_TXP_b06FwBss[(0x194/4) + 1] = { 0x00000000 };
+static u32 bnx2_TXP_b06FwSbss[(0x34/4) + 1] = { 0x00000000 };
+
index 770e28f98fd5329a7434c47be96d3f85f1cf33dc..269a5e407349e90e3c9c7f681979eea9732c5c17 100644 (file)
@@ -3037,7 +3037,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev)
                        bond_set_slave_inactive_flags(bond->current_arp_slave);
 
                        /* search for next candidate */
-                       bond_for_each_slave_from(bond, slave, i, bond->current_arp_slave) {
+                       bond_for_each_slave_from(bond, slave, i, bond->current_arp_slave->next) {
                                if (IS_UP(slave->dev)) {
                                        slave->link = BOND_LINK_BACK;
                                        bond_set_slave_active_flags(slave);
index 1b68dd5a49b6505ed133442273b910cf2898a3fc..4a47df5a9ff9c076ddee640a437eca7f7c9348c9 100644 (file)
 
 #define DRV_NAME               "e100"
 #define DRV_EXT                "-NAPI"
-#define DRV_VERSION            "3.3.6-k2"DRV_EXT
+#define DRV_VERSION            "3.4.8-k2"DRV_EXT
 #define DRV_DESCRIPTION                "Intel(R) PRO/100 Network Driver"
-#define DRV_COPYRIGHT          "Copyright(c) 1999-2004 Intel Corporation"
+#define DRV_COPYRIGHT          "Copyright(c) 1999-2005 Intel Corporation"
 #define PFX                    DRV_NAME ": "
 
 #define E100_WATCHDOG_PERIOD   (2 * HZ)
@@ -210,11 +210,17 @@ static struct pci_device_id e100_id_table[] = {
        INTEL_8255X_ETHERNET_DEVICE(0x1069, 6),
        INTEL_8255X_ETHERNET_DEVICE(0x106A, 6),
        INTEL_8255X_ETHERNET_DEVICE(0x106B, 6),
+       INTEL_8255X_ETHERNET_DEVICE(0x1091, 7),
+       INTEL_8255X_ETHERNET_DEVICE(0x1092, 7),
+       INTEL_8255X_ETHERNET_DEVICE(0x1093, 7),
+       INTEL_8255X_ETHERNET_DEVICE(0x1094, 7),
+       INTEL_8255X_ETHERNET_DEVICE(0x1095, 7),
        INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
        INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
        INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
        INTEL_8255X_ETHERNET_DEVICE(0x2459, 2),
        INTEL_8255X_ETHERNET_DEVICE(0x245D, 2),
+       INTEL_8255X_ETHERNET_DEVICE(0x27DC, 7),
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, e100_id_table);
@@ -269,6 +275,12 @@ enum scb_status {
        rus_mask         = 0x3C,
 };
 
+enum ru_state  {
+       RU_SUSPENDED = 0,
+       RU_RUNNING       = 1,
+       RU_UNINITIALIZED = -1,
+};
+
 enum scb_stat_ack {
        stat_ack_not_ours    = 0x00,
        stat_ack_sw_gen      = 0x04,
@@ -510,7 +522,7 @@ struct nic {
        struct rx *rx_to_use;
        struct rx *rx_to_clean;
        struct rfd blank_rfd;
-       int ru_running;
+       enum ru_state ru_running;
 
        spinlock_t cb_lock                      ____cacheline_aligned;
        spinlock_t cmd_lock;
@@ -539,6 +551,7 @@ struct nic {
        struct timer_list watchdog;
        struct timer_list blink_timer;
        struct mii_if_info mii;
+       struct work_struct tx_timeout_task;
        enum loopback loopback;
 
        struct mem *mem;
@@ -770,7 +783,7 @@ static int e100_eeprom_save(struct nic *nic, u16 start, u16 count)
        return 0;
 }
 
-#define E100_WAIT_SCB_TIMEOUT 40
+#define E100_WAIT_SCB_TIMEOUT 20000 /* we might have to wait 100ms!!! */
 static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
 {
        unsigned long flags;
@@ -840,6 +853,10 @@ static inline int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
                         * because the controller is too busy, so
                         * let's just queue the command and try again
                         * when another command is scheduled. */
+                       if(err == -ENOSPC) {
+                               //request a reset
+                               schedule_work(&nic->tx_timeout_task);
+                       }
                        break;
                } else {
                        nic->cuc_cmd = cuc_resume;
@@ -884,7 +901,7 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
 
 static void e100_get_defaults(struct nic *nic)
 {
-       struct param_range rfds = { .min = 64, .max = 256, .count = 64 };
+       struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
        struct param_range cbs  = { .min = 64, .max = 256, .count = 64 };
 
        pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
@@ -899,8 +916,9 @@ static void e100_get_defaults(struct nic *nic)
        /* Quadwords to DMA into FIFO before starting frame transmit */
        nic->tx_threshold = 0xE0;
 
-       nic->tx_command = cpu_to_le16(cb_tx | cb_i | cb_tx_sf |
-               ((nic->mac >= mac_82558_D101_A4) ? cb_cid : 0));
+       /* no interrupt for every tx completion, delay = 256us if not 557*/
+       nic->tx_command = cpu_to_le16(cb_tx | cb_tx_sf |
+               ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
 
        /* Template for a freshly allocated RFD */
        nic->blank_rfd.command = cpu_to_le16(cb_el);
@@ -964,7 +982,8 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
        if(nic->flags & multicast_all)
                config->multicast_all = 0x1;            /* 1=accept, 0=no */
 
-       if(!(nic->flags & wol_magic))
+       /* disable WoL when up */
+       if(netif_running(nic->netdev) || !(nic->flags & wol_magic))
                config->magic_packet_disable = 0x1;     /* 1=off, 0=on */
 
        if(nic->mac >= mac_82558_D101_A4) {
@@ -1203,7 +1222,9 @@ static void e100_update_stats(struct nic *nic)
                }
        }
 
-       e100_exec_cmd(nic, cuc_dump_reset, 0);
+       
+       if(e100_exec_cmd(nic, cuc_dump_reset, 0))
+               DPRINTK(TX_ERR, DEBUG, "exec cuc_dump_reset failed\n");
 }
 
 static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex)
@@ -1279,12 +1300,15 @@ static inline void e100_xmit_prepare(struct nic *nic, struct cb *cb,
        struct sk_buff *skb)
 {
        cb->command = nic->tx_command;
+       /* interrupt every 16 packets regardless of delay */
+       if((nic->cbs_avail & ~15) == nic->cbs_avail) cb->command |= cb_i;
        cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd);
        cb->u.tcb.tcb_byte_count = 0;
        cb->u.tcb.threshold = nic->tx_threshold;
        cb->u.tcb.tbd_count = 1;
        cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev,
                skb->data, skb->len, PCI_DMA_TODEVICE));
+       // check for mapping failure?
        cb->u.tcb.tbd.size = cpu_to_le16(skb->len);
 }
 
@@ -1297,7 +1321,8 @@ static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                /* SW workaround for ICH[x] 10Mbps/half duplex Tx hang.
                   Issue a NOP command followed by a 1us delay before
                   issuing the Tx command. */
-               e100_exec_cmd(nic, cuc_nop, 0);
+               if(e100_exec_cmd(nic, cuc_nop, 0))
+                       DPRINTK(TX_ERR, DEBUG, "exec cuc_nop failed\n");
                udelay(1);
        }
 
@@ -1415,12 +1440,18 @@ static int e100_alloc_cbs(struct nic *nic)
        return 0;
 }
 
-static inline void e100_start_receiver(struct nic *nic)
+static inline void e100_start_receiver(struct nic *nic, struct rx *rx)
 {
+       if(!nic->rxs) return;
+       if(RU_SUSPENDED != nic->ru_running) return;
+
+       /* handle init time starts */
+       if(!rx) rx = nic->rxs;
+
        /* (Re)start RU if suspended or idle and RFA is non-NULL */
-       if(!nic->ru_running && nic->rx_to_clean->skb) {
-               e100_exec_cmd(nic, ruc_start, nic->rx_to_clean->dma_addr);
-               nic->ru_running = 1;
+       if(rx->skb) {
+               e100_exec_cmd(nic, ruc_start, rx->dma_addr);
+               nic->ru_running = RU_RUNNING;
        }
 }
 
@@ -1437,6 +1468,13 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
        rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
                RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
 
+       if(pci_dma_mapping_error(rx->dma_addr)) {
+               dev_kfree_skb_any(rx->skb);
+               rx->skb = 0;
+               rx->dma_addr = 0;
+               return -ENOMEM;
+       }
+
        /* Link the RFD to end of RFA by linking previous RFD to
         * this one, and clearing EL bit of previous.  */
        if(rx->prev->skb) {
@@ -1471,7 +1509,7 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx,
 
        /* If data isn't ready, nothing to indicate */
        if(unlikely(!(rfd_status & cb_complete)))
-               return -EAGAIN;
+               return -ENODATA;
 
        /* Get actual data size */
        actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF;
@@ -1482,6 +1520,10 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx,
        pci_unmap_single(nic->pdev, rx->dma_addr,
                RFD_BUF_LEN, PCI_DMA_FROMDEVICE);
 
+       /* this allows for a fast restart without re-enabling interrupts */
+       if(le16_to_cpu(rfd->command) & cb_el)
+               nic->ru_running = RU_SUSPENDED;
+
        /* Pull off the RFD and put the actual data (minus eth hdr) */
        skb_reserve(skb, sizeof(struct rfd));
        skb_put(skb, actual_size);
@@ -1514,20 +1556,45 @@ static inline void e100_rx_clean(struct nic *nic, unsigned int *work_done,
        unsigned int work_to_do)
 {
        struct rx *rx;
+       int restart_required = 0;
+       struct rx *rx_to_start = NULL;
+
+       /* are we already rnr? then pay attention!!! this ensures that
+        * the state machine progression never allows a start with a 
+        * partially cleaned list, avoiding a race between hardware
+        * and rx_to_clean when in NAPI mode */
+       if(RU_SUSPENDED == nic->ru_running)
+               restart_required = 1;
 
        /* Indicate newly arrived packets */
        for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) {
-               if(e100_rx_indicate(nic, rx, work_done, work_to_do))
+               int err = e100_rx_indicate(nic, rx, work_done, work_to_do);
+               if(-EAGAIN == err) {
+                       /* hit quota so have more work to do, restart once
+                        * cleanup is complete */
+                       restart_required = 0;
+                       break;
+               } else if(-ENODATA == err)
                        break; /* No more to clean */
        }
 
+       /* save our starting point as the place we'll restart the receiver */
+       if(restart_required)
+               rx_to_start = nic->rx_to_clean;
+
        /* Alloc new skbs to refill list */
        for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) {
                if(unlikely(e100_rx_alloc_skb(nic, rx)))
                        break; /* Better luck next time (see watchdog) */
        }
 
-       e100_start_receiver(nic);
+       if(restart_required) {
+               // ack the rnr?
+               writeb(stat_ack_rnr, &nic->csr->scb.stat_ack);
+               e100_start_receiver(nic, rx_to_start);
+               if(work_done)
+                       (*work_done)++;
+       }
 }
 
 static void e100_rx_clean_list(struct nic *nic)
@@ -1535,6 +1602,8 @@ static void e100_rx_clean_list(struct nic *nic)
        struct rx *rx;
        unsigned int i, count = nic->params.rfds.count;
 
+       nic->ru_running = RU_UNINITIALIZED;
+
        if(nic->rxs) {
                for(rx = nic->rxs, i = 0; i < count; rx++, i++) {
                        if(rx->skb) {
@@ -1548,7 +1617,6 @@ static void e100_rx_clean_list(struct nic *nic)
        }
 
        nic->rx_to_use = nic->rx_to_clean = NULL;
-       nic->ru_running = 0;
 }
 
 static int e100_rx_alloc_list(struct nic *nic)
@@ -1557,6 +1625,7 @@ static int e100_rx_alloc_list(struct nic *nic)
        unsigned int i, count = nic->params.rfds.count;
 
        nic->rx_to_use = nic->rx_to_clean = NULL;
+       nic->ru_running = RU_UNINITIALIZED;
 
        if(!(nic->rxs = kmalloc(sizeof(struct rx) * count, GFP_ATOMIC)))
                return -ENOMEM;
@@ -1572,6 +1641,7 @@ static int e100_rx_alloc_list(struct nic *nic)
        }
 
        nic->rx_to_use = nic->rx_to_clean = nic->rxs;
+       nic->ru_running = RU_SUSPENDED;
 
        return 0;
 }
@@ -1593,7 +1663,7 @@ static irqreturn_t e100_intr(int irq, void *dev_id, struct pt_regs *regs)
 
        /* We hit Receive No Resource (RNR); restart RU after cleaning */
        if(stat_ack & stat_ack_rnr)
-               nic->ru_running = 0;
+               nic->ru_running = RU_SUSPENDED;
 
        e100_disable_irq(nic);
        netif_rx_schedule(netdev);
@@ -1663,6 +1733,7 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu)
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int e100_asf(struct nic *nic)
 {
        /* ASF can be enabled from eeprom */
@@ -1671,6 +1742,7 @@ static int e100_asf(struct nic *nic)
           !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) &&
           ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE));
 }
+#endif
 
 static int e100_up(struct nic *nic)
 {
@@ -1683,13 +1755,16 @@ static int e100_up(struct nic *nic)
        if((err = e100_hw_init(nic)))
                goto err_clean_cbs;
        e100_set_multicast_list(nic->netdev);
-       e100_start_receiver(nic);
+       e100_start_receiver(nic, 0);
        mod_timer(&nic->watchdog, jiffies);
        if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
                nic->netdev->name, nic->netdev)))
                goto err_no_irq;
-       e100_enable_irq(nic);
        netif_wake_queue(nic->netdev);
+       netif_poll_enable(nic->netdev);
+       /* enable ints _after_ enabling poll, preventing a race between
+        * disable ints+schedule */
+       e100_enable_irq(nic);
        return 0;
 
 err_no_irq:
@@ -1703,11 +1778,13 @@ err_rx_clean_list:
 
 static void e100_down(struct nic *nic)
 {
+       /* wait here for poll to complete */
+       netif_poll_disable(nic->netdev);
+       netif_stop_queue(nic->netdev);
        e100_hw_reset(nic);
        free_irq(nic->pdev->irq, nic->netdev);
        del_timer_sync(&nic->watchdog);
        netif_carrier_off(nic->netdev);
-       netif_stop_queue(nic->netdev);
        e100_clean_cbs(nic);
        e100_rx_clean_list(nic);
 }
@@ -1716,6 +1793,15 @@ static void e100_tx_timeout(struct net_device *netdev)
 {
        struct nic *nic = netdev_priv(netdev);
 
+       /* Reset outside of interrupt context, to avoid request_irq 
+        * in interrupt context */
+       schedule_work(&nic->tx_timeout_task);
+}
+
+static void e100_tx_timeout_task(struct net_device *netdev)
+{
+       struct nic *nic = netdev_priv(netdev);
+
        DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
                readb(&nic->csr->scb.status));
        e100_down(netdev_priv(netdev));
@@ -1749,7 +1835,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
                mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
                        BMCR_LOOPBACK);
 
-       e100_start_receiver(nic);
+       e100_start_receiver(nic, 0);
 
        if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
                err = -ENOMEM;
@@ -1869,7 +1955,6 @@ static int e100_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
        else
                nic->flags &= ~wol_magic;
 
-       pci_enable_wake(nic->pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
        e100_exec_cb(nic, NULL, e100_configure);
 
        return 0;
@@ -2223,6 +2308,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
 
        e100_get_defaults(nic);
 
+       /* locks must be initialized before calling hw_reset */
        spin_lock_init(&nic->cb_lock);
        spin_lock_init(&nic->cmd_lock);
 
@@ -2240,6 +2326,9 @@ static int __devinit e100_probe(struct pci_dev *pdev,
        nic->blink_timer.function = e100_blink_led;
        nic->blink_timer.data = (unsigned long)nic;
 
+       INIT_WORK(&nic->tx_timeout_task,
+               (void (*)(void *))e100_tx_timeout_task, netdev);
+
        if((err = e100_alloc(nic))) {
                DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n");
                goto err_out_iounmap;
@@ -2263,7 +2352,8 @@ static int __devinit e100_probe(struct pci_dev *pdev,
           (nic->eeprom[eeprom_id] & eeprom_id_wol))
                nic->flags |= wol_magic;
 
-       pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
+       /* ack any pending wake events, disable PME */
+       pci_enable_wake(pdev, 0, 0);
 
        strcpy(netdev->name, "eth%d");
        if((err = register_netdev(netdev))) {
@@ -2335,7 +2425,10 @@ static int e100_resume(struct pci_dev *pdev)
 
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
-       e100_hw_init(nic);
+       /* ack any pending wake events, disable PME */
+       pci_enable_wake(pdev, 0, 0);
+       if(e100_hw_init(nic))
+               DPRINTK(HW, ERR, "e100_hw_init failed\n");
 
        netif_device_attach(netdev);
        if(netif_running(netdev))
@@ -2345,6 +2438,21 @@ static int e100_resume(struct pci_dev *pdev)
 }
 #endif
 
+
+static void e100_shutdown(struct device *dev)
+{
+       struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct nic *nic = netdev_priv(netdev);
+
+#ifdef CONFIG_PM
+       pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
+#else
+       pci_enable_wake(pdev, 0, nic->flags & (wol_magic));
+#endif
+}
+
+
 static struct pci_driver e100_driver = {
        .name =         DRV_NAME,
        .id_table =     e100_id_table,
@@ -2354,6 +2462,11 @@ static struct pci_driver e100_driver = {
        .suspend =      e100_suspend,
        .resume =       e100_resume,
 #endif
+
+       .driver = {
+               .shutdown = e100_shutdown,
+       }
+
 };
 
 static int __init e100_init_module(void)
index 148930d4e9bdaef73f2e7357b15c86d36286666f..af1e82c5b808d89371b7ad99ff100bb3b5ea666b 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   This program is free software; you can redistribute it and/or modify it 
   under the terms of the GNU General Public License as published by the Free 
@@ -112,6 +112,8 @@ struct e1000_adapter;
 #define E1000_MAX_82544_RXD               4096
 
 /* Supported Rx Buffer Sizes */
+#define E1000_RXBUFFER_128   128    /* Used for packet split */
+#define E1000_RXBUFFER_256   256    /* Used for packet split */
 #define E1000_RXBUFFER_2048  2048
 #define E1000_RXBUFFER_4096  4096
 #define E1000_RXBUFFER_8192  8192
@@ -137,15 +139,19 @@ struct e1000_adapter;
 /* How many Rx Buffers do we bundle into one write to the hardware ? */
 #define E1000_RX_BUFFER_WRITE  16      /* Must be power of 2 */
 
-#define AUTO_ALL_MODES       0
-#define E1000_EEPROM_82544_APM 0x0004
-#define E1000_EEPROM_APME    0x0400
+#define AUTO_ALL_MODES            0
+#define E1000_EEPROM_82544_APM    0x0400
+#define E1000_EEPROM_APME         0x0400
 
 #ifndef E1000_MASTER_SLAVE
 /* Switch to override PHY master/slave setting */
 #define E1000_MASTER_SLAVE     e1000_ms_hw_default
 #endif
 
+#define E1000_MNG_VLAN_NONE -1
+/* Number of packet split data buffers (not including the header buffer) */
+#define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1
+
 /* only works for sizes that are powers of 2 */
 #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
 
@@ -159,6 +165,9 @@ struct e1000_buffer {
        uint16_t next_to_watch;
 };
 
+struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; };
+struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; };
+
 struct e1000_desc_ring {
        /* pointer to the descriptor ring memory */
        void *desc;
@@ -174,12 +183,19 @@ struct e1000_desc_ring {
        unsigned int next_to_clean;
        /* array of buffer information structs */
        struct e1000_buffer *buffer_info;
+       /* arrays of page information for packet split */
+       struct e1000_ps_page *ps_page;
+       struct e1000_ps_page_dma *ps_page_dma;
 };
 
 #define E1000_DESC_UNUSED(R) \
        ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
        (R)->next_to_clean - (R)->next_to_use - 1)
 
+#define E1000_RX_DESC_PS(R, i)     \
+       (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
+#define E1000_RX_DESC_EXT(R, i)            \
+       (&(((union e1000_rx_desc_extended *)((R).desc))[i]))
 #define E1000_GET_DESC(R, i, type)     (&(((struct type *)((R).desc))[i]))
 #define E1000_RX_DESC(R, i)            E1000_GET_DESC(R, i, e1000_rx_desc)
 #define E1000_TX_DESC(R, i)            E1000_GET_DESC(R, i, e1000_tx_desc)
@@ -192,6 +208,7 @@ struct e1000_adapter {
        struct timer_list watchdog_timer;
        struct timer_list phy_info_timer;
        struct vlan_group *vlgrp;
+       uint16_t mng_vlan_id;
        uint32_t bd_number;
        uint32_t rx_buffer_len;
        uint32_t part_num;
@@ -228,14 +245,23 @@ struct e1000_adapter {
        boolean_t detect_tx_hung;
 
        /* RX */
+#ifdef CONFIG_E1000_NAPI
+       boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done,
+                         int work_to_do);
+#else
+       boolean_t (*clean_rx) (struct e1000_adapter *adapter);
+#endif
+       void (*alloc_rx_buf) (struct e1000_adapter *adapter);
        struct e1000_desc_ring rx_ring;
        uint64_t hw_csum_err;
        uint64_t hw_csum_good;
        uint32_t rx_int_delay;
        uint32_t rx_abs_int_delay;
        boolean_t rx_csum;
+       boolean_t rx_ps;
        uint32_t gorcl;
        uint64_t gorcl_old;
+       uint16_t rx_ps_bsize0;
 
        /* Interrupt Throttle Rate */
        uint32_t itr;
@@ -257,5 +283,8 @@ struct e1000_adapter {
 
 
        int msg_enable;
+#ifdef CONFIG_PCI_MSI
+       boolean_t have_msi;
+#endif
 };
 #endif /* _E1000_H_ */
index 0a2ca7c73a4120f751918524a24682601ed51b3f..237247f74df48f0ae0c8e4c9998e7b8f6be9223d 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   This program is free software; you can redistribute it and/or modify it 
   under the terms of the GNU General Public License as published by the Free 
@@ -69,6 +69,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
        { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) },
        { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
        { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) },
+       { "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
        { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) },
        { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) },
        { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) },
@@ -593,7 +594,7 @@ e1000_set_ringparam(struct net_device *netdev,
        tx_old = adapter->tx_ring;
        rx_old = adapter->rx_ring;
 
-       if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+       if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
                return -EINVAL;
 
        if(netif_running(adapter->netdev))
@@ -784,8 +785,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
        /* Hook up test interrupt handler just for this test */
        if(!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) {
                shared_int = FALSE;
-       } else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, 
-                       netdev->name, netdev)){
+       } else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ,
+                             netdev->name, netdev)){
                *data = 1;
                return -1;
        }
@@ -842,10 +843,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
                         * test failed.
                         */
                        adapter->test_icr = 0;
-                       E1000_WRITE_REG(&adapter->hw, IMC, 
-                                       (~mask & 0x00007FFF));
-                       E1000_WRITE_REG(&adapter->hw, ICS, 
-                                       (~mask & 0x00007FFF));
+                       E1000_WRITE_REG(&adapter->hw, IMC, ~mask & 0x00007FFF);
+                       E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF);
                        msec_delay(10);
 
                        if(adapter->test_icr) {
@@ -919,7 +918,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter)
 
        /* Setup Tx descriptor ring and Tx buffers */
 
-       txdr->count = 80;
+       if(!txdr->count)
+               txdr->count = E1000_DEFAULT_TXD;   
 
        size = txdr->count * sizeof(struct e1000_buffer);
        if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
@@ -974,7 +974,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter)
 
        /* Setup Rx descriptor ring and Rx buffers */
 
-       rxdr->count = 80;
+       if(!rxdr->count)
+               rxdr->count = E1000_DEFAULT_RXD;   
 
        size = rxdr->count * sizeof(struct e1000_buffer);
        if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
@@ -1008,7 +1009,7 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter)
                struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
                struct sk_buff *skb;
 
-               if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, 
+               if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
                                GFP_KERNEL))) {
                        ret_val = 6;
                        goto err_nomem;
@@ -1310,31 +1311,62 @@ e1000_run_loopback_test(struct e1000_adapter *adapter)
        struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
        struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
        struct pci_dev *pdev = adapter->pdev;
-       int i, ret_val;
+       int i, j, k, l, lc, good_cnt, ret_val=0;
+       unsigned long time;
 
        E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1);
 
-       for(i = 0; i < 64; i++) {
-               e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024);
-               pci_dma_sync_single_for_device(pdev, txdr->buffer_info[i].dma,
-                                           txdr->buffer_info[i].length,
-                                           PCI_DMA_TODEVICE);
-       }
-       E1000_WRITE_REG(&adapter->hw, TDT, i);
-
-       msec_delay(200);
-
-       i = 0;
-       do {
-               pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[i].dma,
-                                           rxdr->buffer_info[i].length,
-                                           PCI_DMA_FROMDEVICE);
-
-               ret_val = e1000_check_lbtest_frame(rxdr->buffer_info[i].skb,
-                                                  1024);
-               i++;
-       } while (ret_val != 0 && i < 64);
+       /* Calculate the loop count based on the largest descriptor ring 
+        * The idea is to wrap the largest ring a number of times using 64
+        * send/receive pairs during each loop
+        */
 
+       if(rxdr->count <= txdr->count)
+               lc = ((txdr->count / 64) * 2) + 1;
+       else
+               lc = ((rxdr->count / 64) * 2) + 1;
+
+       k = l = 0;
+       for(j = 0; j <= lc; j++) { /* loop count loop */
+               for(i = 0; i < 64; i++) { /* send the packets */
+                       e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 
+                                       1024);
+                       pci_dma_sync_single_for_device(pdev, 
+                                       txdr->buffer_info[k].dma,
+                                       txdr->buffer_info[k].length,
+                                       PCI_DMA_TODEVICE);
+                       if(unlikely(++k == txdr->count)) k = 0;
+               }
+               E1000_WRITE_REG(&adapter->hw, TDT, k);
+               msec_delay(200);
+               time = jiffies; /* set the start time for the receive */
+               good_cnt = 0;
+               do { /* receive the sent packets */
+                       pci_dma_sync_single_for_cpu(pdev, 
+                                       rxdr->buffer_info[l].dma,
+                                       rxdr->buffer_info[l].length,
+                                       PCI_DMA_FROMDEVICE);
+       
+                       ret_val = e1000_check_lbtest_frame(
+                                       rxdr->buffer_info[l].skb,
+                                       1024);
+                       if(!ret_val)
+                               good_cnt++;
+                       if(unlikely(++l == rxdr->count)) l = 0;
+                       /* time + 20 msecs (200 msecs on 2.4) is more than 
+                        * enough time to complete the receives, if it's 
+                        * exceeded, break and error off
+                        */
+               } while (good_cnt < 64 && jiffies < (time + 20));
+               if(good_cnt != 64) {
+                       ret_val = 13; /* ret_val is the same as mis-compare */
+                       break; 
+               }
+               if(jiffies >= (time + 2)) {
+                       ret_val = 14; /* error code for time out error */
+                       break;
+               }
+       } /* end loop count loop */
        return ret_val;
 }
 
@@ -1354,13 +1386,12 @@ static int
 e1000_link_test(struct e1000_adapter *adapter, uint64_t *data)
 {
        *data = 0;
-
        if (adapter->hw.media_type == e1000_media_type_internal_serdes) {
                int i = 0;
                adapter->hw.serdes_link_down = TRUE;
 
-               /* on some blade server designs link establishment */
-               /* could take as long as 2-3 minutes.              */
+               /* On some blade server designs, link establishment
+                * could take as long as 2-3 minutes */
                do {
                        e1000_check_for_link(&adapter->hw);
                        if (adapter->hw.serdes_link_down == FALSE)
@@ -1368,9 +1399,11 @@ e1000_link_test(struct e1000_adapter *adapter, uint64_t *data)
                        msec_delay(20);
                } while (i++ < 3750);
 
-               *data = 1; 
+               *data = 1;
        } else {
                e1000_check_for_link(&adapter->hw);
+               if(adapter->hw.autoneg)  /* if auto_neg is set wait for it */
+                       msec_delay(4000);
 
                if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
                        *data = 1;
index 786a9b935659fbeec6d162df0c6f17d5696ea15b..723589b28be5d7a1716e89858ae1fe6303d9dd63 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   This program is free software; you can redistribute it and/or modify it 
   under the terms of the GNU General Public License as published by the Free 
@@ -63,10 +63,11 @@ static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count);
 static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
 static void e1000_release_eeprom(struct e1000_hw *hw);
 static void e1000_standby_eeprom(struct e1000_hw *hw);
-static int32_t e1000_id_led_init(struct e1000_hw * hw);
 static int32_t e1000_set_vco_speed(struct e1000_hw *hw);
 static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);
 static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
+static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
+static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
 
 /* IGP cable length table */
 static const
@@ -80,6 +81,17 @@ uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
       100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
       110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
 
+static const
+uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
+    { 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43,
+      22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58,
+      32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74,
+      43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90,
+      57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108,
+      73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124,
+      91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128,
+      108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
+
 
 /******************************************************************************
  * Set the phy type member in the hw struct.
@@ -91,10 +103,14 @@ e1000_set_phy_type(struct e1000_hw *hw)
 {
     DEBUGFUNC("e1000_set_phy_type");
 
+    if(hw->mac_type == e1000_undefined)
+        return -E1000_ERR_PHY_TYPE;
+
     switch(hw->phy_id) {
     case M88E1000_E_PHY_ID:
     case M88E1000_I_PHY_ID:
     case M88E1011_I_PHY_ID:
+    case M88E1111_I_PHY_ID:
         hw->phy_type = e1000_phy_m88;
         break;
     case IGP01E1000_I_PHY_ID:
@@ -128,7 +144,6 @@ e1000_phy_init_script(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_phy_init_script");
 
-
     if(hw->phy_init_script) {
         msec_delay(20);
 
@@ -271,6 +286,7 @@ e1000_set_mac_type(struct e1000_hw *hw)
     case E1000_DEV_ID_82546GB_FIBER:
     case E1000_DEV_ID_82546GB_SERDES:
     case E1000_DEV_ID_82546GB_PCIE:
+    case E1000_DEV_ID_82546GB_QUAD_COPPER:
         hw->mac_type = e1000_82546_rev_3;
         break;
     case E1000_DEV_ID_82541EI:
@@ -289,12 +305,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
     case E1000_DEV_ID_82547GI:
         hw->mac_type = e1000_82547_rev_2;
         break;
+    case E1000_DEV_ID_82573E:
+    case E1000_DEV_ID_82573E_IAMT:
+        hw->mac_type = e1000_82573;
+        break;
     default:
         /* Should never have loaded on this device */
         return -E1000_ERR_MAC_TYPE;
     }
 
     switch(hw->mac_type) {
+    case e1000_82573:
+        hw->eeprom_semaphore_present = TRUE;
+        /* fall through */
     case e1000_82541:
     case e1000_82547:
     case e1000_82541_rev_2:
@@ -360,6 +383,9 @@ e1000_reset_hw(struct e1000_hw *hw)
     uint32_t icr;
     uint32_t manc;
     uint32_t led_ctrl;
+    uint32_t timeout;
+    uint32_t extcnf_ctrl;
+    int32_t ret_val;
 
     DEBUGFUNC("e1000_reset_hw");
 
@@ -369,6 +395,15 @@ e1000_reset_hw(struct e1000_hw *hw)
         e1000_pci_clear_mwi(hw);
     }
 
+    if(hw->bus_type == e1000_bus_type_pci_express) {
+        /* Prevent the PCI-E bus from sticking if there is no TLP connection
+         * on the last TLP read/write transaction when MAC is reset.
+         */
+        if(e1000_disable_pciex_master(hw) != E1000_SUCCESS) {
+            DEBUGOUT("PCI-E Master disable polling has failed.\n");
+        }
+    }
+
     /* Clear interrupt mask to stop board from generating interrupts */
     DEBUGOUT("Masking off all interrupts\n");
     E1000_WRITE_REG(hw, IMC, 0xffffffff);
@@ -393,10 +428,32 @@ e1000_reset_hw(struct e1000_hw *hw)
 
     /* Must reset the PHY before resetting the MAC */
     if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-        E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
+        E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
         msec_delay(5);
     }
 
+    /* Must acquire the MDIO ownership before MAC reset.
+     * Ownership defaults to firmware after a reset. */
+    if(hw->mac_type == e1000_82573) {
+        timeout = 10;
+
+        extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
+        extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
+
+        do {
+            E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
+            extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
+
+            if(extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
+                break;
+            else
+                extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
+
+            msec_delay(2);
+            timeout--;
+        } while(timeout);
+    }
+
     /* Issue a global reset to the MAC.  This will reset the chip's
      * transmit, receive, DMA, and link units.  It will not effect
      * the current PCI configuration.  The global reset bit is self-
@@ -450,6 +507,18 @@ e1000_reset_hw(struct e1000_hw *hw)
             /* Wait for EEPROM reload */
             msec_delay(20);
             break;
+        case e1000_82573:
+            udelay(10);
+            ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+            ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+            E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+            E1000_WRITE_FLUSH(hw);
+            /* fall through */
+            ret_val = e1000_get_auto_rd_done(hw);
+            if(ret_val)
+                /* We don't want to continue accessing MAC registers. */
+                return ret_val;
+            break;
         default:
             /* Wait for EEPROM reload (it happens automatically) */
             msec_delay(5);
@@ -457,7 +526,7 @@ e1000_reset_hw(struct e1000_hw *hw)
     }
 
     /* Disable HW ARPs on ASF enabled adapters */
-    if(hw->mac_type >= e1000_82540) {
+    if(hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) {
         manc = E1000_READ_REG(hw, MANC);
         manc &= ~(E1000_MANC_ARP_EN);
         E1000_WRITE_REG(hw, MANC, manc);
@@ -510,6 +579,8 @@ e1000_init_hw(struct e1000_hw *hw)
     uint16_t pcix_stat_hi_word;
     uint16_t cmd_mmrbc;
     uint16_t stat_mmrbc;
+    uint32_t mta_size;
+
     DEBUGFUNC("e1000_init_hw");
 
     /* Initialize Identification LED */
@@ -524,8 +595,8 @@ e1000_init_hw(struct e1000_hw *hw)
 
     /* Disabling VLAN filtering. */
     DEBUGOUT("Initializing the IEEE VLAN\n");
-    E1000_WRITE_REG(hw, VET, 0);
-
+    if (hw->mac_type < e1000_82545_rev_3)
+        E1000_WRITE_REG(hw, VET, 0);
     e1000_clear_vfta(hw);
 
     /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
@@ -553,14 +624,16 @@ e1000_init_hw(struct e1000_hw *hw)
 
     /* Zero out the Multicast HASH table */
     DEBUGOUT("Zeroing the MTA\n");
-    for(i = 0; i < E1000_MC_TBL_SIZE; i++)
+    mta_size = E1000_MC_TBL_SIZE;
+    for(i = 0; i < mta_size; i++)
         E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
 
     /* Set the PCI priority bit correctly in the CTRL register.  This
      * determines if the adapter gives priority to receives, or if it
-     * gives equal priority to transmits and receives.
+     * gives equal priority to transmits and receives.  Valid only on
+     * 82542 and 82543 silicon.
      */
-    if(hw->dma_fairness) {
+    if(hw->dma_fairness && hw->mac_type <= e1000_82543) {
         ctrl = E1000_READ_REG(hw, CTRL);
         E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
     }
@@ -598,9 +671,21 @@ e1000_init_hw(struct e1000_hw *hw)
     if(hw->mac_type > e1000_82544) {
         ctrl = E1000_READ_REG(hw, TXDCTL);
         ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
+        switch (hw->mac_type) {
+        default:
+            break;
+        case e1000_82573:
+            ctrl |= E1000_TXDCTL_COUNT_DESC;
+            break;
+        }
         E1000_WRITE_REG(hw, TXDCTL, ctrl);
     }
 
+    if (hw->mac_type == e1000_82573) {
+        e1000_enable_tx_pkt_filtering(hw); 
+    }
+
+
     /* Clear all of the statistics registers (clear on read).  It is
      * important that we do this after we have tried to establish link
      * because the symbol error count will increment wildly if there
@@ -679,7 +764,7 @@ e1000_setup_link(struct e1000_hw *hw)
      * control setting, then the variable hw->fc will
      * be initialized based on a value in the EEPROM.
      */
-    if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 0) {
+    if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) {
         DEBUGOUT("EEPROM Read Error\n");
         return -E1000_ERR_EEPROM;
     }
@@ -736,6 +821,7 @@ e1000_setup_link(struct e1000_hw *hw)
     E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
     E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
     E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
+
     E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
 
     /* Set the flow control receive threshold registers.  Normally,
@@ -906,20 +992,18 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
 }
 
 /******************************************************************************
-* Detects which PHY is present and the speed and duplex
+* Make sure we have a valid PHY and change PHY mode before link setup.
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
 static int32_t
-e1000_setup_copper_link(struct e1000_hw *hw)
+e1000_copper_link_preconfig(struct e1000_hw *hw)
 {
     uint32_t ctrl;
-    uint32_t led_ctrl;
     int32_t ret_val;
-    uint16_t i;
     uint16_t phy_data;
 
-    DEBUGFUNC("e1000_setup_copper_link");
+    DEBUGFUNC("e1000_copper_link_preconfig");
 
     ctrl = E1000_READ_REG(hw, CTRL);
     /* With 82543, we need to force speed and duplex on the MAC equal to what
@@ -933,7 +1017,9 @@ e1000_setup_copper_link(struct e1000_hw *hw)
     } else {
         ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
         E1000_WRITE_REG(hw, CTRL, ctrl);
-        e1000_phy_hw_reset(hw);
+        ret_val = e1000_phy_hw_reset(hw);
+        if(ret_val)
+            return ret_val;
     }
 
     /* Make sure we have a valid PHY */
@@ -961,353 +1047,451 @@ e1000_setup_copper_link(struct e1000_hw *hw)
        hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
         hw->phy_reset_disable = FALSE;
 
-    if(!hw->phy_reset_disable) {
-        if (hw->phy_type == e1000_phy_igp) {
-
-            ret_val = e1000_phy_reset(hw);
-            if(ret_val) {
-                DEBUGOUT("Error Resetting the PHY\n");
-                return ret_val;
-            }
-
-            /* Wait 10ms for MAC to configure PHY from eeprom settings */
-            msec_delay(15);
+   return E1000_SUCCESS;
+}
 
-            /* Configure activity LED after PHY reset */
-            led_ctrl = E1000_READ_REG(hw, LEDCTL);
-            led_ctrl &= IGP_ACTIVITY_LED_MASK;
-            led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-            E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
 
-            /* disable lplu d3 during driver init */
-            ret_val = e1000_set_d3_lplu_state(hw, FALSE);
-            if(ret_val) {
-                DEBUGOUT("Error Disabling LPLU D3\n");
-                return ret_val;
-            }
+/********************************************************************
+* Copper link setup for e1000_phy_igp series.
+*
+* hw - Struct containing variables accessed by shared code
+*********************************************************************/
+static int32_t
+e1000_copper_link_igp_setup(struct e1000_hw *hw)
+{
+    uint32_t led_ctrl;
+    int32_t ret_val;
+    uint16_t phy_data;
 
-            /* Configure mdi-mdix settings */
-            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
-                                         &phy_data);
-            if(ret_val)
-                return ret_val;
+    DEBUGFUNC("e1000_copper_link_igp_setup");
 
-            if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-                hw->dsp_config_state = e1000_dsp_config_disabled;
-                /* Force MDI for earlier revs of the IGP PHY */
-                phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
-                              IGP01E1000_PSCR_FORCE_MDI_MDIX);
-                hw->mdix = 1;
+    if (hw->phy_reset_disable)
+        return E1000_SUCCESS;
+    
+    ret_val = e1000_phy_reset(hw);
+    if (ret_val) {
+        DEBUGOUT("Error Resetting the PHY\n");
+        return ret_val;
+    }
 
-            } else {
-                hw->dsp_config_state = e1000_dsp_config_enabled;
-                phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
-
-                switch (hw->mdix) {
-                case 1:
-                    phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
-                    break;
-                case 2:
-                    phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
-                    break;
-                case 0:
-                default:
-                    phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
-                    break;
-                }
-            }
-            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
-                                          phy_data);
-            if(ret_val)
-                return ret_val;
+    /* Wait 10ms for MAC to configure PHY from eeprom settings */
+    msec_delay(15);
 
-            /* set auto-master slave resolution settings */
-            if(hw->autoneg) {
-                e1000_ms_type phy_ms_setting = hw->master_slave;
+    /* Configure activity LED after PHY reset */
+    led_ctrl = E1000_READ_REG(hw, LEDCTL);
+    led_ctrl &= IGP_ACTIVITY_LED_MASK;
+    led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
+    E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
 
-                if(hw->ffe_config_state == e1000_ffe_config_active)
-                    hw->ffe_config_state = e1000_ffe_config_enabled;
+    /* disable lplu d3 during driver init */
+    ret_val = e1000_set_d3_lplu_state(hw, FALSE);
+    if (ret_val) {
+        DEBUGOUT("Error Disabling LPLU D3\n");
+        return ret_val;
+    }
 
-                if(hw->dsp_config_state == e1000_dsp_config_activated)
-                    hw->dsp_config_state = e1000_dsp_config_enabled;
+    /* disable lplu d0 during driver init */
+    ret_val = e1000_set_d0_lplu_state(hw, FALSE);
+    if (ret_val) {
+        DEBUGOUT("Error Disabling LPLU D0\n");
+        return ret_val;
+    }
+    /* Configure mdi-mdix settings */
+    ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
+    if (ret_val)
+        return ret_val;
 
-                /* when autonegotiation advertisment is only 1000Mbps then we
-                 * should disable SmartSpeed and enable Auto MasterSlave
-                 * resolution as hardware default. */
-                if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
-                    /* Disable SmartSpeed */
-                    ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-                                                 &phy_data);
-                    if(ret_val)
-                        return ret_val;
-                    phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-                    ret_val = e1000_write_phy_reg(hw,
-                                                  IGP01E1000_PHY_PORT_CONFIG,
-                                                  phy_data);
-                    if(ret_val)
-                        return ret_val;
-                    /* Set auto Master/Slave resolution process */
-                    ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
-                    if(ret_val)
-                        return ret_val;
-                    phy_data &= ~CR_1000T_MS_ENABLE;
-                    ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
-                    if(ret_val)
-                        return ret_val;
-                }
+    if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+        hw->dsp_config_state = e1000_dsp_config_disabled;
+        /* Force MDI for earlier revs of the IGP PHY */
+        phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | IGP01E1000_PSCR_FORCE_MDI_MDIX);
+        hw->mdix = 1;
 
-                ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
-                if(ret_val)
-                    return ret_val;
+    } else {
+        hw->dsp_config_state = e1000_dsp_config_enabled;
+        phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
 
-                /* load defaults for future use */
-                hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
-                                            ((phy_data & CR_1000T_MS_VALUE) ?
-                                             e1000_ms_force_master :
-                                             e1000_ms_force_slave) :
-                                             e1000_ms_auto;
-
-                switch (phy_ms_setting) {
-                case e1000_ms_force_master:
-                    phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
-                    break;
-                case e1000_ms_force_slave:
-                    phy_data |= CR_1000T_MS_ENABLE;
-                    phy_data &= ~(CR_1000T_MS_VALUE);
-                    break;
-                case e1000_ms_auto:
-                    phy_data &= ~CR_1000T_MS_ENABLE;
-                default:
-                    break;
-                }
-                ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
-                if(ret_val)
-                    return ret_val;
-            }
-        } else {
-            /* Enable CRS on TX. This must be set for half-duplex operation. */
-            ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-                                         &phy_data);
-            if(ret_val)
-                return ret_val;
+        switch (hw->mdix) {
+        case 1:
+            phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
+            break;
+        case 2:
+            phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
+            break;
+        case 0:
+        default:
+            phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
+            break;
+        }
+    }
+    ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
+    if(ret_val)
+        return ret_val;
 
-            phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+    /* set auto-master slave resolution settings */
+    if(hw->autoneg) {
+        e1000_ms_type phy_ms_setting = hw->master_slave;
 
-            /* Options:
-             *   MDI/MDI-X = 0 (default)
-             *   0 - Auto for all speeds
-             *   1 - MDI mode
-             *   2 - MDI-X mode
-             *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
-             */
-            phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+        if(hw->ffe_config_state == e1000_ffe_config_active)
+            hw->ffe_config_state = e1000_ffe_config_enabled;
 
-            switch (hw->mdix) {
-            case 1:
-                phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
-                break;
-            case 2:
-                phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
-                break;
-            case 3:
-                phy_data |= M88E1000_PSCR_AUTO_X_1000T;
-                break;
-            case 0:
-            default:
-                phy_data |= M88E1000_PSCR_AUTO_X_MODE;
-                break;
-            }
+        if(hw->dsp_config_state == e1000_dsp_config_activated)
+            hw->dsp_config_state = e1000_dsp_config_enabled;
 
-            /* Options:
-             *   disable_polarity_correction = 0 (default)
-             *       Automatic Correction for Reversed Cable Polarity
-             *   0 - Disabled
-             *   1 - Enabled
-             */
-            phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
-            if(hw->disable_polarity_correction == 1)
-                phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-            ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-                                          phy_data);
+        /* when autonegotiation advertisment is only 1000Mbps then we
+          * should disable SmartSpeed and enable Auto MasterSlave
+          * resolution as hardware default. */
+        if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
+            /* Disable SmartSpeed */
+            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
             if(ret_val)
                 return ret_val;
-
-            /* Force TX_CLK in the Extended PHY Specific Control Register
-             * to 25MHz clock.
-             */
-            ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-                                         &phy_data);
+            phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+            ret_val = e1000_write_phy_reg(hw,
+                                                  IGP01E1000_PHY_PORT_CONFIG,
+                                                  phy_data);
+            if(ret_val)
+                return ret_val;
+            /* Set auto Master/Slave resolution process */
+            ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
+            if(ret_val)
+                return ret_val;
+            phy_data &= ~CR_1000T_MS_ENABLE;
+            ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
             if(ret_val)
                 return ret_val;
+        }
 
-            phy_data |= M88E1000_EPSCR_TX_CLK_25;
+        ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
+        if(ret_val)
+            return ret_val;
 
-            if (hw->phy_revision < M88E1011_I_REV_4) {
-                /* Configure Master and Slave downshift values */
-                phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
-                              M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
-                phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
-                             M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
-                ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-                                              phy_data);
-                if(ret_val)
-                    return ret_val;
-            }
+        /* load defaults for future use */
+        hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
+                                        ((phy_data & CR_1000T_MS_VALUE) ?
+                                         e1000_ms_force_master :
+                                         e1000_ms_force_slave) :
+                                         e1000_ms_auto;
 
-            /* SW Reset the PHY so all changes take effect */
-            ret_val = e1000_phy_reset(hw);
-            if(ret_val) {
-                DEBUGOUT("Error Resetting the PHY\n");
-                return ret_val;
-            }
+        switch (phy_ms_setting) {
+        case e1000_ms_force_master:
+            phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
+            break;
+        case e1000_ms_force_slave:
+            phy_data |= CR_1000T_MS_ENABLE;
+            phy_data &= ~(CR_1000T_MS_VALUE);
+            break;
+        case e1000_ms_auto:
+            phy_data &= ~CR_1000T_MS_ENABLE;
+            default:
+            break;
+        }
+        ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
+        if(ret_val)
+            return ret_val;
         }
 
-        /* Options:
-         *   autoneg = 1 (default)
-         *      PHY will advertise value(s) parsed from
-         *      autoneg_advertised and fc
-         *   autoneg = 0
-         *      PHY will be set to 10H, 10F, 100H, or 100F
-         *      depending on value parsed from forced_speed_duplex.
-         */
+   return E1000_SUCCESS;
+}
 
-        /* Is autoneg enabled?  This is enabled by default or by software
-         * override.  If so, call e1000_phy_setup_autoneg routine to parse the
-         * autoneg_advertised and fc options. If autoneg is NOT enabled, then
-         * the user should have provided a speed/duplex override.  If so, then
-         * call e1000_phy_force_speed_duplex to parse and set this up.
-         */
-        if(hw->autoneg) {
-            /* Perform some bounds checking on the hw->autoneg_advertised
-             * parameter.  If this variable is zero, then set it to the default.
-             */
-            hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
 
-            /* If autoneg_advertised is zero, we assume it was not defaulted
-             * by the calling code so we set to advertise full capability.
-             */
-            if(hw->autoneg_advertised == 0)
-                hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+/********************************************************************
+* Copper link setup for e1000_phy_m88 series.
+*
+* hw - Struct containing variables accessed by shared code
+*********************************************************************/
+static int32_t
+e1000_copper_link_mgp_setup(struct e1000_hw *hw)
+{
+    int32_t ret_val;
+    uint16_t phy_data;
 
-            DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
-            ret_val = e1000_phy_setup_autoneg(hw);
-            if(ret_val) {
-                DEBUGOUT("Error Setting up Auto-Negotiation\n");
-                return ret_val;
-            }
-            DEBUGOUT("Restarting Auto-Neg\n");
+    DEBUGFUNC("e1000_copper_link_mgp_setup");
 
-            /* Restart auto-negotiation by setting the Auto Neg Enable bit and
-             * the Auto Neg Restart bit in the PHY control register.
-             */
-            ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
-            if(ret_val)
-                return ret_val;
+    if(hw->phy_reset_disable)
+        return E1000_SUCCESS;
+    
+    /* Enable CRS on TX. This must be set for half-duplex operation. */
+    ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+    if(ret_val)
+        return ret_val;
 
-            phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
-            ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
-            if(ret_val)
-                return ret_val;
+    phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
 
-            /* Does the user want to wait for Auto-Neg to complete here, or
-             * check at a later time (for example, callback routine).
-             */
-            if(hw->wait_autoneg_complete) {
-                ret_val = e1000_wait_autoneg(hw);
-                if(ret_val) {
-                    DEBUGOUT("Error while waiting for autoneg to complete\n");
-                    return ret_val;
-                }
-            }
-            hw->get_link_status = TRUE;
-        } else {
-            DEBUGOUT("Forcing speed and duplex\n");
-            ret_val = e1000_phy_force_speed_duplex(hw);
-            if(ret_val) {
-                DEBUGOUT("Error Forcing Speed and Duplex\n");
-                return ret_val;
-            }
-        }
-    } /* !hw->phy_reset_disable */
+    /* Options:
+     *   MDI/MDI-X = 0 (default)
+     *   0 - Auto for all speeds
+     *   1 - MDI mode
+     *   2 - MDI-X mode
+     *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+     */
+    phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
 
-    /* Check link status. Wait up to 100 microseconds for link to become
-     * valid.
+    switch (hw->mdix) {
+    case 1:
+        phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+        break;
+    case 2:
+        phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+        break;
+    case 3:
+        phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+        break;
+    case 0:
+    default:
+        phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+        break;
+    }
+
+    /* Options:
+     *   disable_polarity_correction = 0 (default)
+     *       Automatic Correction for Reversed Cable Polarity
+     *   0 - Disabled
+     *   1 - Enabled
      */
-    for(i = 0; i < 10; i++) {
-        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
+    phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+    if(hw->disable_polarity_correction == 1)
+        phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+        ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
         if(ret_val)
             return ret_val;
-        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
+
+    /* Force TX_CLK in the Extended PHY Specific Control Register
+     * to 25MHz clock.
+     */
+    ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
+    if(ret_val)
+        return ret_val;
+
+    phy_data |= M88E1000_EPSCR_TX_CLK_25;
+
+    if (hw->phy_revision < M88E1011_I_REV_4) {
+        /* Configure Master and Slave downshift values */
+        phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
+                              M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
+        phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
+                             M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+        ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
         if(ret_val)
             return ret_val;
+    }
 
-        if(phy_data & MII_SR_LINK_STATUS) {
-            /* We have link, so we need to finish the config process:
-             *   1) Set up the MAC to the current PHY speed/duplex
-             *      if we are on 82543.  If we
-             *      are on newer silicon, we only need to configure
-             *      collision distance in the Transmit Control Register.
-             *   2) Set up flow control on the MAC to that established with
-             *      the link partner.
-             */
-            if(hw->mac_type >= e1000_82544) {
-                e1000_config_collision_dist(hw);
-            } else {
-                ret_val = e1000_config_mac_to_phy(hw);
-                if(ret_val) {
-                    DEBUGOUT("Error configuring MAC to PHY settings\n");
-                    return ret_val;
-                }
-            }
-            ret_val = e1000_config_fc_after_link_up(hw);
-            if(ret_val) {
-                DEBUGOUT("Error Configuring Flow Control\n");
-                return ret_val;
-            }
-            DEBUGOUT("Valid link established!!!\n");
-
-            if(hw->phy_type == e1000_phy_igp) {
-                ret_val = e1000_config_dsp_after_link_change(hw, TRUE);
-                if(ret_val) {
-                    DEBUGOUT("Error Configuring DSP after link up\n");
-                    return ret_val;
-                }
-            }
-            DEBUGOUT("Valid link established!!!\n");
-            return E1000_SUCCESS;
-        }
-        udelay(10);
+    /* SW Reset the PHY so all changes take effect */
+    ret_val = e1000_phy_reset(hw);
+    if(ret_val) {
+        DEBUGOUT("Error Resetting the PHY\n");
+        return ret_val;
     }
 
-    DEBUGOUT("Unable to establish link!!!\n");
-    return E1000_SUCCESS;
+   return E1000_SUCCESS;
 }
 
-/******************************************************************************
-* Configures PHY autoneg and flow control advertisement settings
+/********************************************************************
+* Setup auto-negotiation and flow control advertisements,
+* and then perform auto-negotiation.
 *
 * hw - Struct containing variables accessed by shared code
-******************************************************************************/
-int32_t
-e1000_phy_setup_autoneg(struct e1000_hw *hw)
+*********************************************************************/
+static int32_t
+e1000_copper_link_autoneg(struct e1000_hw *hw)
 {
     int32_t ret_val;
-    uint16_t mii_autoneg_adv_reg;
-    uint16_t mii_1000t_ctrl_reg;
+    uint16_t phy_data;
 
-    DEBUGFUNC("e1000_phy_setup_autoneg");
+    DEBUGFUNC("e1000_copper_link_autoneg");
 
-    /* Read the MII Auto-Neg Advertisement Register (Address 4). */
-    ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
+    /* Perform some bounds checking on the hw->autoneg_advertised
+     * parameter.  If this variable is zero, then set it to the default.
+     */
+    hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+    /* If autoneg_advertised is zero, we assume it was not defaulted
+     * by the calling code so we set to advertise full capability.
+     */
+    if(hw->autoneg_advertised == 0)
+        hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+    DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
+    ret_val = e1000_phy_setup_autoneg(hw);
+    if(ret_val) {
+        DEBUGOUT("Error Setting up Auto-Negotiation\n");
+        return ret_val;
+    }
+    DEBUGOUT("Restarting Auto-Neg\n");
+
+    /* Restart auto-negotiation by setting the Auto Neg Enable bit and
+     * the Auto Neg Restart bit in the PHY control register.
+     */
+    ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
     if(ret_val)
         return ret_val;
 
-    /* Read the MII 1000Base-T Control Register (Address 9). */
-    ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
+    phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
+    ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
     if(ret_val)
         return ret_val;
 
-    /* Need to parse both autoneg_advertised and fc and set up
+    /* Does the user want to wait for Auto-Neg to complete here, or
+     * check at a later time (for example, callback routine).
+     */
+    if(hw->wait_autoneg_complete) {
+        ret_val = e1000_wait_autoneg(hw);
+        if(ret_val) {
+            DEBUGOUT("Error while waiting for autoneg to complete\n");
+            return ret_val;
+        }
+    }
+
+    hw->get_link_status = TRUE;
+
+    return E1000_SUCCESS;
+}
+
+
+/******************************************************************************
+* Config the MAC and the PHY after link is up.
+*   1) Set up the MAC to the current PHY speed/duplex
+*      if we are on 82543.  If we
+*      are on newer silicon, we only need to configure
+*      collision distance in the Transmit Control Register.
+*   2) Set up flow control on the MAC to that established with
+*      the link partner.
+*   3) Config DSP to improve Gigabit link quality for some PHY revisions.    
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int32_t
+e1000_copper_link_postconfig(struct e1000_hw *hw)
+{
+    int32_t ret_val;
+    DEBUGFUNC("e1000_copper_link_postconfig");
+    
+    if(hw->mac_type >= e1000_82544) {
+        e1000_config_collision_dist(hw);
+    } else {
+        ret_val = e1000_config_mac_to_phy(hw);
+        if(ret_val) {
+            DEBUGOUT("Error configuring MAC to PHY settings\n");
+            return ret_val;
+        }
+    }
+    ret_val = e1000_config_fc_after_link_up(hw);
+    if(ret_val) {
+        DEBUGOUT("Error Configuring Flow Control\n");
+        return ret_val;
+    }
+
+    /* Config DSP to improve Giga link quality */
+    if(hw->phy_type == e1000_phy_igp) {
+        ret_val = e1000_config_dsp_after_link_change(hw, TRUE);
+        if(ret_val) {
+            DEBUGOUT("Error Configuring DSP after link up\n");
+            return ret_val;
+        }
+    }
+                
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Detects which PHY is present and setup the speed and duplex
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int32_t
+e1000_setup_copper_link(struct e1000_hw *hw)
+{
+    int32_t ret_val;
+    uint16_t i;
+    uint16_t phy_data;
+
+    DEBUGFUNC("e1000_setup_copper_link");
+
+    /* Check if it is a valid PHY and set PHY mode if necessary. */
+    ret_val = e1000_copper_link_preconfig(hw);
+    if(ret_val)
+        return ret_val;
+
+    if (hw->phy_type == e1000_phy_igp ||
+        hw->phy_type == e1000_phy_igp_2) {
+        ret_val = e1000_copper_link_igp_setup(hw);
+        if(ret_val)
+            return ret_val;
+    } else if (hw->phy_type == e1000_phy_m88) {
+        ret_val = e1000_copper_link_mgp_setup(hw);
+        if(ret_val)
+            return ret_val;
+    }
+
+    if(hw->autoneg) {
+        /* Setup autoneg and flow control advertisement 
+          * and perform autonegotiation */   
+        ret_val = e1000_copper_link_autoneg(hw);
+        if(ret_val)
+            return ret_val;           
+    } else {
+        /* PHY will be set to 10H, 10F, 100H,or 100F
+          * depending on value from forced_speed_duplex. */
+        DEBUGOUT("Forcing speed and duplex\n");
+        ret_val = e1000_phy_force_speed_duplex(hw);
+        if(ret_val) {
+            DEBUGOUT("Error Forcing Speed and Duplex\n");
+            return ret_val;
+        }
+    }
+
+    /* Check link status. Wait up to 100 microseconds for link to become
+     * valid.
+     */
+    for(i = 0; i < 10; i++) {
+        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
+        if(ret_val)
+            return ret_val;
+        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
+        if(ret_val)
+            return ret_val;
+
+        if(phy_data & MII_SR_LINK_STATUS) {
+            /* Config the MAC and PHY after link is up */
+            ret_val = e1000_copper_link_postconfig(hw);
+            if(ret_val)
+                return ret_val;
+            
+            DEBUGOUT("Valid link established!!!\n");
+            return E1000_SUCCESS;
+        }
+        udelay(10);
+    }
+
+    DEBUGOUT("Unable to establish link!!!\n");
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Configures PHY autoneg and flow control advertisement settings
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+int32_t
+e1000_phy_setup_autoneg(struct e1000_hw *hw)
+{
+    int32_t ret_val;
+    uint16_t mii_autoneg_adv_reg;
+    uint16_t mii_1000t_ctrl_reg;
+
+    DEBUGFUNC("e1000_phy_setup_autoneg");
+
+    /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+    ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
+    if(ret_val)
+        return ret_val;
+
+        /* Read the MII 1000Base-T Control Register (Address 9). */
+        ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
+        if(ret_val)
+            return ret_val;
+
+    /* Need to parse both autoneg_advertised and fc and set up
      * the appropriate PHY registers.  First we will parse for
      * autoneg_advertised software override.  Since we can advertise
      * a plethora of combinations, we need to check each bit
@@ -1417,7 +1601,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
 
     DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
 
-    ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
+    ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);    
     if(ret_val)
         return ret_val;
 
@@ -1678,6 +1862,11 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_config_mac_to_phy");
 
+    /* 82544 or newer MAC, Auto Speed Detection takes care of 
+    * MAC speed/duplex configuration.*/
+    if (hw->mac_type >= e1000_82544)
+        return E1000_SUCCESS;
+
     /* Read the Device Control Register and set the bits to Force Speed
      * and Duplex.
      */
@@ -1688,45 +1877,25 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
     /* Set up duplex in the Device Control and Transmit Control
      * registers depending on negotiated values.
      */
-    if (hw->phy_type == e1000_phy_igp) {
-        ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
-                                     &phy_data);
-        if(ret_val)
-            return ret_val;
-
-        if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD;
-        else ctrl &= ~E1000_CTRL_FD;
-
-        e1000_config_collision_dist(hw);
+    ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
+    if(ret_val)
+        return ret_val;
 
-        /* Set up speed in the Device Control register depending on
-         * negotiated values.
-         */
-        if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
-           IGP01E1000_PSSR_SPEED_1000MBPS)
-            ctrl |= E1000_CTRL_SPD_1000;
-        else if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
-                IGP01E1000_PSSR_SPEED_100MBPS)
-            ctrl |= E1000_CTRL_SPD_100;
-    } else {
-        ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
-                                     &phy_data);
-        if(ret_val)
-            return ret_val;
+    if(phy_data & M88E1000_PSSR_DPLX) 
+        ctrl |= E1000_CTRL_FD;
+    else 
+        ctrl &= ~E1000_CTRL_FD;
 
-        if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
-        else ctrl &= ~E1000_CTRL_FD;
+    e1000_config_collision_dist(hw);
 
-        e1000_config_collision_dist(hw);
+    /* Set up speed in the Device Control register depending on
+     * negotiated values.
+     */
+    if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
+        ctrl |= E1000_CTRL_SPD_1000;
+    else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
+        ctrl |= E1000_CTRL_SPD_100;
 
-        /* Set up speed in the Device Control register depending on
-         * negotiated values.
-         */
-        if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
-            ctrl |= E1000_CTRL_SPD_1000;
-        else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
-            ctrl |= E1000_CTRL_SPD_100;
-    }
     /* Write the configured values back to the Device Control Reg. */
     E1000_WRITE_REG(hw, CTRL, ctrl);
     return E1000_SUCCESS;
@@ -2494,8 +2663,8 @@ e1000_read_phy_reg(struct e1000_hw *hw,
 
     DEBUGFUNC("e1000_read_phy_reg");
 
-
-    if(hw->phy_type == e1000_phy_igp &&
+    if((hw->phy_type == e1000_phy_igp || 
+        hw->phy_type == e1000_phy_igp_2) &&
        (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
         ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                          (uint16_t)reg_addr);
@@ -2600,8 +2769,8 @@ e1000_write_phy_reg(struct e1000_hw *hw,
 
     DEBUGFUNC("e1000_write_phy_reg");
 
-
-    if(hw->phy_type == e1000_phy_igp &&
+    if((hw->phy_type == e1000_phy_igp || 
+        hw->phy_type == e1000_phy_igp_2) &&
        (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
         ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                          (uint16_t)reg_addr);
@@ -2679,19 +2848,27 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw,
     return E1000_SUCCESS;
 }
 
+
 /******************************************************************************
 * Returns the PHY to the power-on reset state
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-void
+int32_t
 e1000_phy_hw_reset(struct e1000_hw *hw)
 {
     uint32_t ctrl, ctrl_ext;
     uint32_t led_ctrl;
+    int32_t ret_val;
 
     DEBUGFUNC("e1000_phy_hw_reset");
 
+    /* In the case of the phy reset being blocked, it's not an error, we
+     * simply return success without performing the reset. */
+    ret_val = e1000_check_phy_reset_block(hw);
+    if (ret_val)
+        return E1000_SUCCESS;
+
     DEBUGOUT("Resetting Phy...\n");
 
     if(hw->mac_type > e1000_82543) {
@@ -2727,6 +2904,11 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
         led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
         E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
     }
+
+    /* Wait for FW to finish PHY configuration. */
+    ret_val = e1000_get_phy_cfg_done(hw);
+
+    return ret_val;
 }
 
 /******************************************************************************
@@ -2744,7 +2926,19 @@ e1000_phy_reset(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_phy_reset");
 
-    if(hw->mac_type != e1000_82541_rev_2) {
+    /* In the case of the phy reset being blocked, it's not an error, we
+     * simply return success without performing the reset. */
+    ret_val = e1000_check_phy_reset_block(hw);
+    if (ret_val)
+        return E1000_SUCCESS;
+
+    switch (hw->mac_type) {
+    case e1000_82541_rev_2:
+        ret_val = e1000_phy_hw_reset(hw);
+        if(ret_val)
+            return ret_val;
+        break;
+    default:
         ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
         if(ret_val)
             return ret_val;
@@ -2755,9 +2949,10 @@ e1000_phy_reset(struct e1000_hw *hw)
             return ret_val;
 
         udelay(1);
-    } else e1000_phy_hw_reset(hw);
+        break;
+    }
 
-    if(hw->phy_type == e1000_phy_igp)
+    if(hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2)
         e1000_phy_init_script(hw);
 
     return E1000_SUCCESS;
@@ -2811,6 +3006,9 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
     case e1000_82547_rev_2:
         if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
         break;
+    case e1000_82573:
+        if(hw->phy_id == M88E1111_I_PHY_ID) match = TRUE;
+        break;
     default:
         DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
         return -E1000_ERR_CONFIG;
@@ -2866,7 +3064,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
 
     /* The downshift status is checked only once, after link is established,
      * and it stored in the hw->speed_downgraded parameter. */
-    phy_info->downshift = hw->speed_downgraded;
+    phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
 
     /* IGP01E1000 does not need to support it. */
     phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
@@ -2905,7 +3103,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
         if(ret_val)
             return ret_val;
 
-        /* transalte to old method */
+        /* Translate to old method */
         average = (max_length + min_length) / 2;
 
         if(average <= e1000_igp_cable_length_50)
@@ -2940,7 +3138,7 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
 
     /* The downshift status is checked only once, after link is established,
      * and it stored in the hw->speed_downgraded parameter. */
-    phy_info->downshift = hw->speed_downgraded;
+    phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
 
     ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
     if(ret_val)
@@ -3029,7 +3227,8 @@ e1000_phy_get_info(struct e1000_hw *hw,
         return -E1000_ERR_CONFIG;
     }
 
-    if(hw->phy_type == e1000_phy_igp)
+    if(hw->phy_type == e1000_phy_igp ||
+        hw->phy_type == e1000_phy_igp_2)
         return e1000_phy_igp_get_info(hw, phy_info);
     else
         return e1000_phy_m88_get_info(hw, phy_info);
@@ -3055,11 +3254,12 @@ e1000_validate_mdi_setting(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+int32_t
 e1000_init_eeprom_params(struct e1000_hw *hw)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     uint32_t eecd = E1000_READ_REG(hw, EECD);
+    int32_t ret_val = E1000_SUCCESS;
     uint16_t eeprom_size;
 
     DEBUGFUNC("e1000_init_eeprom_params");
@@ -3074,6 +3274,8 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
         eeprom->opcode_bits = 3;
         eeprom->address_bits = 6;
         eeprom->delay_usec = 50;
+        eeprom->use_eerd = FALSE;
+        eeprom->use_eewr = FALSE;
         break;
     case e1000_82540:
     case e1000_82545:
@@ -3090,6 +3292,8 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
             eeprom->word_size = 64;
             eeprom->address_bits = 6;
         }
+        eeprom->use_eerd = FALSE;
+        eeprom->use_eewr = FALSE;
         break;
     case e1000_82541:
     case e1000_82541_rev_2:
@@ -3118,42 +3322,60 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
                 eeprom->address_bits = 6;
             }
         }
+        eeprom->use_eerd = FALSE;
+        eeprom->use_eewr = FALSE;
+        break;
+    case e1000_82573:
+        eeprom->type = e1000_eeprom_spi;
+        eeprom->opcode_bits = 8;
+        eeprom->delay_usec = 1;
+        if (eecd & E1000_EECD_ADDR_BITS) {
+            eeprom->page_size = 32;
+            eeprom->address_bits = 16;
+        } else {
+            eeprom->page_size = 8;
+            eeprom->address_bits = 8;
+        }
+        eeprom->use_eerd = TRUE;
+        eeprom->use_eewr = TRUE;
+        if(e1000_is_onboard_nvm_eeprom(hw) == FALSE) {
+            eeprom->type = e1000_eeprom_flash;
+            eeprom->word_size = 2048;
+
+            /* Ensure that the Autonomous FLASH update bit is cleared due to
+             * Flash update issue on parts which use a FLASH for NVM. */
+            eecd &= ~E1000_EECD_AUPDEN;
+            E1000_WRITE_REG(hw, EECD, eecd);
+        }
         break;
     default:
         break;
     }
 
     if (eeprom->type == e1000_eeprom_spi) {
-        eeprom->word_size = 64;
-        if (e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) {
-            eeprom_size &= EEPROM_SIZE_MASK;
-
-            switch (eeprom_size) {
-            case EEPROM_SIZE_16KB:
-                eeprom->word_size = 8192;
-                break;
-            case EEPROM_SIZE_8KB:
-                eeprom->word_size = 4096;
-                break;
-            case EEPROM_SIZE_4KB:
-                eeprom->word_size = 2048;
-                break;
-            case EEPROM_SIZE_2KB:
-                eeprom->word_size = 1024;
-                break;
-            case EEPROM_SIZE_1KB:
-                eeprom->word_size = 512;
-                break;
-            case EEPROM_SIZE_512B:
-                eeprom->word_size = 256;
-                break;
-            case EEPROM_SIZE_128B:
-            default:
-                eeprom->word_size = 64;
-                break;
-            }
+        /* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
+         * 32KB (incremented by powers of 2).
+         */
+        if(hw->mac_type <= e1000_82547_rev_2) {
+            /* Set to default value for initial eeprom read. */
+            eeprom->word_size = 64;
+            ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
+            if(ret_val)
+                return ret_val;
+            eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
+            /* 256B eeprom size was not supported in earlier hardware, so we
+             * bump eeprom_size up one to ensure that "1" (which maps to 256B)
+             * is never the result used in the shifting logic below. */
+            if(eeprom_size)
+                eeprom_size++;
+        } else {
+            eeprom_size = (uint16_t)((eecd & E1000_EECD_SIZE_EX_MASK) >>
+                          E1000_EECD_SIZE_EX_SHIFT);
         }
+
+        eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
     }
+    return ret_val;
 }
 
 /******************************************************************************
@@ -3306,8 +3528,12 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_acquire_eeprom");
 
+    if(e1000_get_hw_eeprom_semaphore(hw))
+        return -E1000_ERR_EEPROM;
+
     eecd = E1000_READ_REG(hw, EECD);
 
+    if (hw->mac_type != e1000_82573) {
     /* Request EEPROM Access */
     if(hw->mac_type > e1000_82544) {
         eecd |= E1000_EECD_REQ;
@@ -3326,6 +3552,7 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
             return -E1000_ERR_EEPROM;
         }
     }
+    }
 
     /* Setup EEPROM for Read/Write */
 
@@ -3443,6 +3670,8 @@ e1000_release_eeprom(struct e1000_hw *hw)
         eecd &= ~E1000_EECD_REQ;
         E1000_WRITE_REG(hw, EECD, eecd);
     }
+
+    e1000_put_hw_eeprom_semaphore(hw);
 }
 
 /******************************************************************************
@@ -3504,8 +3733,10 @@ e1000_read_eeprom(struct e1000_hw *hw,
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     uint32_t i = 0;
+    int32_t ret_val;
 
     DEBUGFUNC("e1000_read_eeprom");
+
     /* A check for invalid values:  offset too large, too many words, and not
      * enough words.
      */
@@ -3515,9 +3746,23 @@ e1000_read_eeprom(struct e1000_hw *hw,
         return -E1000_ERR_EEPROM;
     }
 
-    /* Prepare the EEPROM for reading  */
-    if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
-        return -E1000_ERR_EEPROM;
+    /* FLASH reads without acquiring the semaphore are safe in 82573-based
+     * controllers.
+     */
+    if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
+        (hw->mac_type != e1000_82573)) {
+        /* Prepare the EEPROM for reading  */
+        if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+            return -E1000_ERR_EEPROM;
+    }
+
+    if(eeprom->use_eerd == TRUE) {
+        ret_val = e1000_read_eeprom_eerd(hw, offset, words, data);
+        if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
+            (hw->mac_type != e1000_82573))
+            e1000_release_eeprom(hw);
+        return ret_val;
+    }
 
     if(eeprom->type == e1000_eeprom_spi) {
         uint16_t word_in;
@@ -3569,65 +3814,212 @@ e1000_read_eeprom(struct e1000_hw *hw,
 }
 
 /******************************************************************************
- * Verifies that the EEPROM has a valid checksum
+ * Reads a 16 bit word from the EEPROM using the EERD register.
  *
  * hw - Struct containing variables accessed by shared code
- *
- * Reads the first 64 16 bit words of the EEPROM and sums the values read.
- * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
- * valid.
+ * offset - offset of  word in the EEPROM to read
+ * data - word read from the EEPROM
+ * words - number of words to read
  *****************************************************************************/
 int32_t
-e1000_validate_eeprom_checksum(struct e1000_hw *hw)
+e1000_read_eeprom_eerd(struct e1000_hw *hw,
+                  uint16_t offset,
+                  uint16_t words,
+                  uint16_t *data)
 {
-    uint16_t checksum = 0;
-    uint16_t i, eeprom_data;
+    uint32_t i, eerd = 0;
+    int32_t error = 0;
 
-    DEBUGFUNC("e1000_validate_eeprom_checksum");
+    for (i = 0; i < words; i++) {
+        eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) +
+                         E1000_EEPROM_RW_REG_START;
 
-    for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
-        if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
-            DEBUGOUT("EEPROM Read Error\n");
-            return -E1000_ERR_EEPROM;
+        E1000_WRITE_REG(hw, EERD, eerd);
+        error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);
+        
+        if(error) {
+            break;
         }
-        checksum += eeprom_data;
-    }
-
-    if(checksum == (uint16_t) EEPROM_SUM)
-        return E1000_SUCCESS;
-    else {
-        DEBUGOUT("EEPROM Checksum Invalid\n");
-        return -E1000_ERR_EEPROM;
+        data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA);
+      
     }
+    
+    return error;
 }
 
 /******************************************************************************
- * Calculates the EEPROM checksum and writes it to the EEPROM
+ * Writes a 16 bit word from the EEPROM using the EEWR register.
  *
  * hw - Struct containing variables accessed by shared code
- *
- * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
- * Writes the difference to word offset 63 of the EEPROM.
+ * offset - offset of  word in the EEPROM to read
+ * data - word read from the EEPROM
+ * words - number of words to read
  *****************************************************************************/
 int32_t
-e1000_update_eeprom_checksum(struct e1000_hw *hw)
+e1000_write_eeprom_eewr(struct e1000_hw *hw,
+                   uint16_t offset,
+                   uint16_t words,
+                   uint16_t *data)
 {
-    uint16_t checksum = 0;
-    uint16_t i, eeprom_data;
+    uint32_t    register_value = 0;
+    uint32_t    i              = 0;
+    int32_t     error          = 0;
 
-    DEBUGFUNC("e1000_update_eeprom_checksum");
+    for (i = 0; i < words; i++) {
+        register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) | 
+                         ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) | 
+                         E1000_EEPROM_RW_REG_START;
 
-    for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
-        if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
-            DEBUGOUT("EEPROM Read Error\n");
-            return -E1000_ERR_EEPROM;
-        }
-        checksum += eeprom_data;
+        error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
+        if(error) {
+            break;
+        }       
+
+        E1000_WRITE_REG(hw, EEWR, register_value);
+        
+        error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
+        
+        if(error) {
+            break;
+        }       
+    }
+    
+    return error;
+}
+
+/******************************************************************************
+ * Polls the status bit (bit 1) of the EERD to determine when the read is done.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+int32_t
+e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
+{
+    uint32_t attempts = 100000;
+    uint32_t i, reg = 0;
+    int32_t done = E1000_ERR_EEPROM;
+
+    for(i = 0; i < attempts; i++) {
+        if(eerd == E1000_EEPROM_POLL_READ)
+            reg = E1000_READ_REG(hw, EERD);
+        else 
+            reg = E1000_READ_REG(hw, EEWR);
+
+        if(reg & E1000_EEPROM_RW_REG_DONE) {
+            done = E1000_SUCCESS;
+            break;
+        }
+        udelay(5);
+    }
+
+    return done;
+}
+
+/***************************************************************************
+* Description:     Determines if the onboard NVM is FLASH or EEPROM.
+*
+* hw - Struct containing variables accessed by shared code
+****************************************************************************/
+boolean_t
+e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
+{
+    uint32_t eecd = 0;
+
+    if(hw->mac_type == e1000_82573) {
+        eecd = E1000_READ_REG(hw, EECD);
+
+        /* Isolate bits 15 & 16 */
+        eecd = ((eecd >> 15) & 0x03);
+
+        /* If both bits are set, device is Flash type */
+        if(eecd == 0x03) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+/******************************************************************************
+ * Verifies that the EEPROM has a valid checksum
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Reads the first 64 16 bit words of the EEPROM and sums the values read.
+ * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
+ * valid.
+ *****************************************************************************/
+int32_t
+e1000_validate_eeprom_checksum(struct e1000_hw *hw)
+{
+    uint16_t checksum = 0;
+    uint16_t i, eeprom_data;
+
+    DEBUGFUNC("e1000_validate_eeprom_checksum");
+
+    if ((hw->mac_type == e1000_82573) &&
+        (e1000_is_onboard_nvm_eeprom(hw) == FALSE)) {
+        /* Check bit 4 of word 10h.  If it is 0, firmware is done updating
+         * 10h-12h.  Checksum may need to be fixed. */
+        e1000_read_eeprom(hw, 0x10, 1, &eeprom_data);
+        if ((eeprom_data & 0x10) == 0) {
+            /* Read 0x23 and check bit 15.  This bit is a 1 when the checksum
+             * has already been fixed.  If the checksum is still wrong and this
+             * bit is a 1, we need to return bad checksum.  Otherwise, we need
+             * to set this bit to a 1 and update the checksum. */
+            e1000_read_eeprom(hw, 0x23, 1, &eeprom_data);
+            if ((eeprom_data & 0x8000) == 0) {
+                eeprom_data |= 0x8000;
+                e1000_write_eeprom(hw, 0x23, 1, &eeprom_data);
+                e1000_update_eeprom_checksum(hw);
+            }
+        }
+    }
+
+    for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
+        if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
+            DEBUGOUT("EEPROM Read Error\n");
+            return -E1000_ERR_EEPROM;
+        }
+        checksum += eeprom_data;
+    }
+
+    if(checksum == (uint16_t) EEPROM_SUM)
+        return E1000_SUCCESS;
+    else {
+        DEBUGOUT("EEPROM Checksum Invalid\n");
+        return -E1000_ERR_EEPROM;
+    }
+}
+
+/******************************************************************************
+ * Calculates the EEPROM checksum and writes it to the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
+ * Writes the difference to word offset 63 of the EEPROM.
+ *****************************************************************************/
+int32_t
+e1000_update_eeprom_checksum(struct e1000_hw *hw)
+{
+    uint16_t checksum = 0;
+    uint16_t i, eeprom_data;
+
+    DEBUGFUNC("e1000_update_eeprom_checksum");
+
+    for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
+        if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
+            DEBUGOUT("EEPROM Read Error\n");
+            return -E1000_ERR_EEPROM;
+        }
+        checksum += eeprom_data;
     }
     checksum = (uint16_t) EEPROM_SUM - checksum;
     if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
         DEBUGOUT("EEPROM Write Error\n");
         return -E1000_ERR_EEPROM;
+    } else if (hw->eeprom.type == e1000_eeprom_flash) {
+        e1000_commit_shadow_ram(hw);
     }
     return E1000_SUCCESS;
 }
@@ -3663,6 +4055,10 @@ e1000_write_eeprom(struct e1000_hw *hw,
         return -E1000_ERR_EEPROM;
     }
 
+    /* 82573 reads only through eerd */
+    if(eeprom->use_eewr == TRUE)
+        return e1000_write_eeprom_eewr(hw, offset, words, data);
+
     /* Prepare the EEPROM for writing  */
     if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
         return -E1000_ERR_EEPROM;
@@ -3832,6 +4228,65 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw,
     return E1000_SUCCESS;
 }
 
+/******************************************************************************
+ * Flushes the cached eeprom to NVM. This is done by saving the modified values
+ * in the eeprom cache and the non modified values in the currently active bank
+ * to the new bank.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset of  word in the EEPROM to read
+ * data - word read from the EEPROM
+ * words - number of words to read
+ *****************************************************************************/
+int32_t
+e1000_commit_shadow_ram(struct e1000_hw *hw)
+{
+    uint32_t attempts = 100000;
+    uint32_t eecd = 0;
+    uint32_t flop = 0;
+    uint32_t i = 0;
+    int32_t error = E1000_SUCCESS;
+
+    /* The flop register will be used to determine if flash type is STM */
+    flop = E1000_READ_REG(hw, FLOP);
+
+    if (hw->mac_type == e1000_82573) {
+        for (i=0; i < attempts; i++) {
+            eecd = E1000_READ_REG(hw, EECD);
+            if ((eecd & E1000_EECD_FLUPD) == 0) {
+                break;
+            }
+            udelay(5);
+        }
+
+        if (i == attempts) {
+            return -E1000_ERR_EEPROM;
+        }
+
+       /* If STM opcode located in bits 15:8 of flop, reset firmware */
+        if ((flop & 0xFF00) == E1000_STM_OPCODE) {
+            E1000_WRITE_REG(hw, HICR, E1000_HICR_FW_RESET);
+        }
+
+        /* Perform the flash update */
+        E1000_WRITE_REG(hw, EECD, eecd | E1000_EECD_FLUPD);
+
+       for (i=0; i < attempts; i++) {
+            eecd = E1000_READ_REG(hw, EECD);
+            if ((eecd & E1000_EECD_FLUPD) == 0) {
+                break;
+            }
+            udelay(5);
+        }
+
+        if (i == attempts) {
+            return -E1000_ERR_EEPROM;
+        }
+    }
+
+    return error;
+}
+
 /******************************************************************************
  * Reads the adapter's part number from the EEPROM
  *
@@ -3911,6 +4366,7 @@ void
 e1000_init_rx_addrs(struct e1000_hw *hw)
 {
     uint32_t i;
+    uint32_t rar_num;
 
     DEBUGFUNC("e1000_init_rx_addrs");
 
@@ -3919,9 +4375,10 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
 
     e1000_rar_set(hw, hw->mac_addr, 0);
 
+    rar_num = E1000_RAR_ENTRIES;
     /* Zero out the other 15 receive addresses. */
     DEBUGOUT("Clearing RAR[1-15]\n");
-    for(i = 1; i < E1000_RAR_ENTRIES; i++) {
+    for(i = 1; i < rar_num; i++) {
         E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
         E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
     }
@@ -3950,7 +4407,9 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
 {
     uint32_t hash_value;
     uint32_t i;
-
+    uint32_t num_rar_entry;
+    uint32_t num_mta_entry;
+    
     DEBUGFUNC("e1000_mc_addr_list_update");
 
     /* Set the new number of MC addresses that we are being requested to use. */
@@ -3958,14 +4417,16 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
 
     /* Clear RAR[1-15] */
     DEBUGOUT(" Clearing RAR[1-15]\n");
-    for(i = rar_used_count; i < E1000_RAR_ENTRIES; i++) {
+    num_rar_entry = E1000_RAR_ENTRIES;
+    for(i = rar_used_count; i < num_rar_entry; i++) {
         E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
         E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
     }
 
     /* Clear the MTA */
     DEBUGOUT(" Clearing MTA\n");
-    for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++) {
+    num_mta_entry = E1000_NUM_MTA_REGISTERS;
+    for(i = 0; i < num_mta_entry; i++) {
         E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
     }
 
@@ -3989,7 +4450,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
         /* Place this multicast address in the RAR if there is room, *
          * else put it in the MTA
          */
-        if(rar_used_count < E1000_RAR_ENTRIES) {
+        if (rar_used_count < num_rar_entry) {
             e1000_rar_set(hw,
                           mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)),
                           rar_used_count);
@@ -4040,6 +4501,7 @@ e1000_hash_mc_addr(struct e1000_hw *hw,
     }
 
     hash_value &= 0xFFF;
+
     return hash_value;
 }
 
@@ -4144,12 +4606,33 @@ void
 e1000_clear_vfta(struct e1000_hw *hw)
 {
     uint32_t offset;
-
-    for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
-        E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
+    uint32_t vfta_value = 0;
+    uint32_t vfta_offset = 0;
+    uint32_t vfta_bit_in_reg = 0;
+
+    if (hw->mac_type == e1000_82573) {
+        if (hw->mng_cookie.vlan_id != 0) {
+            /* The VFTA is a 4096b bit-field, each identifying a single VLAN
+             * ID.  The following operations determine which 32b entry
+             * (i.e. offset) into the array we want to set the VLAN ID
+             * (i.e. bit) of the manageability unit. */
+            vfta_offset = (hw->mng_cookie.vlan_id >>
+                           E1000_VFTA_ENTRY_SHIFT) &
+                          E1000_VFTA_ENTRY_MASK;
+            vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
+                                    E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
+        }
+    }
+    for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
+        /* If the offset we want to clear is the same offset of the
+         * manageability VLAN ID, then clear all bits except that of the
+         * manageability unit */
+        vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
+        E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
+    }
 }
 
-static int32_t
+int32_t
 e1000_id_led_init(struct e1000_hw * hw)
 {
     uint32_t ledctl;
@@ -4480,6 +4963,19 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw)
     temp = E1000_READ_REG(hw, MGTPRC);
     temp = E1000_READ_REG(hw, MGTPDC);
     temp = E1000_READ_REG(hw, MGTPTC);
+
+    if(hw->mac_type <= e1000_82547_rev_2) return;
+
+    temp = E1000_READ_REG(hw, IAC);
+    temp = E1000_READ_REG(hw, ICRXOC);
+    temp = E1000_READ_REG(hw, ICRXPTC);
+    temp = E1000_READ_REG(hw, ICRXATC);
+    temp = E1000_READ_REG(hw, ICTXPTC);
+    temp = E1000_READ_REG(hw, ICTXATC);
+    temp = E1000_READ_REG(hw, ICTXQEC);
+    temp = E1000_READ_REG(hw, ICTXQMTC);
+    temp = E1000_READ_REG(hw, ICRXDMTC);
+
 }
 
 /******************************************************************************
@@ -4646,6 +5142,11 @@ e1000_get_bus_info(struct e1000_hw *hw)
         hw->bus_speed = e1000_bus_speed_unknown;
         hw->bus_width = e1000_bus_width_unknown;
         break;
+    case e1000_82573:
+        hw->bus_type = e1000_bus_type_pci_express;
+        hw->bus_speed = e1000_bus_speed_2500;
+        hw->bus_width = e1000_bus_width_pciex_4;
+        break;
     default:
         status = E1000_READ_REG(hw, STATUS);
         hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
@@ -4749,6 +5250,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
 
     /* Use old method for Phy older than IGP */
     if(hw->phy_type == e1000_phy_m88) {
+
         ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
                                      &phy_data);
         if(ret_val)
@@ -4865,7 +5367,8 @@ e1000_check_polarity(struct e1000_hw *hw,
             return ret_val;
         *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
                     M88E1000_PSSR_REV_POLARITY_SHIFT;
-    } else if(hw->phy_type == e1000_phy_igp) {
+    } else if(hw->phy_type == e1000_phy_igp ||
+              hw->phy_type == e1000_phy_igp_2) {
         /* Read the Status register to check the speed */
         ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
                                      &phy_data);
@@ -4917,7 +5420,8 @@ e1000_check_downshift(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_check_downshift");
 
-    if(hw->phy_type == e1000_phy_igp) {
+    if(hw->phy_type == e1000_phy_igp || 
+        hw->phy_type == e1000_phy_igp_2) {
         ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
                                      &phy_data);
         if(ret_val)
@@ -4933,6 +5437,7 @@ e1000_check_downshift(struct e1000_hw *hw)
         hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
                                M88E1000_PSSR_DOWNSHIFT_SHIFT;
     }
+
     return E1000_SUCCESS;
 }
 
@@ -5047,7 +5552,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw,
             if(ret_val)
                 return ret_val;
 
-            msec_delay(20);
+            msec_delay_irq(20);
 
             ret_val = e1000_write_phy_reg(hw, 0x0000,
                                           IGP01E1000_IEEE_FORCE_GIGA);
@@ -5071,7 +5576,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw,
             if(ret_val)
                 return ret_val;
 
-            msec_delay(20);
+            msec_delay_irq(20);
 
             /* Now enable the transmitter */
             ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
@@ -5096,7 +5601,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw,
             if(ret_val)
                 return ret_val;
 
-            msec_delay(20);
+            msec_delay_irq(20);
 
             ret_val = e1000_write_phy_reg(hw, 0x0000,
                                           IGP01E1000_IEEE_FORCE_GIGA);
@@ -5112,7 +5617,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw,
             if(ret_val)
                 return ret_val;
 
-            msec_delay(20);
+            msec_delay_irq(20);
 
             /* Now enable the transmitter */
             ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
@@ -5187,22 +5692,36 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
     uint16_t phy_data;
     DEBUGFUNC("e1000_set_d3_lplu_state");
 
-    if(!((hw->mac_type == e1000_82541_rev_2) ||
-         (hw->mac_type == e1000_82547_rev_2)))
+    if(hw->phy_type != e1000_phy_igp && hw->phy_type != e1000_phy_igp_2)
         return E1000_SUCCESS;
 
     /* During driver activity LPLU should not be used or it will attain link
      * from the lowest speeds starting from 10Mbps. The capability is used for
      * Dx transitions and states */
-    ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
-    if(ret_val)
-        return ret_val;
-
-    if(!active) {
-        phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
-        ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
+    if(hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) {
+        ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
+        if(ret_val)
+            return ret_val;
+    } else {
+        ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
         if(ret_val)
             return ret_val;
+    }
+
+    if(!active) {
+        if(hw->mac_type == e1000_82541_rev_2 ||
+           hw->mac_type == e1000_82547_rev_2) {
+            phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
+            ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
+            if(ret_val)
+                return ret_val;
+        } else {
+                phy_data &= ~IGP02E1000_PM_D3_LPLU;
+                ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+                                              phy_data);
+                if (ret_val)
+                    return ret_val;
+        }
 
         /* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
          * Dx states where the power conservation is most important.  During
@@ -5236,11 +5755,105 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
               (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
               (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
 
-        phy_data |= IGP01E1000_GMII_FLEX_SPD;
-        ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
+        if(hw->mac_type == e1000_82541_rev_2 ||
+           hw->mac_type == e1000_82547_rev_2) {
+            phy_data |= IGP01E1000_GMII_FLEX_SPD;
+            ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
+            if(ret_val)
+                return ret_val;
+        } else {
+                phy_data |= IGP02E1000_PM_D3_LPLU;
+                ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+                                              phy_data);
+                if (ret_val)
+                    return ret_val;
+        }
+
+        /* When LPLU is enabled we should disable SmartSpeed */
+        ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
+        if(ret_val)
+            return ret_val;
+
+        phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+        ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
+        if(ret_val)
+            return ret_val;
+
+    }
+    return E1000_SUCCESS;
+}
+
+/*****************************************************************************
+ *
+ * This function sets the lplu d0 state according to the active flag.  When
+ * activating lplu this function also disables smart speed and vise versa.
+ * lplu will not be activated unless the device autonegotiation advertisment
+ * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
+ * hw: Struct containing variables accessed by shared code
+ * active - true to enable lplu false to disable lplu.
+ *
+ * returns: - E1000_ERR_PHY if fail to read/write the PHY
+ *            E1000_SUCCESS at any other case.
+ *
+ ****************************************************************************/
+
+int32_t
+e1000_set_d0_lplu_state(struct e1000_hw *hw,
+                        boolean_t active)
+{
+    int32_t ret_val;
+    uint16_t phy_data;
+    DEBUGFUNC("e1000_set_d0_lplu_state");
+
+    if(hw->mac_type <= e1000_82547_rev_2)
+        return E1000_SUCCESS;
+
+        ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
         if(ret_val)
             return ret_val;
 
+    if (!active) {
+            phy_data &= ~IGP02E1000_PM_D0_LPLU;
+            ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
+            if (ret_val)
+                return ret_val;
+
+        /* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
+         * Dx states where the power conservation is most important.  During
+         * driver activity we should enable SmartSpeed, so performance is
+         * maintained. */
+        if (hw->smart_speed == e1000_smart_speed_on) {
+            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                         &phy_data);
+            if(ret_val)
+                return ret_val;
+
+            phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
+            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                          phy_data);
+            if(ret_val)
+                return ret_val;
+        } else if (hw->smart_speed == e1000_smart_speed_off) {
+            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                         &phy_data);
+           if (ret_val)
+                return ret_val;
+
+            phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                          phy_data);
+            if(ret_val)
+                return ret_val;
+        }
+
+
+    } else {
+            phy_data |= IGP02E1000_PM_D0_LPLU;   
+            ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
+            if (ret_val)
+                return ret_val;
+
         /* When LPLU is enabled we should disable SmartSpeed */
         ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
         if(ret_val)
@@ -5318,21 +5931,353 @@ e1000_set_vco_speed(struct e1000_hw *hw)
     return E1000_SUCCESS;
 }
 
-static int32_t
-e1000_polarity_reversal_workaround(struct e1000_hw *hw)
+
+/*****************************************************************************
+ * This function reads the cookie from ARC ram.
+ *
+ * returns: - E1000_SUCCESS .
+ ****************************************************************************/
+int32_t
+e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer)
 {
-    int32_t ret_val;
-    uint16_t mii_status_reg;
-    uint16_t i;
+    uint8_t i;
+    uint32_t offset = E1000_MNG_DHCP_COOKIE_OFFSET; 
+    uint8_t length = E1000_MNG_DHCP_COOKIE_LENGTH;
 
-    /* Polarity reversal workaround for forced 10F/10H links. */
+    length = (length >> 2);
+    offset = (offset >> 2);
 
-    /* Disable the transmitter on the PHY */
+    for (i = 0; i < length; i++) {
+        *((uint32_t *) buffer + i) =
+            E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i);
+    }
+    return E1000_SUCCESS;
+}
 
-    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
-    if(ret_val)
-        return ret_val;
-    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
+
+/*****************************************************************************
+ * This function checks whether the HOST IF is enabled for command operaton
+ * and also checks whether the previous command is completed.
+ * It busy waits in case of previous command is not completed.
+ *
+ * returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or 
+ *            timeout
+ *          - E1000_SUCCESS for success.
+ ****************************************************************************/
+int32_t
+e1000_mng_enable_host_if(struct e1000_hw * hw)
+{
+    uint32_t hicr;
+    uint8_t i;
+
+    /* Check that the host interface is enabled. */
+    hicr = E1000_READ_REG(hw, HICR);
+    if ((hicr & E1000_HICR_EN) == 0) {
+        DEBUGOUT("E1000_HOST_EN bit disabled.\n");
+        return -E1000_ERR_HOST_INTERFACE_COMMAND;
+    }
+    /* check the previous command is completed */
+    for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
+        hicr = E1000_READ_REG(hw, HICR);
+        if (!(hicr & E1000_HICR_C))
+            break;
+        msec_delay_irq(1);
+    }
+
+    if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { 
+        DEBUGOUT("Previous command timeout failed .\n");
+        return -E1000_ERR_HOST_INTERFACE_COMMAND;
+    }
+    return E1000_SUCCESS;
+}
+
+/*****************************************************************************
+ * This function writes the buffer content at the offset given on the host if.
+ * It also does alignment considerations to do the writes in most efficient way.
+ * Also fills up the sum of the buffer in *buffer parameter.
+ *
+ * returns  - E1000_SUCCESS for success.
+ ****************************************************************************/
+int32_t
+e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer,
+                        uint16_t length, uint16_t offset, uint8_t *sum)
+{
+    uint8_t *tmp;
+    uint8_t *bufptr = buffer;
+    uint32_t data;
+    uint16_t remaining, i, j, prev_bytes;
+
+    /* sum = only sum of the data and it is not checksum */
+
+    if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
+        return -E1000_ERR_PARAM;
+    }
+
+    tmp = (uint8_t *)&data;
+    prev_bytes = offset & 0x3;
+    offset &= 0xFFFC;
+    offset >>= 2;
+
+    if (prev_bytes) {
+        data = E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset);
+        for (j = prev_bytes; j < sizeof(uint32_t); j++) {
+            *(tmp + j) = *bufptr++;
+            *sum += *(tmp + j);
+        }
+        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset, data);
+        length -= j - prev_bytes;
+        offset++;
+    }
+
+    remaining = length & 0x3;
+    length -= remaining;
+
+    /* Calculate length in DWORDs */
+    length >>= 2;
+
+    /* The device driver writes the relevant command block into the
+     * ram area. */
+    for (i = 0; i < length; i++) {
+        for (j = 0; j < sizeof(uint32_t); j++) {
+            *(tmp + j) = *bufptr++;
+            *sum += *(tmp + j);
+        }
+
+        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
+    }
+    if (remaining) {
+        for (j = 0; j < sizeof(uint32_t); j++) {
+            if (j < remaining)
+                *(tmp + j) = *bufptr++;
+            else
+                *(tmp + j) = 0;
+
+            *sum += *(tmp + j);
+        }
+        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
+    }
+
+    return E1000_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * This function writes the command header after does the checksum calculation.
+ *
+ * returns  - E1000_SUCCESS for success.
+ ****************************************************************************/
+int32_t
+e1000_mng_write_cmd_header(struct e1000_hw * hw,
+                           struct e1000_host_mng_command_header * hdr)
+{
+    uint16_t i;
+    uint8_t sum;
+    uint8_t *buffer;
+
+    /* Write the whole command header structure which includes sum of
+     * the buffer */
+
+    uint16_t length = sizeof(struct e1000_host_mng_command_header);
+
+    sum = hdr->checksum;
+    hdr->checksum = 0;
+
+    buffer = (uint8_t *) hdr;
+    i = length;
+    while(i--)
+        sum += buffer[i];
+
+    hdr->checksum = 0 - sum;
+
+    length >>= 2;
+    /* The device driver writes the relevant command block into the ram area. */
+    for (i = 0; i < length; i++)
+        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((uint32_t *) hdr + i));
+
+    return E1000_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * This function indicates to ARC that a new command is pending which completes
+ * one write operation by the driver.
+ *
+ * returns  - E1000_SUCCESS for success.
+ ****************************************************************************/
+int32_t
+e1000_mng_write_commit(
+    struct e1000_hw * hw)
+{
+    uint32_t hicr;
+
+    hicr = E1000_READ_REG(hw, HICR);
+    /* Setting this bit tells the ARC that a new command is pending. */
+    E1000_WRITE_REG(hw, HICR, hicr | E1000_HICR_C);
+
+    return E1000_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * This function checks the mode of the firmware.
+ *
+ * returns  - TRUE when the mode is IAMT or FALSE.
+ ****************************************************************************/
+boolean_t
+e1000_check_mng_mode(
+    struct e1000_hw *hw)
+{
+    uint32_t fwsm;
+
+    fwsm = E1000_READ_REG(hw, FWSM);
+
+    if((fwsm & E1000_FWSM_MODE_MASK) ==
+        (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
+        return TRUE;
+
+    return FALSE;
+}
+
+
+/*****************************************************************************
+ * This function writes the dhcp info .
+ ****************************************************************************/
+int32_t
+e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
+                         uint16_t length)
+{
+    int32_t ret_val;
+    struct e1000_host_mng_command_header hdr;
+
+    hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
+    hdr.command_length = length;
+    hdr.reserved1 = 0;
+    hdr.reserved2 = 0;
+    hdr.checksum = 0;
+
+    ret_val = e1000_mng_enable_host_if(hw);
+    if (ret_val == E1000_SUCCESS) {
+        ret_val = e1000_mng_host_if_write(hw, buffer, length, sizeof(hdr),
+                                          &(hdr.checksum));
+        if (ret_val == E1000_SUCCESS) {
+            ret_val = e1000_mng_write_cmd_header(hw, &hdr);
+            if (ret_val == E1000_SUCCESS)
+                ret_val = e1000_mng_write_commit(hw);
+        }
+    }
+    return ret_val;
+}
+
+
+/*****************************************************************************
+ * This function calculates the checksum.
+ *
+ * returns  - checksum of buffer contents.
+ ****************************************************************************/
+uint8_t
+e1000_calculate_mng_checksum(char *buffer, uint32_t length)
+{
+    uint8_t sum = 0;
+    uint32_t i;
+
+    if (!buffer)
+        return 0;
+
+    for (i=0; i < length; i++)
+        sum += buffer[i];
+
+    return (uint8_t) (0 - sum);
+}
+
+/*****************************************************************************
+ * This function checks whether tx pkt filtering needs to be enabled or not.
+ *
+ * returns  - TRUE for packet filtering or FALSE.
+ ****************************************************************************/
+boolean_t
+e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
+{
+    /* called in init as well as watchdog timer functions */
+
+    int32_t ret_val, checksum;
+    boolean_t tx_filter = FALSE;
+    struct e1000_host_mng_dhcp_cookie *hdr = &(hw->mng_cookie);
+    uint8_t *buffer = (uint8_t *) &(hw->mng_cookie);
+
+    if (e1000_check_mng_mode(hw)) {
+        ret_val = e1000_mng_enable_host_if(hw);
+        if (ret_val == E1000_SUCCESS) {
+            ret_val = e1000_host_if_read_cookie(hw, buffer);
+            if (ret_val == E1000_SUCCESS) {
+                checksum = hdr->checksum;
+                hdr->checksum = 0;
+                if ((hdr->signature == E1000_IAMT_SIGNATURE) &&
+                    checksum == e1000_calculate_mng_checksum((char *)buffer,
+                                               E1000_MNG_DHCP_COOKIE_LENGTH)) {
+                    if (hdr->status &
+                        E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT)
+                        tx_filter = TRUE;
+                } else
+                    tx_filter = TRUE;
+            } else
+                tx_filter = TRUE;
+        }
+    }
+
+    hw->tx_pkt_filtering = tx_filter;
+    return tx_filter;
+}
+
+/******************************************************************************
+ * Verifies the hardware needs to allow ARPs to be processed by the host
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * returns: - TRUE/FALSE
+ *
+ *****************************************************************************/
+uint32_t
+e1000_enable_mng_pass_thru(struct e1000_hw *hw)
+{
+    uint32_t manc;
+    uint32_t fwsm, factps;
+
+    if (hw->asf_firmware_present) {
+        manc = E1000_READ_REG(hw, MANC);
+
+        if (!(manc & E1000_MANC_RCV_TCO_EN) ||
+            !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
+            return FALSE;
+        if (e1000_arc_subsystem_valid(hw) == TRUE) {
+            fwsm = E1000_READ_REG(hw, FWSM);
+            factps = E1000_READ_REG(hw, FACTPS);
+
+            if (((fwsm & E1000_FWSM_MODE_MASK) ==
+                (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) &&
+                (factps & E1000_FACTPS_MNGCG))
+                return TRUE;
+        } else
+            if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
+                return TRUE;
+    }
+    return FALSE;
+}
+
+static int32_t
+e1000_polarity_reversal_workaround(struct e1000_hw *hw)
+{
+    int32_t ret_val;
+    uint16_t mii_status_reg;
+    uint16_t i;
+
+    /* Polarity reversal workaround for forced 10F/10H links. */
+
+    /* Disable the transmitter on the PHY */
+
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
+    if(ret_val)
+        return ret_val;
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
     if(ret_val)
         return ret_val;
 
@@ -5403,3 +6348,265 @@ e1000_polarity_reversal_workaround(struct e1000_hw *hw)
     return E1000_SUCCESS;
 }
 
+/***************************************************************************
+ *
+ * Disables PCI-Express master access.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - none.
+ *
+ ***************************************************************************/
+void
+e1000_set_pci_express_master_disable(struct e1000_hw *hw)
+{
+    uint32_t ctrl;
+
+    DEBUGFUNC("e1000_set_pci_express_master_disable");
+
+    if (hw->bus_type != e1000_bus_type_pci_express)
+        return;
+
+    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
+    E1000_WRITE_REG(hw, CTRL, ctrl);
+}
+
+/***************************************************************************
+ *
+ * Enables PCI-Express master access.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - none.
+ *
+ ***************************************************************************/
+void
+e1000_enable_pciex_master(struct e1000_hw *hw)
+{
+    uint32_t ctrl;
+
+    DEBUGFUNC("e1000_enable_pciex_master");
+
+    if (hw->bus_type != e1000_bus_type_pci_express)
+        return;
+
+    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
+    E1000_WRITE_REG(hw, CTRL, ctrl);
+}
+
+/*******************************************************************************
+ *
+ * Disables PCI-Express master access and verifies there are no pending requests
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_ERR_MASTER_REQUESTS_PENDING if master disable bit hasn't
+ *            caused the master requests to be disabled.
+ *            E1000_SUCCESS master requests disabled.
+ *
+ ******************************************************************************/
+int32_t
+e1000_disable_pciex_master(struct e1000_hw *hw)
+{
+    int32_t timeout = MASTER_DISABLE_TIMEOUT;   /* 80ms */
+
+    DEBUGFUNC("e1000_disable_pciex_master");
+
+    if (hw->bus_type != e1000_bus_type_pci_express)
+        return E1000_SUCCESS;
+
+    e1000_set_pci_express_master_disable(hw);
+
+    while(timeout) {
+        if(!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
+            break;
+        else
+            udelay(100);
+        timeout--;
+    }
+
+    if(!timeout) {
+        DEBUGOUT("Master requests are pending.\n");
+        return -E1000_ERR_MASTER_REQUESTS_PENDING;
+    }
+
+    return E1000_SUCCESS;
+}
+
+/*******************************************************************************
+ *
+ * Check for EEPROM Auto Read bit done.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_ERR_RESET if fail to reset MAC
+ *            E1000_SUCCESS at any other case.
+ *
+ ******************************************************************************/
+int32_t
+e1000_get_auto_rd_done(struct e1000_hw *hw)
+{
+    int32_t timeout = AUTO_READ_DONE_TIMEOUT;
+
+    DEBUGFUNC("e1000_get_auto_rd_done");
+
+    switch (hw->mac_type) {
+    default:
+        msec_delay(5);
+        break;
+    case e1000_82573:
+        while(timeout) {
+            if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break;
+            else msec_delay(1);
+            timeout--;
+        }
+
+        if(!timeout) {
+            DEBUGOUT("Auto read by HW from EEPROM has not completed.\n");
+            return -E1000_ERR_RESET;
+        }
+        break;
+    }
+
+    return E1000_SUCCESS;
+}
+
+/***************************************************************************
+ * Checks if the PHY configuration is done
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_ERR_RESET if fail to reset MAC
+ *            E1000_SUCCESS at any other case.
+ *
+ ***************************************************************************/
+int32_t
+e1000_get_phy_cfg_done(struct e1000_hw *hw)
+{
+    DEBUGFUNC("e1000_get_phy_cfg_done");
+
+    /* Simply wait for 10ms */
+    msec_delay(10);
+
+    return E1000_SUCCESS;
+}
+
+/***************************************************************************
+ *
+ * Using the combination of SMBI and SWESMBI semaphore bits when resetting
+ * adapter or Eeprom access.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_ERR_EEPROM if fail to access EEPROM.
+ *            E1000_SUCCESS at any other case.
+ *
+ ***************************************************************************/
+int32_t
+e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
+{
+    int32_t timeout;
+    uint32_t swsm;
+
+    DEBUGFUNC("e1000_get_hw_eeprom_semaphore");
+
+    if(!hw->eeprom_semaphore_present)
+        return E1000_SUCCESS;
+
+
+    /* Get the FW semaphore. */
+    timeout = hw->eeprom.word_size + 1;
+    while(timeout) {
+        swsm = E1000_READ_REG(hw, SWSM);
+        swsm |= E1000_SWSM_SWESMBI;
+        E1000_WRITE_REG(hw, SWSM, swsm);
+        /* if we managed to set the bit we got the semaphore. */
+        swsm = E1000_READ_REG(hw, SWSM);
+        if(swsm & E1000_SWSM_SWESMBI)
+            break;
+
+        udelay(50);
+        timeout--;
+    }
+
+    if(!timeout) {
+        /* Release semaphores */
+        e1000_put_hw_eeprom_semaphore(hw);
+        DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n");
+        return -E1000_ERR_EEPROM;
+    }
+
+    return E1000_SUCCESS;
+}
+
+/***************************************************************************
+ * This function clears HW semaphore bits.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - None.
+ *
+ ***************************************************************************/
+void
+e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
+{
+    uint32_t swsm;
+
+    DEBUGFUNC("e1000_put_hw_eeprom_semaphore");
+
+    if(!hw->eeprom_semaphore_present)
+        return;
+
+    swsm = E1000_READ_REG(hw, SWSM);
+    /* Release both semaphores. */
+    swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
+    E1000_WRITE_REG(hw, SWSM, swsm);
+}
+
+/******************************************************************************
+ * Checks if PHY reset is blocked due to SOL/IDER session, for example.
+ * Returning E1000_BLK_PHY_RESET isn't necessarily an error.  But it's up to
+ * the caller to figure out how to deal with it.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_BLK_PHY_RESET
+ *            E1000_SUCCESS
+ *
+ *****************************************************************************/
+int32_t
+e1000_check_phy_reset_block(struct e1000_hw *hw)
+{
+    uint32_t manc = 0;
+    if(hw->mac_type > e1000_82547_rev_2)
+        manc = E1000_READ_REG(hw, MANC);
+    return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
+           E1000_BLK_PHY_RESET : E1000_SUCCESS;
+}
+
+uint8_t
+e1000_arc_subsystem_valid(struct e1000_hw *hw)
+{
+    uint32_t fwsm;
+
+    /* On 8257x silicon, registers in the range of 0x8800 - 0x8FFC
+     * may not be provided a DMA clock when no manageability features are
+     * enabled.  We do not want to perform any reads/writes to these registers
+     * if this is the case.  We read FWSM to determine the manageability mode.
+     */
+    switch (hw->mac_type) {
+    case e1000_82573:
+        fwsm = E1000_READ_REG(hw, FWSM);
+        if((fwsm & E1000_FWSM_MODE_MASK) != 0)
+            return TRUE;
+        break;
+    default:
+        break;
+    }
+    return FALSE;
+}
+
+
+
index f397e637a3c5808a7a41ce650e450ad5b732926c..a0263ee96c6b0ee9133cc0ebdbee7ce08bfe5d75 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   This program is free software; you can redistribute it and/or modify it 
   under the terms of the GNU General Public License as published by the Free 
@@ -57,6 +57,7 @@ typedef enum {
     e1000_82541_rev_2,
     e1000_82547,
     e1000_82547_rev_2,
+    e1000_82573,
     e1000_num_macs
 } e1000_mac_type;
 
@@ -64,6 +65,7 @@ typedef enum {
     e1000_eeprom_uninitialized = 0,
     e1000_eeprom_spi,
     e1000_eeprom_microwire,
+    e1000_eeprom_flash,
     e1000_num_eeprom_types
 } e1000_eeprom_type;
 
@@ -96,6 +98,7 @@ typedef enum {
     e1000_bus_type_unknown = 0,
     e1000_bus_type_pci,
     e1000_bus_type_pcix,
+    e1000_bus_type_pci_express,
     e1000_bus_type_reserved
 } e1000_bus_type;
 
@@ -107,6 +110,7 @@ typedef enum {
     e1000_bus_speed_100,
     e1000_bus_speed_120,
     e1000_bus_speed_133,
+    e1000_bus_speed_2500,
     e1000_bus_speed_reserved
 } e1000_bus_speed;
 
@@ -115,6 +119,8 @@ typedef enum {
     e1000_bus_width_unknown = 0,
     e1000_bus_width_32,
     e1000_bus_width_64,
+    e1000_bus_width_pciex_1,
+    e1000_bus_width_pciex_4,
     e1000_bus_width_reserved
 } e1000_bus_width;
 
@@ -196,6 +202,7 @@ typedef enum {
 typedef enum {
     e1000_phy_m88 = 0,
     e1000_phy_igp,
+    e1000_phy_igp_2,
     e1000_phy_undefined = 0xFF
 } e1000_phy_type;
 
@@ -242,8 +249,19 @@ struct e1000_eeprom_info {
     uint16_t address_bits;
     uint16_t delay_usec;
     uint16_t page_size;
+    boolean_t use_eerd;
+    boolean_t use_eewr;
 };
 
+/* Flex ASF Information */
+#define E1000_HOST_IF_MAX_SIZE  2048
+
+typedef enum {
+    e1000_byte_align = 0,
+    e1000_word_align = 1,
+    e1000_dword_align = 2
+} e1000_align_type;
+
 
 
 /* Error Codes */
@@ -254,11 +272,16 @@ struct e1000_eeprom_info {
 #define E1000_ERR_PARAM    4
 #define E1000_ERR_MAC_TYPE 5
 #define E1000_ERR_PHY_TYPE 6
+#define E1000_ERR_RESET   9
+#define E1000_ERR_MASTER_REQUESTS_PENDING 10
+#define E1000_ERR_HOST_INTERFACE_COMMAND 11
+#define E1000_BLK_PHY_RESET   12
 
 /* Function prototypes */
 /* Initialization */
 int32_t e1000_reset_hw(struct e1000_hw *hw);
 int32_t e1000_init_hw(struct e1000_hw *hw);
+int32_t e1000_id_led_init(struct e1000_hw * hw);
 int32_t e1000_set_mac_type(struct e1000_hw *hw);
 void e1000_set_media_type(struct e1000_hw *hw);
 
@@ -275,7 +298,7 @@ int32_t e1000_force_mac_fc(struct e1000_hw *hw);
 /* PHY */
 int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data);
 int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
-void e1000_phy_hw_reset(struct e1000_hw *hw);
+int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
 int32_t e1000_phy_reset(struct e1000_hw *hw);
 int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
 int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
@@ -287,13 +310,86 @@ int32_t e1000_check_downshift(struct e1000_hw *hw);
 int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
 
 /* EEPROM Functions */
-void e1000_init_eeprom_params(struct e1000_hw *hw);
+int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
+boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
+int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
+
+/* MNG HOST IF functions */
+uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
+
+#define E1000_MNG_DHCP_TX_PAYLOAD_CMD   64
+#define E1000_HI_MAX_MNG_DATA_LENGTH    0x6F8   /* Host Interface data length */
+
+#define E1000_MNG_DHCP_COMMAND_TIMEOUT  10      /* Time in ms to process MNG command */
+#define E1000_MNG_DHCP_COOKIE_OFFSET   0x6F0   /* Cookie offset */
+#define E1000_MNG_DHCP_COOKIE_LENGTH   0x10    /* Cookie length */
+#define E1000_MNG_IAMT_MODE            0x3
+#define E1000_IAMT_SIGNATURE            0x544D4149 /* Intel(R) Active Management Technology signature */
+
+#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT 0x1 /* DHCP parsing enabled */
+#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT    0x2 /* DHCP parsing enabled */
+#define E1000_VFTA_ENTRY_SHIFT                       0x5
+#define E1000_VFTA_ENTRY_MASK                        0x7F
+#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK              0x1F
+
+struct e1000_host_mng_command_header {
+    uint8_t command_id;
+    uint8_t checksum;
+    uint16_t reserved1;
+    uint16_t reserved2;
+    uint16_t command_length;
+};
+
+struct e1000_host_mng_command_info {
+    struct e1000_host_mng_command_header command_header;  /* Command Head/Command Result Head has 4 bytes */
+    uint8_t command_data[E1000_HI_MAX_MNG_DATA_LENGTH];   /* Command data can length 0..0x658*/
+};
+#ifdef __BIG_ENDIAN
+struct e1000_host_mng_dhcp_cookie{
+    uint32_t signature;
+    uint16_t vlan_id;
+    uint8_t reserved0;
+    uint8_t status;
+    uint32_t reserved1;
+    uint8_t checksum;
+    uint8_t reserved3;
+    uint16_t reserved2;
+};
+#else
+struct e1000_host_mng_dhcp_cookie{
+    uint32_t signature;
+    uint8_t status;
+    uint8_t reserved0;
+    uint16_t vlan_id;
+    uint32_t reserved1;
+    uint16_t reserved2;
+    uint8_t reserved3;
+    uint8_t checksum;
+};
+#endif
+
+int32_t e1000_mng_write_dhcp_info(struct e1000_hw *hw, uint8_t *buffer, 
+                                                       uint16_t length);
+boolean_t e1000_check_mng_mode(struct e1000_hw *hw);
+boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
+int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
+int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer,
+                            uint16_t length, uint16_t offset, uint8_t *sum);
+int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw, 
+                                   struct e1000_host_mng_command_header* hdr);
+
+int32_t e1000_mng_write_commit(struct e1000_hw *hw);
+
 int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
 int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
 int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
 int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
 int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
 int32_t e1000_read_mac_addr(struct e1000_hw * hw);
+int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
+void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
 
 /* Filters (multicast, vlan, receive) */
 void e1000_init_rx_addrs(struct e1000_hw *hw);
@@ -313,7 +409,6 @@ int32_t e1000_led_off(struct e1000_hw *hw);
 /* Adaptive IFS Functions */
 
 /* Everything else */
-uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
 void e1000_clear_hw_cntrs(struct e1000_hw *hw);
 void e1000_reset_adaptive(struct e1000_hw *hw);
 void e1000_update_adaptive(struct e1000_hw *hw);
@@ -330,6 +425,19 @@ void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
 void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
 int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
 int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
+void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
+void e1000_enable_pciex_master(struct e1000_hw *hw);
+int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
+int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
+int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
+int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
+void e1000_release_software_semaphore(struct e1000_hw *hw);
+int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
+int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
+void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
+uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
 
 #define E1000_READ_REG_IO(a, reg) \
     e1000_read_reg_io((a), E1000_##reg)
@@ -369,6 +477,10 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
 #define E1000_DEV_ID_82546GB_SERDES      0x107B
 #define E1000_DEV_ID_82546GB_PCIE        0x108A
 #define E1000_DEV_ID_82547EI             0x1019
+#define E1000_DEV_ID_82573E              0x108B
+#define E1000_DEV_ID_82573E_IAMT         0x108C
+
+#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
 
 #define NODE_ADDRESS_SIZE 6
 #define ETH_LENGTH_OF_ADDRESS 6
@@ -381,6 +493,7 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
 #define E1000_REVISION_0       0
 #define E1000_REVISION_1       1
 #define E1000_REVISION_2       2
+#define E1000_REVISION_3       3
 
 #define SPEED_10    10
 #define SPEED_100   100
@@ -437,6 +550,7 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
     E1000_IMS_RXSEQ  |    \
     E1000_IMS_LSC)
 
+
 /* Number of high/low register pairs in the RAR. The RAR (Receive Address
  * Registers) holds the directed and multicast addresses that we monitor. We
  * reserve one of these spots for our directed address, allowing us room for
@@ -457,14 +571,74 @@ struct e1000_rx_desc {
     uint16_t special;
 };
 
+/* Receive Descriptor - Extended */
+union e1000_rx_desc_extended {
+    struct {
+        uint64_t buffer_addr;
+        uint64_t reserved;
+    } read;
+    struct {
+        struct {
+            uint32_t mrq;              /* Multiple Rx Queues */
+            union {
+                uint32_t rss;          /* RSS Hash */
+                struct {
+                    uint16_t ip_id;    /* IP id */
+                    uint16_t csum;     /* Packet Checksum */
+                } csum_ip;
+            } hi_dword;
+        } lower;
+        struct {
+            uint32_t status_error;     /* ext status/error */
+            uint16_t length;
+            uint16_t vlan;             /* VLAN tag */
+        } upper;
+    } wb;  /* writeback */
+};
+
+#define MAX_PS_BUFFERS 4
+/* Receive Descriptor - Packet Split */
+union e1000_rx_desc_packet_split {
+    struct {
+        /* one buffer for protocol header(s), three data buffers */
+        uint64_t buffer_addr[MAX_PS_BUFFERS];
+    } read;
+    struct {
+        struct {
+            uint32_t mrq;              /* Multiple Rx Queues */
+            union {
+                uint32_t rss;          /* RSS Hash */
+                struct {
+                    uint16_t ip_id;    /* IP id */
+                    uint16_t csum;     /* Packet Checksum */
+                } csum_ip;
+            } hi_dword;
+        } lower;
+        struct {
+            uint32_t status_error;     /* ext status/error */
+            uint16_t length0;          /* length of buffer 0 */
+            uint16_t vlan;             /* VLAN tag */
+        } middle;
+        struct {
+            uint16_t header_status;
+            uint16_t length[3];        /* length of buffers 1-3 */
+        } upper;
+        uint64_t reserved;
+    } wb; /* writeback */
+};
+
 /* Receive Decriptor bit definitions */
 #define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
 #define E1000_RXD_STAT_EOP      0x02    /* End of Packet */
 #define E1000_RXD_STAT_IXSM     0x04    /* Ignore checksum */
 #define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
+#define E1000_RXD_STAT_UDPCS    0x10    /* UDP xsum caculated */
 #define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
 #define E1000_RXD_STAT_IPCS     0x40    /* IP xsum calculated */
 #define E1000_RXD_STAT_PIF      0x80    /* passed in-exact filter */
+#define E1000_RXD_STAT_IPIDV    0x200   /* IP identification valid */
+#define E1000_RXD_STAT_UDPV     0x400   /* Valid UDP checksum */
+#define E1000_RXD_STAT_ACK      0x8000  /* ACK Packet indication */
 #define E1000_RXD_ERR_CE        0x01    /* CRC Error */
 #define E1000_RXD_ERR_SE        0x02    /* Symbol Error */
 #define E1000_RXD_ERR_SEQ       0x04    /* Sequence Error */
@@ -474,9 +648,20 @@ struct e1000_rx_desc {
 #define E1000_RXD_ERR_RXE       0x80    /* Rx Data Error */
 #define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */
 #define E1000_RXD_SPC_PRI_MASK  0xE000  /* Priority is in upper 3 bits */
-#define E1000_RXD_SPC_PRI_SHIFT 0x000D  /* Priority is in upper 3 of 16 */
+#define E1000_RXD_SPC_PRI_SHIFT 13
 #define E1000_RXD_SPC_CFI_MASK  0x1000  /* CFI is bit 12 */
-#define E1000_RXD_SPC_CFI_SHIFT 0x000C  /* CFI is bit 12 */
+#define E1000_RXD_SPC_CFI_SHIFT 12
+
+#define E1000_RXDEXT_STATERR_CE    0x01000000
+#define E1000_RXDEXT_STATERR_SE    0x02000000
+#define E1000_RXDEXT_STATERR_SEQ   0x04000000
+#define E1000_RXDEXT_STATERR_CXE   0x10000000
+#define E1000_RXDEXT_STATERR_TCPE  0x20000000
+#define E1000_RXDEXT_STATERR_IPE   0x40000000
+#define E1000_RXDEXT_STATERR_RXE   0x80000000
+
+#define E1000_RXDPS_HDRSTAT_HDRSP        0x00008000
+#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK  0x000003FF
 
 /* mask to determine if packets should be dropped due to frame errors */
 #define E1000_RXD_ERR_FRAME_ERR_MASK ( \
@@ -486,6 +671,15 @@ struct e1000_rx_desc {
     E1000_RXD_ERR_CXE |                \
     E1000_RXD_ERR_RXE)
 
+
+/* Same mask, but for extended and packet split descriptors */
+#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
+    E1000_RXDEXT_STATERR_CE  |            \
+    E1000_RXDEXT_STATERR_SE  |            \
+    E1000_RXDEXT_STATERR_SEQ |            \
+    E1000_RXDEXT_STATERR_CXE |            \
+    E1000_RXDEXT_STATERR_RXE)
+
 /* Transmit Descriptor */
 struct e1000_tx_desc {
     uint64_t buffer_addr;       /* Address of the descriptor's data buffer */
@@ -667,6 +861,7 @@ struct e1000_ffvt_entry {
 #define E1000_ICS      0x000C8  /* Interrupt Cause Set - WO */
 #define E1000_IMS      0x000D0  /* Interrupt Mask Set - RW */
 #define E1000_IMC      0x000D8  /* Interrupt Mask Clear - WO */
+#define E1000_IAM      0x000E0  /* Interrupt Acknowledge Auto Mask */
 #define E1000_RCTL     0x00100  /* RX Control - RW */
 #define E1000_FCTTV    0x00170  /* Flow Control Transmit Timer Value - RW */
 #define E1000_TXCW     0x00178  /* TX Configuration Word - RW */
@@ -676,9 +871,23 @@ struct e1000_ffvt_entry {
 #define E1000_TBT      0x00448  /* TX Burst Timer - RW */
 #define E1000_AIT      0x00458  /* Adaptive Interframe Spacing Throttle - RW */
 #define E1000_LEDCTL   0x00E00  /* LED Control - RW */
+#define E1000_EXTCNF_CTRL  0x00F00  /* Extended Configuration Control */
+#define E1000_EXTCNF_SIZE  0x00F08  /* Extended Configuration Size */
 #define E1000_PBA      0x01000  /* Packet Buffer Allocation - RW */
+#define E1000_PBS      0x01008  /* Packet Buffer Size */
+#define E1000_EEMNGCTL 0x01010  /* MNG EEprom Control */
+#define E1000_FLASH_UPDATES 1000
+#define E1000_EEARBC   0x01024  /* EEPROM Auto Read Bus Control */
+#define E1000_FLASHT   0x01028  /* FLASH Timer Register */
+#define E1000_EEWR     0x0102C  /* EEPROM Write Register - RW */
+#define E1000_FLSWCTL  0x01030  /* FLASH control register */
+#define E1000_FLSWDATA 0x01034  /* FLASH data register */
+#define E1000_FLSWCNT  0x01038  /* FLASH Access Counter */
+#define E1000_FLOP     0x0103C  /* FLASH Opcode Register */
+#define E1000_ERT      0x02008  /* Early Rx Threshold - RW */
 #define E1000_FCRTL    0x02160  /* Flow Control Receive Threshold Low - RW */
 #define E1000_FCRTH    0x02168  /* Flow Control Receive Threshold High - RW */
+#define E1000_PSRCTL   0x02170  /* Packet Split Receive Control - RW */
 #define E1000_RDBAL    0x02800  /* RX Descriptor Base Address Low - RW */
 #define E1000_RDBAH    0x02804  /* RX Descriptor Base Address High - RW */
 #define E1000_RDLEN    0x02808  /* RX Descriptor Length - RW */
@@ -688,6 +897,7 @@ struct e1000_ffvt_entry {
 #define E1000_RXDCTL   0x02828  /* RX Descriptor Control - RW */
 #define E1000_RADV     0x0282C  /* RX Interrupt Absolute Delay Timer - RW */
 #define E1000_RSRPD    0x02C00  /* RX Small Packet Detect - RW */
+#define E1000_RAID     0x02C08  /* Receive Ack Interrupt Delay - RW */
 #define E1000_TXDMAC   0x03000  /* TX DMA Control - RW */
 #define E1000_TDFH     0x03410  /* TX Data FIFO Head - RW */
 #define E1000_TDFT     0x03418  /* TX Data FIFO Tail - RW */
@@ -703,6 +913,14 @@ struct e1000_ffvt_entry {
 #define E1000_TXDCTL   0x03828  /* TX Descriptor Control - RW */
 #define E1000_TADV     0x0382C  /* TX Interrupt Absolute Delay Val - RW */
 #define E1000_TSPMT    0x03830  /* TCP Segmentation PAD & Min Threshold - RW */
+#define E1000_TARC0    0x03840 /* TX Arbitration Count (0) */
+#define E1000_TDBAL1   0x03900 /* TX Desc Base Address Low (1) - RW */
+#define E1000_TDBAH1   0x03904 /* TX Desc Base Address High (1) - RW */
+#define E1000_TDLEN1   0x03908 /* TX Desc Length (1) - RW */
+#define E1000_TDH1     0x03910 /* TX Desc Head (1) - RW */
+#define E1000_TDT1     0x03918 /* TX Desc Tail (1) - RW */
+#define E1000_TXDCTL1  0x03928 /* TX Descriptor Control (1) - RW */
+#define E1000_TARC1    0x03940 /* TX Arbitration Count (1) */
 #define E1000_CRCERRS  0x04000  /* CRC Error Count - R/clr */
 #define E1000_ALGNERRC 0x04004  /* Alignment Error Count - R/clr */
 #define E1000_SYMERRS  0x04008  /* Symbol Error Count - R/clr */
@@ -761,7 +979,17 @@ struct e1000_ffvt_entry {
 #define E1000_BPTC     0x040F4  /* Broadcast Packets TX Count - R/clr */
 #define E1000_TSCTC    0x040F8  /* TCP Segmentation Context TX - R/clr */
 #define E1000_TSCTFC   0x040FC  /* TCP Segmentation Context TX Fail - R/clr */
+#define E1000_IAC       0x4100  /* Interrupt Assertion Count */
+#define E1000_ICRXPTC   0x4104  /* Interrupt Cause Rx Packet Timer Expire Count */
+#define E1000_ICRXATC   0x4108  /* Interrupt Cause Rx Absolute Timer Expire Count */
+#define E1000_ICTXPTC   0x410C  /* Interrupt Cause Tx Packet Timer Expire Count */
+#define E1000_ICTXATC   0x4110  /* Interrupt Cause Tx Absolute Timer Expire Count */
+#define E1000_ICTXQEC   0x4118  /* Interrupt Cause Tx Queue Empty Count */
+#define E1000_ICTXQMTC  0x411C  /* Interrupt Cause Tx Queue Minimum Threshold Count */
+#define E1000_ICRXDMTC  0x4120  /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
+#define E1000_ICRXOC    0x4124  /* Interrupt Cause Receiver Overrun Count */
 #define E1000_RXCSUM   0x05000  /* RX Checksum Control - RW */
+#define E1000_RFCTL    0x05008  /* Receive Filter Control*/
 #define E1000_MTA      0x05200  /* Multicast Table Array - RW Array */
 #define E1000_RA       0x05400  /* Receive Address - RW Array */
 #define E1000_VFTA     0x05600  /* VLAN Filter Table Array - RW Array */
@@ -779,6 +1007,16 @@ struct e1000_ffvt_entry {
 #define E1000_FFMT     0x09000  /* Flexible Filter Mask Table - RW Array */
 #define E1000_FFVT     0x09800  /* Flexible Filter Value Table - RW Array */
 
+#define E1000_GCR       0x05B00 /* PCI-Ex Control */
+#define E1000_GSCL_1    0x05B10 /* PCI-Ex Statistic Control #1 */
+#define E1000_GSCL_2    0x05B14 /* PCI-Ex Statistic Control #2 */
+#define E1000_GSCL_3    0x05B18 /* PCI-Ex Statistic Control #3 */
+#define E1000_GSCL_4    0x05B1C /* PCI-Ex Statistic Control #4 */
+#define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */
+#define E1000_SWSM      0x05B50 /* SW Semaphore */
+#define E1000_FWSM      0x05B54 /* FW Semaphore */
+#define E1000_FFLT_DBG  0x05F04 /* Debug Register */
+#define E1000_HICR      0x08F00 /* Host Inteface Control */
 /* Register Set (82542)
  *
  * Some of the 82542 registers are located at different offsets than they are
@@ -829,6 +1067,18 @@ struct e1000_ffvt_entry {
 #define E1000_82542_VFTA     0x00600
 #define E1000_82542_LEDCTL   E1000_LEDCTL
 #define E1000_82542_PBA      E1000_PBA
+#define E1000_82542_PBS      E1000_PBS
+#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
+#define E1000_82542_EEARBC   E1000_EEARBC
+#define E1000_82542_FLASHT   E1000_FLASHT
+#define E1000_82542_EEWR     E1000_EEWR
+#define E1000_82542_FLSWCTL  E1000_FLSWCTL
+#define E1000_82542_FLSWDATA E1000_FLSWDATA
+#define E1000_82542_FLSWCNT  E1000_FLSWCNT
+#define E1000_82542_FLOP     E1000_FLOP
+#define E1000_82542_EXTCNF_CTRL  E1000_EXTCNF_CTRL
+#define E1000_82542_EXTCNF_SIZE  E1000_EXTCNF_SIZE
+#define E1000_82542_ERT      E1000_ERT
 #define E1000_82542_RXDCTL   E1000_RXDCTL
 #define E1000_82542_RADV     E1000_RADV
 #define E1000_82542_RSRPD    E1000_RSRPD
@@ -913,6 +1163,38 @@ struct e1000_ffvt_entry {
 #define E1000_82542_FFMT     E1000_FFMT
 #define E1000_82542_FFVT     E1000_FFVT
 #define E1000_82542_HOST_IF  E1000_HOST_IF
+#define E1000_82542_IAM         E1000_IAM
+#define E1000_82542_EEMNGCTL    E1000_EEMNGCTL
+#define E1000_82542_PSRCTL      E1000_PSRCTL
+#define E1000_82542_RAID        E1000_RAID
+#define E1000_82542_TARC0       E1000_TARC0
+#define E1000_82542_TDBAL1      E1000_TDBAL1
+#define E1000_82542_TDBAH1      E1000_TDBAH1
+#define E1000_82542_TDLEN1      E1000_TDLEN1
+#define E1000_82542_TDH1        E1000_TDH1
+#define E1000_82542_TDT1        E1000_TDT1
+#define E1000_82542_TXDCTL1     E1000_TXDCTL1
+#define E1000_82542_TARC1       E1000_TARC1
+#define E1000_82542_RFCTL       E1000_RFCTL
+#define E1000_82542_GCR         E1000_GCR
+#define E1000_82542_GSCL_1      E1000_GSCL_1
+#define E1000_82542_GSCL_2      E1000_GSCL_2
+#define E1000_82542_GSCL_3      E1000_GSCL_3
+#define E1000_82542_GSCL_4      E1000_GSCL_4
+#define E1000_82542_FACTPS      E1000_FACTPS
+#define E1000_82542_SWSM        E1000_SWSM
+#define E1000_82542_FWSM        E1000_FWSM
+#define E1000_82542_FFLT_DBG    E1000_FFLT_DBG
+#define E1000_82542_IAC         E1000_IAC
+#define E1000_82542_ICRXPTC     E1000_ICRXPTC
+#define E1000_82542_ICRXATC     E1000_ICRXATC
+#define E1000_82542_ICTXPTC     E1000_ICTXPTC
+#define E1000_82542_ICTXATC     E1000_ICTXATC
+#define E1000_82542_ICTXQEC     E1000_ICTXQEC
+#define E1000_82542_ICTXQMTC    E1000_ICTXQMTC
+#define E1000_82542_ICRXDMTC    E1000_ICRXDMTC
+#define E1000_82542_ICRXOC      E1000_ICRXOC
+#define E1000_82542_HICR        E1000_HICR
 
 /* Statistics counters collected by the MAC */
 struct e1000_hw_stats {
@@ -974,11 +1256,21 @@ struct e1000_hw_stats {
     uint64_t bptc;
     uint64_t tsctc;
     uint64_t tsctfc;
+    uint64_t iac;
+    uint64_t icrxptc;
+    uint64_t icrxatc;
+    uint64_t ictxptc;
+    uint64_t ictxatc;
+    uint64_t ictxqec;
+    uint64_t ictxqmtc;
+    uint64_t icrxdmtc;
+    uint64_t icrxoc;
 };
 
 /* Structure containing variables used by the shared code (e1000_hw.c) */
 struct e1000_hw {
-    uint8_t __iomem *hw_addr;
+    uint8_t *hw_addr;
+    uint8_t *flash_address;
     e1000_mac_type mac_type;
     e1000_phy_type phy_type;
     uint32_t phy_init_script;
@@ -993,6 +1285,7 @@ struct e1000_hw {
     e1000_ms_type original_master_slave;
     e1000_ffe_config ffe_config_state;
     uint32_t asf_firmware_present;
+    uint32_t eeprom_semaphore_present;
     unsigned long io_base;
     uint32_t phy_id;
     uint32_t phy_revision;
@@ -1009,6 +1302,8 @@ struct e1000_hw {
     uint32_t ledctl_default;
     uint32_t ledctl_mode1;
     uint32_t ledctl_mode2;
+    boolean_t tx_pkt_filtering;
+    struct e1000_host_mng_dhcp_cookie mng_cookie;
     uint16_t phy_spd_default;
     uint16_t autoneg_advertised;
     uint16_t pci_cmd_word;
@@ -1047,16 +1342,24 @@ struct e1000_hw {
     boolean_t adaptive_ifs;
     boolean_t ifs_params_forced;
     boolean_t in_ifs_mode;
+    boolean_t mng_reg_access_disabled;
 };
 
 
 #define E1000_EEPROM_SWDPIN0   0x0001   /* SWDPIN 0 EEPROM Value */
 #define E1000_EEPROM_LED_LOGIC 0x0020   /* Led Logic Word */
+#define E1000_EEPROM_RW_REG_DATA   16   /* Offset to data in EEPROM read/write registers */
+#define E1000_EEPROM_RW_REG_DONE   2    /* Offset to READ/WRITE done bit */
+#define E1000_EEPROM_RW_REG_START  1    /* First bit for telling part to start operation */
+#define E1000_EEPROM_RW_ADDR_SHIFT 2    /* Shift to the address bits */
+#define E1000_EEPROM_POLL_WRITE    1    /* Flag for polling for write complete */
+#define E1000_EEPROM_POLL_READ     0    /* Flag for polling for read complete */
 /* Register Bit Masks */
 /* Device Control */
 #define E1000_CTRL_FD       0x00000001  /* Full duplex.0=half; 1=full */
 #define E1000_CTRL_BEM      0x00000002  /* Endian Mode.0=little,1=big */
 #define E1000_CTRL_PRIOR    0x00000004  /* Priority on PCI. 0=rx,1=fair */
+#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
 #define E1000_CTRL_LRST     0x00000008  /* Link reset. 0=normal,1=reset */
 #define E1000_CTRL_TME      0x00000010  /* Test mode. 0=normal,1=test */
 #define E1000_CTRL_SLE      0x00000020  /* Serial Link on 0=dis,1=en */
@@ -1070,6 +1373,7 @@ struct e1000_hw {
 #define E1000_CTRL_BEM32    0x00000400  /* Big Endian 32 mode */
 #define E1000_CTRL_FRCSPD   0x00000800  /* Force Speed */
 #define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */
+#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
 #define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
 #define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
 #define E1000_CTRL_SWDPIN2  0x00100000  /* SWDPIN 2 value */
@@ -1089,6 +1393,7 @@ struct e1000_hw {
 #define E1000_STATUS_FD         0x00000001      /* Full duplex.0=half,1=full */
 #define E1000_STATUS_LU         0x00000002      /* Link up.0=no,1=link */
 #define E1000_STATUS_FUNC_MASK  0x0000000C      /* PCI Function Mask */
+#define E1000_STATUS_FUNC_SHIFT 2
 #define E1000_STATUS_FUNC_0     0x00000000      /* Function 0 */
 #define E1000_STATUS_FUNC_1     0x00000004      /* Function 1 */
 #define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */
@@ -1098,6 +1403,8 @@ struct e1000_hw {
 #define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */
 #define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */
 #define E1000_STATUS_ASDV       0x00000300      /* Auto speed detect value */
+#define E1000_STATUS_DOCK_CI    0x00000800      /* Change in Dock/Undock state. Clear on write '0'. */
+#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
 #define E1000_STATUS_MTXCKOK    0x00000400      /* MTX clock running OK */
 #define E1000_STATUS_PCI66      0x00000800      /* In 66Mhz slot */
 #define E1000_STATUS_BUS64      0x00001000      /* In 64 bit slot */
@@ -1128,6 +1435,18 @@ struct e1000_hw {
 #ifndef E1000_EEPROM_GRANT_ATTEMPTS
 #define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
 #endif
+#define E1000_EECD_AUTO_RD          0x00000200  /* EEPROM Auto Read done */
+#define E1000_EECD_SIZE_EX_MASK     0x00007800  /* EEprom Size */
+#define E1000_EECD_SIZE_EX_SHIFT    11
+#define E1000_EECD_NVADDS    0x00018000 /* NVM Address Size */
+#define E1000_EECD_SELSHAD   0x00020000 /* Select Shadow RAM */
+#define E1000_EECD_INITSRAM  0x00040000 /* Initialize Shadow RAM */
+#define E1000_EECD_FLUPD     0x00080000 /* Update FLASH */
+#define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
+#define E1000_EECD_SHADV     0x00200000 /* Shadow RAM Data Valid */
+#define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
+#define E1000_STM_OPCODE     0xDB00
+#define E1000_HICR_FW_RESET  0xC0
 
 /* EEPROM Read */
 #define E1000_EERD_START      0x00000001 /* Start Read */
@@ -1171,6 +1490,8 @@ struct e1000_hw {
 #define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
 #define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
 #define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
+#define E1000_CTRL_EXT_IAME           0x08000000  /* Interrupt acknowledge Auto-mask */
+#define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000  /* Clear Interrupt timers after IMS clear */
 
 /* MDI Control */
 #define E1000_MDIC_DATA_MASK 0x0000FFFF
@@ -1187,14 +1508,17 @@ struct e1000_hw {
 /* LED Control */
 #define E1000_LEDCTL_LED0_MODE_MASK       0x0000000F
 #define E1000_LEDCTL_LED0_MODE_SHIFT      0
+#define E1000_LEDCTL_LED0_BLINK_RATE      0x0000020
 #define E1000_LEDCTL_LED0_IVRT            0x00000040
 #define E1000_LEDCTL_LED0_BLINK           0x00000080
 #define E1000_LEDCTL_LED1_MODE_MASK       0x00000F00
 #define E1000_LEDCTL_LED1_MODE_SHIFT      8
+#define E1000_LEDCTL_LED1_BLINK_RATE      0x0002000
 #define E1000_LEDCTL_LED1_IVRT            0x00004000
 #define E1000_LEDCTL_LED1_BLINK           0x00008000
 #define E1000_LEDCTL_LED2_MODE_MASK       0x000F0000
 #define E1000_LEDCTL_LED2_MODE_SHIFT      16
+#define E1000_LEDCTL_LED2_BLINK_RATE      0x00200000
 #define E1000_LEDCTL_LED2_IVRT            0x00400000
 #define E1000_LEDCTL_LED2_BLINK           0x00800000
 #define E1000_LEDCTL_LED3_MODE_MASK       0x0F000000
@@ -1238,6 +1562,10 @@ struct e1000_hw {
 #define E1000_ICR_GPI_EN3       0x00004000 /* GP Int 3 */
 #define E1000_ICR_TXD_LOW       0x00008000
 #define E1000_ICR_SRPD          0x00010000
+#define E1000_ICR_ACK           0x00020000 /* Receive Ack frame */
+#define E1000_ICR_MNG           0x00040000 /* Manageability event */
+#define E1000_ICR_DOCK          0x00080000 /* Dock/Undock */
+#define E1000_ICR_INT_ASSERTED  0x80000000 /* If this bit asserted, the driver should claim the interrupt */
 
 /* Interrupt Cause Set */
 #define E1000_ICS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
@@ -1255,6 +1583,9 @@ struct e1000_hw {
 #define E1000_ICS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
 #define E1000_ICS_TXD_LOW   E1000_ICR_TXD_LOW
 #define E1000_ICS_SRPD      E1000_ICR_SRPD
+#define E1000_ICS_ACK       E1000_ICR_ACK       /* Receive Ack frame */
+#define E1000_ICS_MNG       E1000_ICR_MNG       /* Manageability event */
+#define E1000_ICS_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
 
 /* Interrupt Mask Set */
 #define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
@@ -1272,6 +1603,9 @@ struct e1000_hw {
 #define E1000_IMS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
 #define E1000_IMS_TXD_LOW   E1000_ICR_TXD_LOW
 #define E1000_IMS_SRPD      E1000_ICR_SRPD
+#define E1000_IMS_ACK       E1000_ICR_ACK       /* Receive Ack frame */
+#define E1000_IMS_MNG       E1000_ICR_MNG       /* Manageability event */
+#define E1000_IMS_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
 
 /* Interrupt Mask Clear */
 #define E1000_IMC_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
@@ -1289,6 +1623,9 @@ struct e1000_hw {
 #define E1000_IMC_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
 #define E1000_IMC_TXD_LOW   E1000_ICR_TXD_LOW
 #define E1000_IMC_SRPD      E1000_ICR_SRPD
+#define E1000_IMC_ACK       E1000_ICR_ACK       /* Receive Ack frame */
+#define E1000_IMC_MNG       E1000_ICR_MNG       /* Manageability event */
+#define E1000_IMC_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
 
 /* Receive Control */
 #define E1000_RCTL_RST            0x00000001    /* Software reset */
@@ -1301,6 +1638,8 @@ struct e1000_hw {
 #define E1000_RCTL_LBM_MAC        0x00000040    /* MAC loopback mode */
 #define E1000_RCTL_LBM_SLP        0x00000080    /* serial link loopback mode */
 #define E1000_RCTL_LBM_TCVR       0x000000C0    /* tcvr loopback mode */
+#define E1000_RCTL_DTYP_MASK      0x00000C00    /* Descriptor type mask */
+#define E1000_RCTL_DTYP_PS        0x00000400    /* Packet Split descriptor */
 #define E1000_RCTL_RDMTS_HALF     0x00000000    /* rx desc min threshold size */
 #define E1000_RCTL_RDMTS_QUAT     0x00000100    /* rx desc min threshold size */
 #define E1000_RCTL_RDMTS_EIGTH    0x00000200    /* rx desc min threshold size */
@@ -1327,6 +1666,34 @@ struct e1000_hw {
 #define E1000_RCTL_PMCF           0x00800000    /* pass MAC control frames */
 #define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
 #define E1000_RCTL_SECRC          0x04000000    /* Strip Ethernet CRC */
+#define E1000_RCTL_FLXBUF_MASK    0x78000000    /* Flexible buffer size */
+#define E1000_RCTL_FLXBUF_SHIFT   27            /* Flexible buffer shift */
+
+/* Use byte values for the following shift parameters
+ * Usage:
+ *     psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
+ *                  E1000_PSRCTL_BSIZE0_MASK) |
+ *                ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
+ *                  E1000_PSRCTL_BSIZE1_MASK) |
+ *                ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
+ *                  E1000_PSRCTL_BSIZE2_MASK) |
+ *                ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
+ *                  E1000_PSRCTL_BSIZE3_MASK))
+ * where value0 = [128..16256],  default=256
+ *       value1 = [1024..64512], default=4096
+ *       value2 = [0..64512],    default=4096
+ *       value3 = [0..64512],    default=0
+ */
+    
+#define E1000_PSRCTL_BSIZE0_MASK   0x0000007F
+#define E1000_PSRCTL_BSIZE1_MASK   0x00003F00
+#define E1000_PSRCTL_BSIZE2_MASK   0x003F0000
+#define E1000_PSRCTL_BSIZE3_MASK   0x3F000000
+
+#define E1000_PSRCTL_BSIZE0_SHIFT  7            /* Shift _right_ 7 */
+#define E1000_PSRCTL_BSIZE1_SHIFT  2            /* Shift _right_ 2 */
+#define E1000_PSRCTL_BSIZE2_SHIFT  6            /* Shift _left_ 6 */
+#define E1000_PSRCTL_BSIZE3_SHIFT 14            /* Shift _left_ 14 */
 
 /* Receive Descriptor */
 #define E1000_RDT_DELAY 0x0000ffff      /* Delay timer (1=1024us) */
@@ -1341,6 +1708,23 @@ struct e1000_hw {
 #define E1000_FCRTL_RTL  0x0000FFF8     /* Mask Bits[15:3] for RTL */
 #define E1000_FCRTL_XONE 0x80000000     /* Enable XON frame transmission */
 
+/* Header split receive */
+#define E1000_RFCTL_ISCSI_DIS           0x00000001
+#define E1000_RFCTL_ISCSI_DWC_MASK      0x0000003E
+#define E1000_RFCTL_ISCSI_DWC_SHIFT     1
+#define E1000_RFCTL_NFSW_DIS            0x00000040
+#define E1000_RFCTL_NFSR_DIS            0x00000080
+#define E1000_RFCTL_NFS_VER_MASK        0x00000300
+#define E1000_RFCTL_NFS_VER_SHIFT       8
+#define E1000_RFCTL_IPV6_DIS            0x00000400
+#define E1000_RFCTL_IPV6_XSUM_DIS       0x00000800
+#define E1000_RFCTL_ACK_DIS             0x00001000
+#define E1000_RFCTL_ACKD_DIS            0x00002000
+#define E1000_RFCTL_IPFRSP_DIS          0x00004000
+#define E1000_RFCTL_EXTEN               0x00008000
+#define E1000_RFCTL_IPV6_EX_DIS         0x00010000
+#define E1000_RFCTL_NEW_IPV6_EXT_DIS    0x00020000
+
 /* Receive Descriptor Control */
 #define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */
 #define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */
@@ -1354,6 +1738,8 @@ struct e1000_hw {
 #define E1000_TXDCTL_GRAN    0x01000000 /* TXDCTL Granularity */
 #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
 #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
+#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc.
+                                              still to be processed. */
 
 /* Transmit Configuration Word */
 #define E1000_TXCW_FD         0x00000020        /* TXCW full duplex */
@@ -1387,12 +1773,16 @@ struct e1000_hw {
 #define E1000_TCTL_PBE    0x00800000    /* Packet Burst Enable */
 #define E1000_TCTL_RTLC   0x01000000    /* Re-transmit on late collision */
 #define E1000_TCTL_NRTU   0x02000000    /* No Re-transmit on underrun */
+#define E1000_TCTL_MULR   0x10000000    /* Multiple request support */
 
 /* Receive Checksum Control */
 #define E1000_RXCSUM_PCSS_MASK 0x000000FF   /* Packet Checksum Start */
 #define E1000_RXCSUM_IPOFL     0x00000100   /* IPv4 checksum offload */
 #define E1000_RXCSUM_TUOFL     0x00000200   /* TCP / UDP checksum offload */
 #define E1000_RXCSUM_IPV6OFL   0x00000400   /* IPv6 checksum offload */
+#define E1000_RXCSUM_IPPCSE    0x00001000   /* IP payload checksum enable */
+#define E1000_RXCSUM_PCSD      0x00002000   /* packet checksum disabled */
+
 
 /* Definitions for power management and wakeup registers */
 /* Wake Up Control */
@@ -1411,6 +1801,7 @@ struct e1000_hw {
 #define E1000_WUFC_ARP  0x00000020 /* ARP Request Packet Wakeup Enable */
 #define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
 #define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
+#define E1000_WUFC_IGNORE_TCO      0x00008000 /* Ignore WakeOn TCO packets */
 #define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
 #define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
 #define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
@@ -1446,13 +1837,19 @@ struct e1000_hw {
 #define E1000_MANC_ARP_EN        0x00002000 /* Enable ARP Request Filtering */
 #define E1000_MANC_NEIGHBOR_EN   0x00004000 /* Enable Neighbor Discovery
                                              * Filtering */
+#define E1000_MANC_ARP_RES_EN    0x00008000 /* Enable ARP response Filtering */
 #define E1000_MANC_TCO_RESET     0x00010000 /* TCO Reset Occurred */
 #define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
 #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
+#define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000 /* Block phy resets */
 #define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000 /* Enable MAC address
                                                     * filtering */
 #define E1000_MANC_EN_MNG2HOST   0x00200000 /* Enable MNG packets to host
                                              * memory */
+#define E1000_MANC_EN_IP_ADDR_FILTER    0x00400000 /* Enable IP address
+                                                    * filtering */
+#define E1000_MANC_EN_XSUM_FILTER   0x00800000 /* Enable checksum filtering */
+#define E1000_MANC_BR_EN            0x01000000 /* Enable broadcast filtering */
 #define E1000_MANC_SMB_REQ       0x01000000 /* SMBus Request */
 #define E1000_MANC_SMB_GNT       0x02000000 /* SMBus Grant */
 #define E1000_MANC_SMB_CLK_IN    0x04000000 /* SMBus Clock In */
@@ -1463,11 +1860,97 @@ struct e1000_hw {
 #define E1000_MANC_SMB_DATA_OUT_SHIFT  28 /* SMBus Data Out Shift */
 #define E1000_MANC_SMB_CLK_OUT_SHIFT   29 /* SMBus Clock Out Shift */
 
+/* SW Semaphore Register */
+#define E1000_SWSM_SMBI         0x00000001 /* Driver Semaphore bit */
+#define E1000_SWSM_SWESMBI      0x00000002 /* FW Semaphore bit */
+#define E1000_SWSM_WMNG         0x00000004 /* Wake MNG Clock */
+#define E1000_SWSM_DRV_LOAD     0x00000008 /* Driver Loaded Bit */
+
+/* FW Semaphore Register */
+#define E1000_FWSM_MODE_MASK    0x0000000E /* FW mode */
+#define E1000_FWSM_MODE_SHIFT            1
+#define E1000_FWSM_FW_VALID     0x00008000 /* FW established a valid mode */
+
+/* FFLT Debug Register */
+#define E1000_FFLT_DBG_INVC     0x00100000 /* Invalid /C/ code handling */
+
+typedef enum {
+    e1000_mng_mode_none     = 0,
+    e1000_mng_mode_asf,
+    e1000_mng_mode_pt,
+    e1000_mng_mode_ipmi,
+    e1000_mng_mode_host_interface_only
+} e1000_mng_mode;
+
+/* Host Inteface Control Register */
+#define E1000_HICR_EN           0x00000001  /* Enable Bit - RO */
+#define E1000_HICR_C            0x00000002  /* Driver sets this bit when done
+                                             * to put command in RAM */
+#define E1000_HICR_SV           0x00000004  /* Status Validity */
+#define E1000_HICR_FWR          0x00000080  /* FW reset. Set by the Host */
+
+/* Host Interface Command Interface - Address range 0x8800-0x8EFF */
+#define E1000_HI_MAX_DATA_LENGTH         252 /* Host Interface data length */
+#define E1000_HI_MAX_BLOCK_BYTE_LENGTH  1792 /* Number of bytes in range */
+#define E1000_HI_MAX_BLOCK_DWORD_LENGTH  448 /* Number of dwords in range */
+#define E1000_HI_COMMAND_TIMEOUT         500 /* Time in ms to process HI command */
+
+struct e1000_host_command_header {
+    uint8_t command_id;
+    uint8_t command_length;
+    uint8_t command_options;   /* I/F bits for command, status for return */
+    uint8_t checksum;
+};
+struct e1000_host_command_info {
+    struct e1000_host_command_header command_header;  /* Command Head/Command Result Head has 4 bytes */
+    uint8_t command_data[E1000_HI_MAX_DATA_LENGTH];   /* Command data can length 0..252 */
+};
+
+/* Host SMB register #0 */
+#define E1000_HSMC0R_CLKIN      0x00000001  /* SMB Clock in */
+#define E1000_HSMC0R_DATAIN     0x00000002  /* SMB Data in */
+#define E1000_HSMC0R_DATAOUT    0x00000004  /* SMB Data out */
+#define E1000_HSMC0R_CLKOUT     0x00000008  /* SMB Clock out */
+
+/* Host SMB register #1 */
+#define E1000_HSMC1R_CLKIN      E1000_HSMC0R_CLKIN
+#define E1000_HSMC1R_DATAIN     E1000_HSMC0R_DATAIN
+#define E1000_HSMC1R_DATAOUT    E1000_HSMC0R_DATAOUT
+#define E1000_HSMC1R_CLKOUT     E1000_HSMC0R_CLKOUT
+
+/* FW Status Register */
+#define E1000_FWSTS_FWS_MASK    0x000000FF  /* FW Status */
+
 /* Wake Up Packet Length */
 #define E1000_WUPL_LENGTH_MASK 0x0FFF   /* Only the lower 12 bits are valid */
 
 #define E1000_MDALIGN          4096
 
+#define E1000_GCR_BEM32                 0x00400000
+/* Function Active and Power State to MNG */
+#define E1000_FACTPS_FUNC0_POWER_STATE_MASK         0x00000003
+#define E1000_FACTPS_LAN0_VALID                     0x00000004
+#define E1000_FACTPS_FUNC0_AUX_EN                   0x00000008
+#define E1000_FACTPS_FUNC1_POWER_STATE_MASK         0x000000C0
+#define E1000_FACTPS_FUNC1_POWER_STATE_SHIFT        6
+#define E1000_FACTPS_LAN1_VALID                     0x00000100
+#define E1000_FACTPS_FUNC1_AUX_EN                   0x00000200
+#define E1000_FACTPS_FUNC2_POWER_STATE_MASK         0x00003000
+#define E1000_FACTPS_FUNC2_POWER_STATE_SHIFT        12
+#define E1000_FACTPS_IDE_ENABLE                     0x00004000
+#define E1000_FACTPS_FUNC2_AUX_EN                   0x00008000
+#define E1000_FACTPS_FUNC3_POWER_STATE_MASK         0x000C0000
+#define E1000_FACTPS_FUNC3_POWER_STATE_SHIFT        18
+#define E1000_FACTPS_SP_ENABLE                      0x00100000
+#define E1000_FACTPS_FUNC3_AUX_EN                   0x00200000
+#define E1000_FACTPS_FUNC4_POWER_STATE_MASK         0x03000000
+#define E1000_FACTPS_FUNC4_POWER_STATE_SHIFT        24
+#define E1000_FACTPS_IPMI_ENABLE                    0x04000000
+#define E1000_FACTPS_FUNC4_AUX_EN                   0x08000000
+#define E1000_FACTPS_MNGCG                          0x20000000
+#define E1000_FACTPS_LAN_FUNC_SEL                   0x40000000
+#define E1000_FACTPS_PM_STATE_CHANGED               0x80000000
+
 /* EEPROM Commands - Microwire */
 #define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */
 #define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */
@@ -1477,22 +1960,20 @@ struct e1000_hw {
 
 /* EEPROM Commands - SPI */
 #define EEPROM_MAX_RETRY_SPI    5000 /* Max wait of 5ms, for RDY signal */
-#define EEPROM_READ_OPCODE_SPI  0x3  /* EEPROM read opcode */
-#define EEPROM_WRITE_OPCODE_SPI 0x2  /* EEPROM write opcode */
-#define EEPROM_A8_OPCODE_SPI    0x8  /* opcode bit-3 = address bit-8 */
-#define EEPROM_WREN_OPCODE_SPI  0x6  /* EEPROM set Write Enable latch */
-#define EEPROM_WRDI_OPCODE_SPI  0x4  /* EEPROM reset Write Enable latch */
-#define EEPROM_RDSR_OPCODE_SPI  0x5  /* EEPROM read Status register */
-#define EEPROM_WRSR_OPCODE_SPI  0x1  /* EEPROM write Status register */
+#define EEPROM_READ_OPCODE_SPI      0x03  /* EEPROM read opcode */
+#define EEPROM_WRITE_OPCODE_SPI     0x02  /* EEPROM write opcode */
+#define EEPROM_A8_OPCODE_SPI        0x08  /* opcode bit-3 = address bit-8 */
+#define EEPROM_WREN_OPCODE_SPI      0x06  /* EEPROM set Write Enable latch */
+#define EEPROM_WRDI_OPCODE_SPI      0x04  /* EEPROM reset Write Enable latch */
+#define EEPROM_RDSR_OPCODE_SPI      0x05  /* EEPROM read Status register */
+#define EEPROM_WRSR_OPCODE_SPI      0x01  /* EEPROM write Status register */
+#define EEPROM_ERASE4K_OPCODE_SPI   0x20  /* EEPROM ERASE 4KB */
+#define EEPROM_ERASE64K_OPCODE_SPI  0xD8  /* EEPROM ERASE 64KB */
+#define EEPROM_ERASE256_OPCODE_SPI  0xDB  /* EEPROM ERASE 256B */
 
 /* EEPROM Size definitions */
-#define EEPROM_SIZE_16KB        0x1800
-#define EEPROM_SIZE_8KB         0x1400
-#define EEPROM_SIZE_4KB         0x1000
-#define EEPROM_SIZE_2KB         0x0C00
-#define EEPROM_SIZE_1KB         0x0800
-#define EEPROM_SIZE_512B        0x0400
-#define EEPROM_SIZE_128B        0x0000
+#define EEPROM_WORD_SIZE_SHIFT  6
+#define EEPROM_SIZE_SHIFT       10
 #define EEPROM_SIZE_MASK        0x1C00
 
 /* EEPROM Word Offsets */
@@ -1606,7 +2087,22 @@ struct e1000_hw {
 #define IFS_MIN                40
 #define IFS_RATIO              4
 
+/* Extended Configuration Control and Size */
+#define E1000_EXTCNF_CTRL_PCIE_WRITE_ENABLE 0x00000001
+#define E1000_EXTCNF_CTRL_PHY_WRITE_ENABLE  0x00000002
+#define E1000_EXTCNF_CTRL_D_UD_ENABLE       0x00000004
+#define E1000_EXTCNF_CTRL_D_UD_LATENCY      0x00000008
+#define E1000_EXTCNF_CTRL_D_UD_OWNER        0x00000010
+#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
+#define E1000_EXTCNF_CTRL_MDIO_HW_OWNERSHIP 0x00000040
+#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER   0x1FFF0000
+
+#define E1000_EXTCNF_SIZE_EXT_PHY_LENGTH    0x000000FF
+#define E1000_EXTCNF_SIZE_EXT_DOCK_LENGTH   0x0000FF00
+#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH   0x00FF0000
+
 /* PBA constants */
+#define E1000_PBA_12K 0x000C    /* 12KB, default Rx allocation */
 #define E1000_PBA_16K 0x0010    /* 16KB, default TX allocation */
 #define E1000_PBA_22K 0x0016
 #define E1000_PBA_24K 0x0018
@@ -1663,6 +2159,13 @@ struct e1000_hw {
 /* Number of milliseconds we wait for auto-negotiation to complete */
 #define LINK_UP_TIMEOUT             500
 
+/* Number of 100 microseconds we wait for PCI Express master disable */
+#define MASTER_DISABLE_TIMEOUT      800
+/* Number of milliseconds we wait for Eeprom auto read bit done after MAC reset */
+#define AUTO_READ_DONE_TIMEOUT      10
+/* Number of milliseconds we wait for PHY configuration done after MAC reset */
+#define PHY_CFG_TIMEOUT             40
+
 #define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
 
 /* The carrier extension symbol, as received by the NIC. */
@@ -1763,6 +2266,7 @@ struct e1000_hw {
 #define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */
 #define IGP01E1000_GMII_FIFO       0x14 /* GMII FIFO Register */
 #define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */
+#define IGP02E1000_PHY_POWER_MGMT      0x19
 #define IGP01E1000_PHY_PAGE_SELECT     0x1F /* PHY Page Select Core Register */
 
 /* IGP01E1000 AGC Registers - stores the cable length values*/
@@ -1771,12 +2275,20 @@ struct e1000_hw {
 #define IGP01E1000_PHY_AGC_C        0x1472
 #define IGP01E1000_PHY_AGC_D        0x1872
 
+/* IGP02E1000 AGC Registers for cable length values */
+#define IGP02E1000_PHY_AGC_A        0x11B1
+#define IGP02E1000_PHY_AGC_B        0x12B1
+#define IGP02E1000_PHY_AGC_C        0x14B1
+#define IGP02E1000_PHY_AGC_D        0x18B1
+
 /* IGP01E1000 DSP Reset Register */
 #define IGP01E1000_PHY_DSP_RESET   0x1F33
 #define IGP01E1000_PHY_DSP_SET     0x1F71
 #define IGP01E1000_PHY_DSP_FFE     0x1F35
 
 #define IGP01E1000_PHY_CHANNEL_NUM    4
+#define IGP02E1000_PHY_CHANNEL_NUM    4
+
 #define IGP01E1000_PHY_AGC_PARAM_A    0x1171
 #define IGP01E1000_PHY_AGC_PARAM_B    0x1271
 #define IGP01E1000_PHY_AGC_PARAM_C    0x1471
@@ -2060,20 +2572,30 @@ struct e1000_hw {
 #define IGP01E1000_MSE_CHANNEL_B        0x0F00
 #define IGP01E1000_MSE_CHANNEL_A        0xF000
 
+#define IGP02E1000_PM_SPD                         0x0001  /* Smart Power Down */
+#define IGP02E1000_PM_D3_LPLU                     0x0004  /* Enable LPLU in non-D0a modes */
+#define IGP02E1000_PM_D0_LPLU                     0x0002  /* Enable LPLU in D0a mode */
+
 /* IGP01E1000 DSP reset macros */
 #define DSP_RESET_ENABLE     0x0
 #define DSP_RESET_DISABLE    0x2
 #define E1000_MAX_DSP_RESETS 10
 
-/* IGP01E1000 AGC Registers */
+/* IGP01E1000 & IGP02E1000 AGC Registers */
 
 #define IGP01E1000_AGC_LENGTH_SHIFT 7         /* Coarse - 13:11, Fine - 10:7 */
+#define IGP02E1000_AGC_LENGTH_SHIFT 9         /* Coarse - 15:13, Fine - 12:9 */
+
+/* IGP02E1000 AGC Register Length 9-bit mask */
+#define IGP02E1000_AGC_LENGTH_MASK  0x7F
 
 /* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
 #define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
+#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128
 
-/* The precision of the length is +/- 10 meters */
+/* The precision error of the cable length is +/- 10 meters */
 #define IGP01E1000_AGC_RANGE    10
+#define IGP02E1000_AGC_RANGE    10
 
 /* IGP01E1000 PCS Initialization register */
 /* bits 3:6 in the PCS registers stores the channels polarity */
@@ -2113,6 +2635,8 @@ struct e1000_hw {
 #define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
 #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
 #define M88E1011_I_REV_4   0x04
+#define M88E1111_I_PHY_ID  0x01410CC0
+#define L1LXT971A_PHY_ID   0x001378E0
 
 /* Miscellaneous PHY bit definitions. */
 #define PHY_PREAMBLE        0xFFFFFFFF
index 82549a6fcfb39500bf1a4ccd1d0cafc378e8d002..325495b8b60c62db8a8db095c8deda706d84d627 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   This program is free software; you can redistribute it and/or modify it 
   under the terms of the GNU General Public License as published by the Free 
 #include "e1000.h"
 
 /* Change Log
- * 5.3.12      6/7/04
- * - kcompat NETIF_MSG for older kernels (2.4.9) <sean.p.mcdermott@intel.com>
- * - if_mii support and associated kcompat for older kernels
- * - More errlogging support from Jon Mason <jonmason@us.ibm.com>
- * - Fix TSO issues on PPC64 machines -- Jon Mason <jonmason@us.ibm.com>
- *
- * 5.7.1       12/16/04
- * - Resurrect 82547EI/GI related fix in e1000_intr to avoid deadlocks. This
- *   fix was removed as it caused system instability. The suspected cause of 
- *   this is the called to e1000_irq_disable in e1000_intr. Inlined the 
- *   required piece of e1000_irq_disable into e1000_intr - Anton Blanchard
- * 5.7.0       12/10/04
- * - include fix to the condition that determines when to quit NAPI - Robert Olsson
- * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down
- * 5.6.5       11/01/04
- * - Enabling NETIF_F_SG without checksum offload is illegal - 
-     John Mason <jdmason@us.ibm.com>
- * 5.6.3        10/26/04
- * - Remove redundant initialization - Jamal Hadi
- * - Reset buffer_info->dma in tx resource cleanup logic
- * 5.6.2       10/12/04
- * - Avoid filling tx_ring completely - shemminger@osdl.org
- * - Replace schedule_timeout() with msleep()/msleep_interruptible() -
- *   nacc@us.ibm.com
- * - Sparse cleanup - shemminger@osdl.org
- * - Fix tx resource cleanup logic
- * - LLTX support - ak@suse.de and hadi@cyberus.ca
+ * 6.0.44+     2/15/05
+ *   o applied Anton's patch to resolve tx hang in hardware
+ *   o Applied Andrew Mortons patch - e1000 stops working after resume
  */
 
 char e1000_driver_name[] = "e1000";
@@ -65,7 +41,7 @@ char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION "5.7.6-k2"DRIVERNAPI
+#define DRV_VERSION "6.0.54-k2"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
 char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
 
@@ -96,6 +72,7 @@ static struct pci_device_id e1000_pci_tbl[] = {
        INTEL_E1000_ETHERNET_DEVICE(0x1017),
        INTEL_E1000_ETHERNET_DEVICE(0x1018),
        INTEL_E1000_ETHERNET_DEVICE(0x1019),
+       INTEL_E1000_ETHERNET_DEVICE(0x101A),
        INTEL_E1000_ETHERNET_DEVICE(0x101D),
        INTEL_E1000_ETHERNET_DEVICE(0x101E),
        INTEL_E1000_ETHERNET_DEVICE(0x1026),
@@ -110,6 +87,9 @@ static struct pci_device_id e1000_pci_tbl[] = {
        INTEL_E1000_ETHERNET_DEVICE(0x107B),
        INTEL_E1000_ETHERNET_DEVICE(0x107C),
        INTEL_E1000_ETHERNET_DEVICE(0x108A),
+       INTEL_E1000_ETHERNET_DEVICE(0x108B),
+       INTEL_E1000_ETHERNET_DEVICE(0x108C),
+       INTEL_E1000_ETHERNET_DEVICE(0x1099),
        /* required last entry */
        {0,}
 };
@@ -155,10 +135,14 @@ static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
 static int e1000_clean(struct net_device *netdev, int *budget);
 static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
                                     int *work_done, int work_to_do);
+static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+                                       int *work_done, int work_to_do);
 #else
 static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter);
+static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter);
 #endif
 static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
+static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter);
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
 static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
                           int cmd);
@@ -286,7 +270,29 @@ e1000_irq_enable(struct e1000_adapter *adapter)
                E1000_WRITE_FLUSH(&adapter->hw);
        }
 }
-
+void
+e1000_update_mng_vlan(struct e1000_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       uint16_t vid = adapter->hw.mng_cookie.vlan_id;
+       uint16_t old_vid = adapter->mng_vlan_id;
+       if(adapter->vlgrp) {
+               if(!adapter->vlgrp->vlan_devices[vid]) {
+                       if(adapter->hw.mng_cookie.status &
+                               E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
+                               e1000_vlan_rx_add_vid(netdev, vid);
+                               adapter->mng_vlan_id = vid;
+                       } else
+                               adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
+                               
+                       if((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) &&
+                                       (vid != old_vid) && 
+                                       !adapter->vlgrp->vlan_devices[old_vid])
+                               e1000_vlan_rx_kill_vid(netdev, old_vid);
+               }
+       }
+}
+       
 int
 e1000_up(struct e1000_adapter *adapter)
 {
@@ -310,19 +316,33 @@ e1000_up(struct e1000_adapter *adapter)
        e1000_configure_tx(adapter);
        e1000_setup_rctl(adapter);
        e1000_configure_rx(adapter);
-       e1000_alloc_rx_buffers(adapter);
+       adapter->alloc_rx_buf(adapter);
 
+#ifdef CONFIG_PCI_MSI
+       if(adapter->hw.mac_type > e1000_82547_rev_2) {
+               adapter->have_msi = TRUE;
+               if((err = pci_enable_msi(adapter->pdev))) {
+                       DPRINTK(PROBE, ERR,
+                        "Unable to allocate MSI interrupt Error: %d\n", err);
+                       adapter->have_msi = FALSE;
+               }
+       }
+#endif
        if((err = request_irq(adapter->pdev->irq, &e1000_intr,
                              SA_SHIRQ | SA_SAMPLE_RANDOM,
-                             netdev->name, netdev)))
+                             netdev->name, netdev))) {
+               DPRINTK(PROBE, ERR,
+                   "Unable to allocate interrupt Error: %d\n", err);
                return err;
+       }
 
        mod_timer(&adapter->watchdog_timer, jiffies);
-       e1000_irq_enable(adapter);
 
 #ifdef CONFIG_E1000_NAPI
        netif_poll_enable(netdev);
 #endif
+       e1000_irq_enable(adapter);
+
        return 0;
 }
 
@@ -333,6 +353,11 @@ e1000_down(struct e1000_adapter *adapter)
 
        e1000_irq_disable(adapter);
        free_irq(adapter->pdev->irq, netdev);
+#ifdef CONFIG_PCI_MSI
+       if(adapter->hw.mac_type > e1000_82547_rev_2 &&
+          adapter->have_msi == TRUE)
+               pci_disable_msi(adapter->pdev);
+#endif
        del_timer_sync(&adapter->tx_fifo_stall_timer);
        del_timer_sync(&adapter->watchdog_timer);
        del_timer_sync(&adapter->phy_info_timer);
@@ -350,62 +375,93 @@ e1000_down(struct e1000_adapter *adapter)
        e1000_clean_rx_ring(adapter);
 
        /* If WoL is not enabled
+        * and management mode is not IAMT
         * Power down the PHY so no link is implied when interface is down */
-       if(!adapter->wol && adapter->hw.media_type == e1000_media_type_copper) {
+       if(!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
+          adapter->hw.media_type == e1000_media_type_copper &&
+          !e1000_check_mng_mode(&adapter->hw) &&
+          !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN)) {
                uint16_t mii_reg;
                e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
                mii_reg |= MII_CR_POWER_DOWN;
                e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
+               mdelay(1);
        }
 }
 
 void
 e1000_reset(struct e1000_adapter *adapter)
 {
-       uint32_t pba;
+       struct net_device *netdev = adapter->netdev;
+       uint32_t pba, manc;
+       uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
+       uint16_t fc_low_water_mark = E1000_FC_LOW_DIFF;
 
        /* Repartition Pba for greater than 9k mtu
         * To take effect CTRL.RST is required.
         */
 
-       if(adapter->hw.mac_type < e1000_82547) {
-               if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
-                       pba = E1000_PBA_40K;
-               else
-                       pba = E1000_PBA_48K;
-       } else {
-               if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
-                       pba = E1000_PBA_22K;
-               else
-                       pba = E1000_PBA_30K;
+       switch (adapter->hw.mac_type) {
+       case e1000_82547:
+       case e1000_82547_rev_2:
+               pba = E1000_PBA_30K;
+               break;
+       case e1000_82573:
+               pba = E1000_PBA_12K;
+               break;
+       default:
+               pba = E1000_PBA_48K;
+               break;
+       }
+
+       if((adapter->hw.mac_type != e1000_82573) &&
+          (adapter->rx_buffer_len > E1000_RXBUFFER_8192)) {
+               pba -= 8; /* allocate more FIFO for Tx */
+               /* send an XOFF when there is enough space in the
+                * Rx FIFO to hold one extra full size Rx packet 
+               */
+               fc_high_water_mark = netdev->mtu + ENET_HEADER_SIZE + 
+                                       ETHERNET_FCS_SIZE + 1;
+               fc_low_water_mark = fc_high_water_mark + 8;
+       }
+
+
+       if(adapter->hw.mac_type == e1000_82547) {
                adapter->tx_fifo_head = 0;
                adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
                adapter->tx_fifo_size =
                        (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
                atomic_set(&adapter->tx_fifo_stall, 0);
        }
+
        E1000_WRITE_REG(&adapter->hw, PBA, pba);
 
        /* flow control settings */
        adapter->hw.fc_high_water = (pba << E1000_PBA_BYTES_SHIFT) -
-                                   E1000_FC_HIGH_DIFF;
+                                   fc_high_water_mark;
        adapter->hw.fc_low_water = (pba << E1000_PBA_BYTES_SHIFT) -
-                                  E1000_FC_LOW_DIFF;
+                                  fc_low_water_mark;
        adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
        adapter->hw.fc_send_xon = 1;
        adapter->hw.fc = adapter->hw.original_fc;
 
+       /* Allow time for pending master requests to run */
        e1000_reset_hw(&adapter->hw);
        if(adapter->hw.mac_type >= e1000_82544)
                E1000_WRITE_REG(&adapter->hw, WUC, 0);
        if(e1000_init_hw(&adapter->hw))
                DPRINTK(PROBE, ERR, "Hardware Error\n");
-
+       e1000_update_mng_vlan(adapter);
        /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
        E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE);
 
        e1000_reset_adaptive(&adapter->hw);
        e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
+       if (adapter->en_mng_pt) {
+               manc = E1000_READ_REG(&adapter->hw, MANC);
+               manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
+               E1000_WRITE_REG(&adapter->hw, MANC, manc);
+       }
 }
 
 /**
@@ -426,15 +482,13 @@ e1000_probe(struct pci_dev *pdev,
 {
        struct net_device *netdev;
        struct e1000_adapter *adapter;
+       unsigned long mmio_start, mmio_len;
+       uint32_t swsm;
+
        static int cards_found = 0;
-       unsigned long mmio_start;
-       int mmio_len;
-       int pci_using_dac;
-       int i;
-       int err;
+       int i, err, pci_using_dac;
        uint16_t eeprom_data;
        uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
-
        if((err = pci_enable_device(pdev)))
                return err;
 
@@ -521,6 +575,9 @@ e1000_probe(struct pci_dev *pdev,
        if((err = e1000_sw_init(adapter)))
                goto err_sw_init;
 
+       if((err = e1000_check_phy_reset_block(&adapter->hw)))
+               DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
+
        if(adapter->hw.mac_type >= e1000_82543) {
                netdev->features = NETIF_F_SG |
                                   NETIF_F_HW_CSUM |
@@ -533,6 +590,11 @@ e1000_probe(struct pci_dev *pdev,
        if((adapter->hw.mac_type >= e1000_82544) &&
           (adapter->hw.mac_type != e1000_82547))
                netdev->features |= NETIF_F_TSO;
+
+#ifdef NETIF_F_TSO_IPV6
+       if(adapter->hw.mac_type > e1000_82547_rev_2)
+               netdev->features |= NETIF_F_TSO_IPV6;
+#endif
 #endif
        if(pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
@@ -540,6 +602,8 @@ e1000_probe(struct pci_dev *pdev,
        /* hard_start_xmit is safe against parallel locking */
        netdev->features |= NETIF_F_LLTX; 
  
+       adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
+
        /* before reading the EEPROM, reset the controller to 
         * put the device in a known good starting state */
        
@@ -555,7 +619,7 @@ e1000_probe(struct pci_dev *pdev,
 
        /* copy the MAC address out of the EEPROM */
 
-       if (e1000_read_mac_addr(&adapter->hw))
+       if(e1000_read_mac_addr(&adapter->hw))
                DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
        memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
 
@@ -629,6 +693,17 @@ e1000_probe(struct pci_dev *pdev,
        /* reset the hardware with the new settings */
        e1000_reset(adapter);
 
+       /* Let firmware know the driver has taken over */
+       switch(adapter->hw.mac_type) {
+       case e1000_82573:
+               swsm = E1000_READ_REG(&adapter->hw, SWSM);
+               E1000_WRITE_REG(&adapter->hw, SWSM,
+                               swsm | E1000_SWSM_DRV_LOAD);
+               break;
+       default:
+               break;
+       }
+
        strcpy(netdev->name, "eth%d");
        if((err = register_netdev(netdev)))
                goto err_register;
@@ -664,7 +739,7 @@ e1000_remove(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev->priv;
-       uint32_t manc;
+       uint32_t manc, swsm;
 
        flush_scheduled_work();
 
@@ -677,9 +752,21 @@ e1000_remove(struct pci_dev *pdev)
                }
        }
 
+       switch(adapter->hw.mac_type) {
+       case e1000_82573:
+               swsm = E1000_READ_REG(&adapter->hw, SWSM);
+               E1000_WRITE_REG(&adapter->hw, SWSM,
+                               swsm & ~E1000_SWSM_DRV_LOAD);
+               break;
+
+       default:
+               break;
+       }
+
        unregister_netdev(netdev);
 
-       e1000_phy_hw_reset(&adapter->hw);
+       if(!e1000_check_phy_reset_block(&adapter->hw))
+               e1000_phy_hw_reset(&adapter->hw);
 
        iounmap(adapter->hw.hw_addr);
        pci_release_regions(pdev);
@@ -717,6 +804,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
        pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
 
        adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+       adapter->rx_ps_bsize0 = E1000_RXBUFFER_256;
        hw->max_frame_size = netdev->mtu +
                             ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
        hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
@@ -730,7 +818,10 @@ e1000_sw_init(struct e1000_adapter *adapter)
 
        /* initialize eeprom parameters */
 
-       e1000_init_eeprom_params(hw);
+       if(e1000_init_eeprom_params(hw)) {
+               E1000_ERR("EEPROM initialization failed\n");
+               return -EIO;
+       }
 
        switch(hw->mac_type) {
        default:
@@ -795,6 +886,11 @@ e1000_open(struct net_device *netdev)
 
        if((err = e1000_up(adapter)))
                goto err_up;
+       adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
+       if((adapter->hw.mng_cookie.status &
+                         E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
+               e1000_update_mng_vlan(adapter);
+       }
 
        return E1000_SUCCESS;
 
@@ -830,14 +926,18 @@ e1000_close(struct net_device *netdev)
        e1000_free_tx_resources(adapter);
        e1000_free_rx_resources(adapter);
 
+       if((adapter->hw.mng_cookie.status &
+                         E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
+               e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+       }
        return 0;
 }
 
 /**
  * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
  * @adapter: address of board private structure
- * @begin: address of beginning of memory
- * @end: address of end of memory
+ * @start: address of beginning of memory
+ * @len: length of memory
  **/
 static inline boolean_t
 e1000_check_64k_bound(struct e1000_adapter *adapter,
@@ -846,12 +946,10 @@ e1000_check_64k_bound(struct e1000_adapter *adapter,
        unsigned long begin = (unsigned long) start;
        unsigned long end = begin + len;
 
-       /* first rev 82545 and 82546 need to not allow any memory
-        * write location to cross 64k boundary due to errata 23 */
+       /* First rev 82545 and 82546 need to not allow any memory
+        * write location to cross 64k boundary due to errata 23 */
        if (adapter->hw.mac_type == e1000_82545 ||
-           adapter->hw.mac_type == e1000_82546 ) {
-
-               /* check buffer doesn't cross 64kB */
+           adapter->hw.mac_type == e1000_82546) {
                return ((begin ^ (end - 1)) >> 16) != 0 ? FALSE : TRUE;
        }
 
@@ -875,8 +973,8 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter)
        size = sizeof(struct e1000_buffer) * txdr->count;
        txdr->buffer_info = vmalloc(size);
        if(!txdr->buffer_info) {
-               DPRINTK(PROBE, ERR, 
-               "Unable to Allocate Memory for the Transmit descriptor ring\n");
+               DPRINTK(PROBE, ERR,
+               "Unable to allocate memory for the transmit descriptor ring\n");
                return -ENOMEM;
        }
        memset(txdr->buffer_info, 0, size);
@@ -889,38 +987,38 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter)
        txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
        if(!txdr->desc) {
 setup_tx_desc_die:
-               DPRINTK(PROBE, ERR, 
-               "Unable to Allocate Memory for the Transmit descriptor ring\n");
                vfree(txdr->buffer_info);
+               DPRINTK(PROBE, ERR,
+               "Unable to allocate memory for the transmit descriptor ring\n");
                return -ENOMEM;
        }
 
-       /* fix for errata 23, cant cross 64kB boundary */
+       /* Fix for errata 23, can't cross 64kB boundary */
        if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
                void *olddesc = txdr->desc;
                dma_addr_t olddma = txdr->dma;
-               DPRINTK(TX_ERR,ERR,"txdr align check failed: %u bytes at %p\n",
-                       txdr->size, txdr->desc);
-               /* try again, without freeing the previous */
+               DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
+                                    "at %p\n", txdr->size, txdr->desc);
+               /* Try again, without freeing the previous */
                txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
-               /* failed allocation, critial failure */
                if(!txdr->desc) {
+               /* Failed allocation, critical failure */
                        pci_free_consistent(pdev, txdr->size, olddesc, olddma);
                        goto setup_tx_desc_die;
                }
 
                if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
                        /* give up */
-                       pci_free_consistent(pdev, txdr->size,
-                            txdr->desc, txdr->dma);
+                       pci_free_consistent(pdev, txdr->size, txdr->desc,
+                                           txdr->dma);
                        pci_free_consistent(pdev, txdr->size, olddesc, olddma);
                        DPRINTK(PROBE, ERR,
-                        "Unable to Allocate aligned Memory for the Transmit"
-                        " descriptor ring\n");
+                               "Unable to allocate aligned memory "
+                               "for the transmit descriptor ring\n");
                        vfree(txdr->buffer_info);
                        return -ENOMEM;
                } else {
-                       /* free old, move on with the new one since its okay */
+                       /* Free old allocation, new allocation was successful */
                        pci_free_consistent(pdev, txdr->size, olddesc, olddma);
                }
        }
@@ -1022,59 +1120,88 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter)
 {
        struct e1000_desc_ring *rxdr = &adapter->rx_ring;
        struct pci_dev *pdev = adapter->pdev;
-       int size;
+       int size, desc_len;
 
        size = sizeof(struct e1000_buffer) * rxdr->count;
        rxdr->buffer_info = vmalloc(size);
        if(!rxdr->buffer_info) {
-               DPRINTK(PROBE, ERR, 
-               "Unable to Allocate Memory for the Recieve descriptor ring\n");
+               DPRINTK(PROBE, ERR,
+               "Unable to allocate memory for the receive descriptor ring\n");
                return -ENOMEM;
        }
        memset(rxdr->buffer_info, 0, size);
 
+       size = sizeof(struct e1000_ps_page) * rxdr->count;
+       rxdr->ps_page = kmalloc(size, GFP_KERNEL);
+       if(!rxdr->ps_page) {
+               vfree(rxdr->buffer_info);
+               DPRINTK(PROBE, ERR,
+               "Unable to allocate memory for the receive descriptor ring\n");
+               return -ENOMEM;
+       }
+       memset(rxdr->ps_page, 0, size);
+
+       size = sizeof(struct e1000_ps_page_dma) * rxdr->count;
+       rxdr->ps_page_dma = kmalloc(size, GFP_KERNEL);
+       if(!rxdr->ps_page_dma) {
+               vfree(rxdr->buffer_info);
+               kfree(rxdr->ps_page);
+               DPRINTK(PROBE, ERR,
+               "Unable to allocate memory for the receive descriptor ring\n");
+               return -ENOMEM;
+       }
+       memset(rxdr->ps_page_dma, 0, size);
+
+       if(adapter->hw.mac_type <= e1000_82547_rev_2)
+               desc_len = sizeof(struct e1000_rx_desc);
+       else
+               desc_len = sizeof(union e1000_rx_desc_packet_split);
+
        /* Round up to nearest 4K */
 
-       rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);
+       rxdr->size = rxdr->count * desc_len;
        E1000_ROUNDUP(rxdr->size, 4096);
 
        rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
 
        if(!rxdr->desc) {
 setup_rx_desc_die:
-               DPRINTK(PROBE, ERR, 
-               "Unble to Allocate Memory for the Recieve descriptor ring\n");
                vfree(rxdr->buffer_info);
+               kfree(rxdr->ps_page);
+               kfree(rxdr->ps_page_dma);
+               DPRINTK(PROBE, ERR,
+               "Unable to allocate memory for the receive descriptor ring\n");
                return -ENOMEM;
        }
 
-       /* fix for errata 23, cant cross 64kB boundary */
+       /* Fix for errata 23, can't cross 64kB boundary */
        if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
                void *olddesc = rxdr->desc;
                dma_addr_t olddma = rxdr->dma;
-               DPRINTK(RX_ERR,ERR,
-                       "rxdr align check failed: %u bytes at %p\n",
-                       rxdr->size, rxdr->desc);
-               /* try again, without freeing the previous */
+               DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
+                                    "at %p\n", rxdr->size, rxdr->desc);
+               /* Try again, without freeing the previous */
                rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
-               /* failed allocation, critial failure */
                if(!rxdr->desc) {
+               /* Failed allocation, critical failure */
                        pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
                        goto setup_rx_desc_die;
                }
 
                if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
                        /* give up */
-                       pci_free_consistent(pdev, rxdr->size,
-                            rxdr->desc, rxdr->dma);
+                       pci_free_consistent(pdev, rxdr->size, rxdr->desc,
+                                           rxdr->dma);
                        pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
-                       DPRINTK(PROBE, ERR, 
-                               "Unable to Allocate aligned Memory for the"
-                               " Receive descriptor ring\n");
+                       DPRINTK(PROBE, ERR,
+                               "Unable to allocate aligned memory "
+                               "for the receive descriptor ring\n");
                        vfree(rxdr->buffer_info);
+                       kfree(rxdr->ps_page);
+                       kfree(rxdr->ps_page_dma);
                        return -ENOMEM;
                } else {
-                       /* free old, move on with the new one since its okay */
+                       /* Free old allocation, new allocation was successful */
                        pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
                }
        }
@@ -1087,14 +1214,15 @@ setup_rx_desc_die:
 }
 
 /**
- * e1000_setup_rctl - configure the receive control register
+ * e1000_setup_rctl - configure the receive control registers
  * @adapter: Board private structure
  **/
 
 static void
 e1000_setup_rctl(struct e1000_adapter *adapter)
 {
-       uint32_t rctl;
+       uint32_t rctl, rfctl;
+       uint32_t psrctl = 0;
 
        rctl = E1000_READ_REG(&adapter->hw, RCTL);
 
@@ -1109,24 +1237,69 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
        else
                rctl &= ~E1000_RCTL_SBP;
 
+       if (adapter->netdev->mtu <= ETH_DATA_LEN)
+               rctl &= ~E1000_RCTL_LPE;
+       else
+               rctl |= E1000_RCTL_LPE;
+
        /* Setup buffer sizes */
-       rctl &= ~(E1000_RCTL_SZ_4096);
-       rctl |= (E1000_RCTL_BSEX | E1000_RCTL_LPE);
-       switch (adapter->rx_buffer_len) {
-       case E1000_RXBUFFER_2048:
-       default:
-               rctl |= E1000_RCTL_SZ_2048;
-               rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE);
-               break;
-       case E1000_RXBUFFER_4096:
-               rctl |= E1000_RCTL_SZ_4096;
-               break;
-       case E1000_RXBUFFER_8192:
-               rctl |= E1000_RCTL_SZ_8192;
-               break;
-       case E1000_RXBUFFER_16384:
-               rctl |= E1000_RCTL_SZ_16384;
-               break;
+       if(adapter->hw.mac_type == e1000_82573) {
+               /* We can now specify buffers in 1K increments.
+                * BSIZE and BSEX are ignored in this case. */
+               rctl |= adapter->rx_buffer_len << 0x11;
+       } else {
+               rctl &= ~E1000_RCTL_SZ_4096;
+               rctl |= E1000_RCTL_BSEX; 
+               switch (adapter->rx_buffer_len) {
+               case E1000_RXBUFFER_2048:
+               default:
+                       rctl |= E1000_RCTL_SZ_2048;
+                       rctl &= ~E1000_RCTL_BSEX;
+                       break;
+               case E1000_RXBUFFER_4096:
+                       rctl |= E1000_RCTL_SZ_4096;
+                       break;
+               case E1000_RXBUFFER_8192:
+                       rctl |= E1000_RCTL_SZ_8192;
+                       break;
+               case E1000_RXBUFFER_16384:
+                       rctl |= E1000_RCTL_SZ_16384;
+                       break;
+               }
+       }
+
+#ifdef CONFIG_E1000_PACKET_SPLIT
+       /* 82571 and greater support packet-split where the protocol
+        * header is placed in skb->data and the packet data is
+        * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
+        * In the case of a non-split, skb->data is linearly filled,
+        * followed by the page buffers.  Therefore, skb->data is
+        * sized to hold the largest protocol header.
+        */
+       adapter->rx_ps = (adapter->hw.mac_type > e1000_82547_rev_2) 
+                         && (adapter->netdev->mtu 
+                             < ((3 * PAGE_SIZE) + adapter->rx_ps_bsize0));
+#endif
+       if(adapter->rx_ps) {
+               /* Configure extra packet-split registers */
+               rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
+               rfctl |= E1000_RFCTL_EXTEN;
+               /* disable IPv6 packet split support */
+               rfctl |= E1000_RFCTL_IPV6_DIS;
+               E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl);
+
+               rctl |= E1000_RCTL_DTYP_PS | E1000_RCTL_SECRC;
+               
+               psrctl |= adapter->rx_ps_bsize0 >>
+                       E1000_PSRCTL_BSIZE0_SHIFT;
+               psrctl |= PAGE_SIZE >>
+                       E1000_PSRCTL_BSIZE1_SHIFT;
+               psrctl |= PAGE_SIZE <<
+                       E1000_PSRCTL_BSIZE2_SHIFT;
+               psrctl |= PAGE_SIZE <<
+                       E1000_PSRCTL_BSIZE3_SHIFT;
+
+               E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
        }
 
        E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
@@ -1143,9 +1316,18 @@ static void
 e1000_configure_rx(struct e1000_adapter *adapter)
 {
        uint64_t rdba = adapter->rx_ring.dma;
-       uint32_t rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc);
-       uint32_t rctl;
-       uint32_t rxcsum;
+       uint32_t rdlen, rctl, rxcsum;
+
+       if(adapter->rx_ps) {
+               rdlen = adapter->rx_ring.count *
+                       sizeof(union e1000_rx_desc_packet_split);
+               adapter->clean_rx = e1000_clean_rx_irq_ps;
+               adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
+       } else {
+               rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc);
+               adapter->clean_rx = e1000_clean_rx_irq;
+               adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
+       }
 
        /* disable receives while setting up the descriptors */
        rctl = E1000_READ_REG(&adapter->hw, RCTL);
@@ -1172,13 +1354,27 @@ e1000_configure_rx(struct e1000_adapter *adapter)
        E1000_WRITE_REG(&adapter->hw, RDT, 0);
 
        /* Enable 82543 Receive Checksum Offload for TCP and UDP */
-       if((adapter->hw.mac_type >= e1000_82543) &&
-          (adapter->rx_csum == TRUE)) {
+       if(adapter->hw.mac_type >= e1000_82543) {
                rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM);
-               rxcsum |= E1000_RXCSUM_TUOFL;
+               if(adapter->rx_csum == TRUE) {
+                       rxcsum |= E1000_RXCSUM_TUOFL;
+
+                       /* Enable 82573 IPv4 payload checksum for UDP fragments
+                        * Must be used in conjunction with packet-split. */
+                       if((adapter->hw.mac_type > e1000_82547_rev_2) && 
+                          (adapter->rx_ps)) {
+                               rxcsum |= E1000_RXCSUM_IPPCSE;
+                       }
+               } else {
+                       rxcsum &= ~E1000_RXCSUM_TUOFL;
+                       /* don't need to clear IPPCSE as it defaults to 0 */
+               }
                E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum);
        }
 
+       if (adapter->hw.mac_type == e1000_82573)
+               E1000_WRITE_REG(&adapter->hw, ERT, 0x0100);
+
        /* Enable Receives */
        E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
 }
@@ -1210,13 +1406,11 @@ static inline void
 e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
                        struct e1000_buffer *buffer_info)
 {
-       struct pci_dev *pdev = adapter->pdev;
-
        if(buffer_info->dma) {
-               pci_unmap_page(pdev,
-                              buffer_info->dma,
-                              buffer_info->length,
-                              PCI_DMA_TODEVICE);
+               pci_unmap_page(adapter->pdev,
+                               buffer_info->dma,
+                               buffer_info->length,
+                               PCI_DMA_TODEVICE);
                buffer_info->dma = 0;
        }
        if(buffer_info->skb) {
@@ -1241,7 +1435,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter)
        /* Free all the Tx ring sk_buffs */
 
        if (likely(adapter->previous_buffer_info.skb != NULL)) {
-               e1000_unmap_and_free_tx_resource(adapter, 
+               e1000_unmap_and_free_tx_resource(adapter,
                                &adapter->previous_buffer_info);
        }
 
@@ -1281,6 +1475,10 @@ e1000_free_rx_resources(struct e1000_adapter *adapter)
 
        vfree(rx_ring->buffer_info);
        rx_ring->buffer_info = NULL;
+       kfree(rx_ring->ps_page);
+       rx_ring->ps_page = NULL;
+       kfree(rx_ring->ps_page_dma);
+       rx_ring->ps_page_dma = NULL;
 
        pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
 
@@ -1297,16 +1495,19 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter)
 {
        struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
        struct e1000_buffer *buffer_info;
+       struct e1000_ps_page *ps_page;
+       struct e1000_ps_page_dma *ps_page_dma;
        struct pci_dev *pdev = adapter->pdev;
        unsigned long size;
-       unsigned int i;
+       unsigned int i, j;
 
        /* Free all the Rx ring sk_buffs */
 
        for(i = 0; i < rx_ring->count; i++) {
                buffer_info = &rx_ring->buffer_info[i];
                if(buffer_info->skb) {
-
+                       ps_page = &rx_ring->ps_page[i];
+                       ps_page_dma = &rx_ring->ps_page_dma[i];
                        pci_unmap_single(pdev,
                                         buffer_info->dma,
                                         buffer_info->length,
@@ -1314,11 +1515,25 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter)
 
                        dev_kfree_skb(buffer_info->skb);
                        buffer_info->skb = NULL;
+
+                       for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+                               if(!ps_page->ps_page[j]) break;
+                               pci_unmap_single(pdev,
+                                                ps_page_dma->ps_page_dma[j],
+                                                PAGE_SIZE, PCI_DMA_FROMDEVICE);
+                               ps_page_dma->ps_page_dma[j] = 0;
+                               put_page(ps_page->ps_page[j]);
+                               ps_page->ps_page[j] = NULL;
+                       }
                }
        }
 
        size = sizeof(struct e1000_buffer) * rx_ring->count;
        memset(rx_ring->buffer_info, 0, size);
+       size = sizeof(struct e1000_ps_page) * rx_ring->count;
+       memset(rx_ring->ps_page, 0, size);
+       size = sizeof(struct e1000_ps_page_dma) * rx_ring->count;
+       memset(rx_ring->ps_page_dma, 0, size);
 
        /* Zero out the descriptor ring */
 
@@ -1422,15 +1637,15 @@ e1000_set_multi(struct net_device *netdev)
        struct e1000_adapter *adapter = netdev->priv;
        struct e1000_hw *hw = &adapter->hw;
        struct dev_mc_list *mc_ptr;
+       unsigned long flags;
        uint32_t rctl;
        uint32_t hash_value;
        int i;
-       unsigned long flags;
-
-       /* Check for Promiscuous and All Multicast modes */
 
        spin_lock_irqsave(&adapter->tx_lock, flags);
 
+       /* Check for Promiscuous and All Multicast modes */
+
        rctl = E1000_READ_REG(hw, RCTL);
 
        if(netdev->flags & IFF_PROMISC) {
@@ -1556,6 +1771,11 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
        uint32_t link;
 
        e1000_check_for_link(&adapter->hw);
+       if (adapter->hw.mac_type == e1000_82573) {
+               e1000_enable_tx_pkt_filtering(&adapter->hw);
+               if(adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)
+                       e1000_update_mng_vlan(adapter);
+       }       
 
        if((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
           !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE))
@@ -1632,7 +1852,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
        /* Cause software interrupt to ensure rx ring is cleaned */
        E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
 
-       /* Force detection of hung controller every watchdog period*/
+       /* Force detection of hung controller every watchdog period */
        adapter->detect_tx_hung = TRUE;
 
        /* Reset the timer */
@@ -1642,6 +1862,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter)
 #define E1000_TX_FLAGS_CSUM            0x00000001
 #define E1000_TX_FLAGS_VLAN            0x00000002
 #define E1000_TX_FLAGS_TSO             0x00000004
+#define E1000_TX_FLAGS_IPV4            0x00000008
 #define E1000_TX_FLAGS_VLAN_MASK       0xffff0000
 #define E1000_TX_FLAGS_VLAN_SHIFT      16
 
@@ -1652,7 +1873,7 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
        struct e1000_context_desc *context_desc;
        unsigned int i;
        uint32_t cmd_length = 0;
-       uint16_t ipcse, tucse, mss;
+       uint16_t ipcse = 0, tucse, mss;
        uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
        int err;
 
@@ -1665,23 +1886,37 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
 
                hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
                mss = skb_shinfo(skb)->tso_size;
-               skb->nh.iph->tot_len = 0;
-               skb->nh.iph->check = 0;
-               skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
-                                                     skb->nh.iph->daddr,
-                                                     0,
-                                                     IPPROTO_TCP,
-                                                     0);
+               if(skb->protocol == ntohs(ETH_P_IP)) {
+                       skb->nh.iph->tot_len = 0;
+                       skb->nh.iph->check = 0;
+                       skb->h.th->check =
+                               ~csum_tcpudp_magic(skb->nh.iph->saddr,
+                                                  skb->nh.iph->daddr,
+                                                  0,
+                                                  IPPROTO_TCP,
+                                                  0);
+                       cmd_length = E1000_TXD_CMD_IP;
+                       ipcse = skb->h.raw - skb->data - 1;
+#ifdef NETIF_F_TSO_IPV6
+               } else if(skb->protocol == ntohs(ETH_P_IPV6)) {
+                       skb->nh.ipv6h->payload_len = 0;
+                       skb->h.th->check =
+                               ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+                                                &skb->nh.ipv6h->daddr,
+                                                0,
+                                                IPPROTO_TCP,
+                                                0);
+                       ipcse = 0;
+#endif
+               }
                ipcss = skb->nh.raw - skb->data;
                ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data;
-               ipcse = skb->h.raw - skb->data - 1;
                tucss = skb->h.raw - skb->data;
                tucso = (void *)&(skb->h.th->check) - (void *)skb->data;
                tucse = 0;
 
                cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
-                              E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP |
-                              (skb->len - (hdr_len)));
+                              E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
 
                i = adapter->tx_ring.next_to_use;
                context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
@@ -1760,6 +1995,15 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
                if(unlikely(mss && !nr_frags && size == len && size > 8))
                        size -= 4;
 #endif
+               /* work-around for errata 10 and it applies
+                * to all controllers in PCI-X mode
+                * The fix is to make sure that the first descriptor of a
+                * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
+                */
+               if(unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
+                               (size > 2015) && count == 0))
+                       size = 2015;
+                                                                                
                /* Workaround for potential 82544 hang in PCI-X.  Avoid
                 * terminating buffers within evenly-aligned dwords. */
                if(unlikely(adapter->pcix_82544 &&
@@ -1840,7 +2084,10 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
        if(likely(tx_flags & E1000_TX_FLAGS_TSO)) {
                txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
                             E1000_TXD_CMD_TSE;
-               txd_upper |= (E1000_TXD_POPTS_IXSM | E1000_TXD_POPTS_TXSM) << 8;
+               txd_upper |= E1000_TXD_POPTS_TXSM << 8;
+
+               if(likely(tx_flags & E1000_TX_FLAGS_IPV4))
+                       txd_upper |= E1000_TXD_POPTS_IXSM << 8;
        }
 
        if(likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
@@ -1915,6 +2162,53 @@ no_fifo_stall_required:
        return 0;
 }
 
+#define MINIMUM_DHCP_PACKET_SIZE 282
+static inline int
+e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
+{
+       struct e1000_hw *hw =  &adapter->hw;
+       uint16_t length, offset;
+       if(vlan_tx_tag_present(skb)) {
+               if(!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
+                       ( adapter->hw.mng_cookie.status &
+                         E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
+                       return 0;
+       }
+       if(htons(ETH_P_IP) == skb->protocol) {
+               const struct iphdr *ip = skb->nh.iph;
+               if(IPPROTO_UDP == ip->protocol) {
+                       struct udphdr *udp = (struct udphdr *)(skb->h.uh);
+                       if(ntohs(udp->dest) == 67) {
+                               offset = (uint8_t *)udp + 8 - skb->data;
+                               length = skb->len - offset;
+
+                               return e1000_mng_write_dhcp_info(hw,
+                                               (uint8_t *)udp + 8, length);
+                       }
+               }
+       } else if((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
+               struct ethhdr *eth = (struct ethhdr *) skb->data;
+               if((htons(ETH_P_IP) == eth->h_proto)) {
+                       const struct iphdr *ip = 
+                               (struct iphdr *)((uint8_t *)skb->data+14);
+                       if(IPPROTO_UDP == ip->protocol) {
+                               struct udphdr *udp = 
+                                       (struct udphdr *)((uint8_t *)ip + 
+                                               (ip->ihl << 2));
+                               if(ntohs(udp->dest) == 67) {
+                                       offset = (uint8_t *)udp + 8 - skb->data;
+                                       length = skb->len - offset;
+
+                                       return e1000_mng_write_dhcp_info(hw,
+                                                       (uint8_t *)udp + 8, 
+                                                       length);
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
 #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
 static int
 e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
@@ -1939,7 +2233,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
 #ifdef NETIF_F_TSO
        mss = skb_shinfo(skb)->tso_size;
-       /* The controller does a simple calculation to
+       /* The controller does a simple calculation to 
         * make sure there is enough room in the FIFO before
         * initiating the DMA for each buffer.  The calc is:
         * 4 = ceil(buffer len/mss).  To make sure we don't
@@ -1952,7 +2246,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        if((mss) || (skb->ip_summed == CHECKSUM_HW))
                count++;
-       count++;        /* for sentinel desc */
+       count++;
 #else
        if(skb->ip_summed == CHECKSUM_HW)
                count++;
@@ -1962,6 +2256,13 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        if(adapter->pcix_82544)
                count++;
 
+       /* work-around for errata 10 and it applies to all controllers 
+        * in PCI-X mode, so add one more descriptor to the count
+        */
+       if(unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
+                       (len > 2015)))
+               count++;
+
        nr_frags = skb_shinfo(skb)->nr_frags;
        for(f = 0; f < nr_frags; f++)
                count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
@@ -1975,6 +2276,9 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                local_irq_restore(flags); 
                return NETDEV_TX_LOCKED; 
        } 
+       if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
+               e1000_transfer_dhcp_info(adapter, skb);
+
 
        /* need: count + 2 desc gap to keep tail from touching
         * head, otherwise try next time */
@@ -2011,6 +2315,12 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        else if(likely(e1000_tx_csum(adapter, skb)))
                tx_flags |= E1000_TX_FLAGS_CSUM;
 
+       /* Old method was to assume IPv4 packet by default if TSO was enabled.
+        * 82573 hardware supports TSO capabilities for IPv6 as well...
+        * no longer assume, we must. */
+       if(likely(skb->protocol == ntohs(ETH_P_IP)))
+               tx_flags |= E1000_TX_FLAGS_IPV4;
+
        e1000_tx_queue(adapter,
                e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss),
                tx_flags);
@@ -2077,7 +2387,6 @@ static int
 e1000_change_mtu(struct net_device *netdev, int new_mtu)
 {
        struct e1000_adapter *adapter = netdev->priv;
-       int old_mtu = adapter->rx_buffer_len;
        int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
 
        if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
@@ -2086,29 +2395,45 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
                        return -EINVAL;
        }
 
-       if(max_frame <= MAXIMUM_ETHERNET_FRAME_SIZE) {
-               adapter->rx_buffer_len = E1000_RXBUFFER_2048;
-
-       } else if(adapter->hw.mac_type < e1000_82543) {
-               DPRINTK(PROBE, ERR, "Jumbo Frames not supported on 82542\n");
+#define MAX_STD_JUMBO_FRAME_SIZE 9216
+       /* might want this to be bigger enum check... */
+       if (adapter->hw.mac_type == e1000_82573 &&
+           max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
+               DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
+                                   "on 82573\n");
                return -EINVAL;
+       }
 
-       } else if(max_frame <= E1000_RXBUFFER_4096) {
-               adapter->rx_buffer_len = E1000_RXBUFFER_4096;
-
-       } else if(max_frame <= E1000_RXBUFFER_8192) {
-               adapter->rx_buffer_len = E1000_RXBUFFER_8192;
-
+       if(adapter->hw.mac_type > e1000_82547_rev_2) {
+               adapter->rx_buffer_len = max_frame;
+               E1000_ROUNDUP(adapter->rx_buffer_len, 1024);
        } else {
-               adapter->rx_buffer_len = E1000_RXBUFFER_16384;
+               if(unlikely((adapter->hw.mac_type < e1000_82543) &&
+                  (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) {
+                       DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
+                                           "on 82542\n");
+                       return -EINVAL;
+
+               } else {
+                       if(max_frame <= E1000_RXBUFFER_2048) {
+                               adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+                       } else if(max_frame <= E1000_RXBUFFER_4096) {
+                               adapter->rx_buffer_len = E1000_RXBUFFER_4096;
+                       } else if(max_frame <= E1000_RXBUFFER_8192) {
+                               adapter->rx_buffer_len = E1000_RXBUFFER_8192;
+                       } else if(max_frame <= E1000_RXBUFFER_16384) {
+                               adapter->rx_buffer_len = E1000_RXBUFFER_16384;
+                       }
+               }
        }
 
-       if(old_mtu != adapter->rx_buffer_len && netif_running(netdev)) {
+       netdev->mtu = new_mtu;
+
+       if(netif_running(netdev)) {
                e1000_down(adapter);
                e1000_up(adapter);
        }
 
-       netdev->mtu = new_mtu;
        adapter->hw.max_frame_size = max_frame;
 
        return 0;
@@ -2199,6 +2524,17 @@ e1000_update_stats(struct e1000_adapter *adapter)
                adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC);
                adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC);
        }
+       if(hw->mac_type > e1000_82547_rev_2) {
+               adapter->stats.iac += E1000_READ_REG(hw, IAC);
+               adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC);
+               adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC);
+               adapter->stats.icrxatc += E1000_READ_REG(hw, ICRXATC);
+               adapter->stats.ictxptc += E1000_READ_REG(hw, ICTXPTC);
+               adapter->stats.ictxatc += E1000_READ_REG(hw, ICTXATC);
+               adapter->stats.ictxqec += E1000_READ_REG(hw, ICTXQEC);
+               adapter->stats.ictxqmtc += E1000_READ_REG(hw, ICTXQMTC);
+               adapter->stats.icrxdmtc += E1000_READ_REG(hw, ICRXDMTC);
+       }
 
        /* Fill out the OS statistics structure */
 
@@ -2213,9 +2549,9 @@ e1000_update_stats(struct e1000_adapter *adapter)
 
        adapter->net_stats.rx_errors = adapter->stats.rxerrc +
                adapter->stats.crcerrs + adapter->stats.algnerrc +
-               adapter->stats.rlec + adapter->stats.rnbc +
-               adapter->stats.mpc + adapter->stats.cexterr;
-       adapter->net_stats.rx_dropped = adapter->stats.rnbc;
+               adapter->stats.rlec + adapter->stats.mpc + 
+               adapter->stats.cexterr;
+       adapter->net_stats.rx_dropped = adapter->stats.mpc;
        adapter->net_stats.rx_length_errors = adapter->stats.rlec;
        adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
        adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
@@ -2300,11 +2636,11 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
        */
        if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2){
                atomic_inc(&adapter->irq_sem);
-               E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+               E1000_WRITE_REG(hw, IMC, ~0);
        }
 
        for(i = 0; i < E1000_MAX_INTR; i++)
-               if(unlikely(!e1000_clean_rx_irq(adapter) &
+               if(unlikely(!adapter->clean_rx(adapter) &
                   !e1000_clean_tx_irq(adapter)))
                        break;
 
@@ -2328,16 +2664,15 @@ e1000_clean(struct net_device *netdev, int *budget)
        int work_to_do = min(*budget, netdev->quota);
        int tx_cleaned;
        int work_done = 0;
-       
+
        tx_cleaned = e1000_clean_tx_irq(adapter);
-       e1000_clean_rx_irq(adapter, &work_done, work_to_do);
+       adapter->clean_rx(adapter, &work_done, work_to_do);
 
        *budget -= work_done;
        netdev->quota -= work_done;
        
-       /* if no Tx and not enough Rx work done, exit the polling mode */
-       if((!tx_cleaned && (work_done < work_to_do)) || 
-                               !netif_running(netdev)) {
+       /* If no Tx and no Rx work done, exit the polling mode */
+       if ((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
                netif_rx_complete(netdev);
                e1000_irq_enable(adapter);
                return 0;
@@ -2367,11 +2702,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
        eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
        while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-               /* pre-mature writeback of Tx descriptors     */
-               /* clear (free buffers and unmap pci_mapping) */
-               /* previous_buffer_info                       */
+               /* Premature writeback of Tx descriptors clear (free buffers
+                * and unmap pci_mapping) previous_buffer_info */
                if (likely(adapter->previous_buffer_info.skb != NULL)) {
-                       e1000_unmap_and_free_tx_resource(adapter, 
+                       e1000_unmap_and_free_tx_resource(adapter,
                                        &adapter->previous_buffer_info);
                }
 
@@ -2380,26 +2714,30 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
                        buffer_info = &tx_ring->buffer_info[i];
                        cleaned = (i == eop);
 
-                       /* pre-mature writeback of Tx descriptors */
-                       /* save the cleaning of the this for the  */
-                       /* next iteration                         */
-                       if (cleaned) {
-                               memcpy(&adapter->previous_buffer_info,
-                                       buffer_info,
-                                       sizeof(struct e1000_buffer));
-                               memset(buffer_info,
-                                       0,
-                                       sizeof(struct e1000_buffer));
+#ifdef NETIF_F_TSO
+                       if (!(netdev->features & NETIF_F_TSO)) {
+#endif
+                               e1000_unmap_and_free_tx_resource(adapter,
+                                                                buffer_info);
+#ifdef NETIF_F_TSO
                        } else {
-                               e1000_unmap_and_free_tx_resource(adapter, 
-                                                       buffer_info);
+                               if (cleaned) {
+                                       memcpy(&adapter->previous_buffer_info,
+                                              buffer_info,
+                                              sizeof(struct e1000_buffer));
+                                       memset(buffer_info, 0,
+                                              sizeof(struct e1000_buffer));
+                               } else {
+                                       e1000_unmap_and_free_tx_resource(
+                                           adapter, buffer_info);
+                               }
                        }
+#endif
 
                        tx_desc->buffer_addr = 0;
                        tx_desc->lower.data = 0;
                        tx_desc->upper.data = 0;
 
-                       cleaned = (i == eop);
                        if(unlikely(++i == tx_ring->count)) i = 0;
                }
                
@@ -2416,57 +2754,107 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
                netif_wake_queue(netdev);
 
        spin_unlock(&adapter->tx_lock);
        if(adapter->detect_tx_hung) {
-               /* detect a transmit hang in hardware, this serializes the
+
+               /* Detect a transmit hang in hardware, this serializes the
                 * check with the clearing of time_stamp and movement of i */
                adapter->detect_tx_hung = FALSE;
-               if(tx_ring->buffer_info[i].dma &&
-                  time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) &&
-                  !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
+               if (tx_ring->buffer_info[i].dma &&
+                   time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ)
+                   && !(E1000_READ_REG(&adapter->hw, STATUS) &
+                       E1000_STATUS_TXOFF)) {
+
+                       /* detected Tx unit hang */
+                       i = tx_ring->next_to_clean;
+                       eop = tx_ring->buffer_info[i].next_to_watch;
+                       eop_desc = E1000_TX_DESC(*tx_ring, eop);
+                       DPRINTK(TX_ERR, ERR, "Detected Tx Unit Hang\n"
+                                       "  TDH                  <%x>\n"
+                                       "  TDT                  <%x>\n"
+                                       "  next_to_use          <%x>\n"
+                                       "  next_to_clean        <%x>\n"
+                                       "buffer_info[next_to_clean]\n"
+                                       "  dma                  <%llx>\n"
+                                       "  time_stamp           <%lx>\n"
+                                       "  next_to_watch        <%x>\n"
+                                       "  jiffies              <%lx>\n"
+                                       "  next_to_watch.status <%x>\n",
+                               E1000_READ_REG(&adapter->hw, TDH),
+                               E1000_READ_REG(&adapter->hw, TDT),
+                               tx_ring->next_to_use,
+                               i,
+                               tx_ring->buffer_info[i].dma,
+                               tx_ring->buffer_info[i].time_stamp,
+                               eop,
+                               jiffies,
+                               eop_desc->upper.fields.status);
                        netif_stop_queue(netdev);
+               }
        }
+#ifdef NETIF_F_TSO
+
+       if( unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+           time_after(jiffies, adapter->previous_buffer_info.time_stamp + HZ)))
+               e1000_unmap_and_free_tx_resource(
+                   adapter, &adapter->previous_buffer_info);
 
+#endif
        return cleaned;
 }
 
 /**
  * e1000_rx_checksum - Receive Checksum Offload for 82543
- * @adapter: board private structure
- * @rx_desc: receive descriptor
- * @sk_buff: socket buffer with received data
+ * @adapter:     board private structure
+ * @status_err:  receive descriptor status and error fields
+ * @csum:        receive descriptor csum field
+ * @sk_buff:     socket buffer with received data
  **/
 
 static inline void
 e1000_rx_checksum(struct e1000_adapter *adapter,
-                  struct e1000_rx_desc *rx_desc,
-                  struct sk_buff *skb)
+                 uint32_t status_err, uint32_t csum,
+                 struct sk_buff *skb)
 {
+       uint16_t status = (uint16_t)status_err;
+       uint8_t errors = (uint8_t)(status_err >> 24);
+       skb->ip_summed = CHECKSUM_NONE;
+
        /* 82543 or newer only */
-       if(unlikely((adapter->hw.mac_type < e1000_82543) ||
+       if(unlikely(adapter->hw.mac_type < e1000_82543)) return;
        /* Ignore Checksum bit is set */
-       (rx_desc->status & E1000_RXD_STAT_IXSM) ||
-       /* TCP Checksum has not been calculated */
-       (!(rx_desc->status & E1000_RXD_STAT_TCPCS)))) {
-               skb->ip_summed = CHECKSUM_NONE;
-               return;
-       }
-
-       /* At this point we know the hardware did the TCP checksum */
-       /* now look at the TCP checksum error bit */
-       if(rx_desc->errors & E1000_RXD_ERR_TCPE) {
+       if(unlikely(status & E1000_RXD_STAT_IXSM)) return;
+       /* TCP/UDP checksum error bit is set */
+       if(unlikely(errors & E1000_RXD_ERR_TCPE)) {
                /* let the stack verify checksum errors */
-               skb->ip_summed = CHECKSUM_NONE;
                adapter->hw_csum_err++;
+               return;
+       }
+       /* TCP/UDP Checksum has not been calculated */
+       if(adapter->hw.mac_type <= e1000_82547_rev_2) {
+               if(!(status & E1000_RXD_STAT_TCPCS))
+                       return;
        } else {
+               if(!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
+                       return;
+       }
+       /* It must be a TCP or UDP packet with a valid checksum */
+       if (likely(status & E1000_RXD_STAT_TCPCS)) {
                /* TCP checksum is good */
                skb->ip_summed = CHECKSUM_UNNECESSARY;
-               adapter->hw_csum_good++;
+       } else if (adapter->hw.mac_type > e1000_82547_rev_2) {
+               /* IP fragment with UDP payload */
+               /* Hardware complements the payload checksum, so we undo it
+                * and then put the value in host order for further stack use.
+                */
+               csum = ntohl(csum ^ 0xFFFF);
+               skb->csum = csum;
+               skb->ip_summed = CHECKSUM_HW;
        }
+       adapter->hw_csum_good++;
 }
 
 /**
- * e1000_clean_rx_irq - Send received data up the network stack
+ * e1000_clean_rx_irq - Send received data up the network stack; legacy
  * @adapter: board private structure
  **/
 
@@ -2513,7 +2901,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
                if(unlikely(!(rx_desc->status & E1000_RXD_STAT_EOP))) {
                        /* All receives must fit into a single buffer */
                        E1000_DBG("%s: Receive packet consumed multiple"
-                                       " buffers\n", netdev->name);
+                                 " buffers\n", netdev->name);
                        dev_kfree_skb_irq(skb);
                        goto next_desc;
                }
@@ -2539,15 +2927,17 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
                skb_put(skb, length - ETHERNET_FCS_SIZE);
 
                /* Receive Checksum Offload */
-               e1000_rx_checksum(adapter, rx_desc, skb);
-
+               e1000_rx_checksum(adapter,
+                                 (uint32_t)(rx_desc->status) |
+                                 ((uint32_t)(rx_desc->errors) << 24),
+                                 rx_desc->csum, skb);
                skb->protocol = eth_type_trans(skb, netdev);
 #ifdef CONFIG_E1000_NAPI
                if(unlikely(adapter->vlgrp &&
                            (rx_desc->status & E1000_RXD_STAT_VP))) {
                        vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-                                       le16_to_cpu(rx_desc->special) &
-                                       E1000_RXD_SPC_VLAN_MASK);
+                                                le16_to_cpu(rx_desc->special) &
+                                                E1000_RXD_SPC_VLAN_MASK);
                } else {
                        netif_receive_skb(skb);
                }
@@ -2570,16 +2960,142 @@ next_desc:
 
                rx_desc = E1000_RX_DESC(*rx_ring, i);
        }
-
        rx_ring->next_to_clean = i;
+       adapter->alloc_rx_buf(adapter);
+
+       return cleaned;
+}
+
+/**
+ * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
+ * @adapter: board private structure
+ **/
+
+static boolean_t
+#ifdef CONFIG_E1000_NAPI
+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, int *work_done,
+                      int work_to_do)
+#else
+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
+#endif
+{
+       struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+       union e1000_rx_desc_packet_split *rx_desc;
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev *pdev = adapter->pdev;
+       struct e1000_buffer *buffer_info;
+       struct e1000_ps_page *ps_page;
+       struct e1000_ps_page_dma *ps_page_dma;
+       struct sk_buff *skb;
+       unsigned int i, j;
+       uint32_t length, staterr;
+       boolean_t cleaned = FALSE;
+
+       i = rx_ring->next_to_clean;
+       rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
+       staterr = rx_desc->wb.middle.status_error;
+
+       while(staterr & E1000_RXD_STAT_DD) {
+               buffer_info = &rx_ring->buffer_info[i];
+               ps_page = &rx_ring->ps_page[i];
+               ps_page_dma = &rx_ring->ps_page_dma[i];
+#ifdef CONFIG_E1000_NAPI
+               if(unlikely(*work_done >= work_to_do))
+                       break;
+               (*work_done)++;
+#endif
+               cleaned = TRUE;
+               pci_unmap_single(pdev, buffer_info->dma,
+                                buffer_info->length,
+                                PCI_DMA_FROMDEVICE);
+
+               skb = buffer_info->skb;
+
+               if(unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
+                       E1000_DBG("%s: Packet Split buffers didn't pick up"
+                                 " the full packet\n", netdev->name);
+                       dev_kfree_skb_irq(skb);
+                       goto next_desc;
+               }
+
+               if(unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
+                       dev_kfree_skb_irq(skb);
+                       goto next_desc;
+               }
+
+               length = le16_to_cpu(rx_desc->wb.middle.length0);
+
+               if(unlikely(!length)) {
+                       E1000_DBG("%s: Last part of the packet spanning"
+                                 " multiple descriptors\n", netdev->name);
+                       dev_kfree_skb_irq(skb);
+                       goto next_desc;
+               }
+
+               /* Good Receive */
+               skb_put(skb, length);
+
+               for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+                       if(!(length = le16_to_cpu(rx_desc->wb.upper.length[j])))
+                               break;
+
+                       pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
+                                       PAGE_SIZE, PCI_DMA_FROMDEVICE);
+                       ps_page_dma->ps_page_dma[j] = 0;
+                       skb_shinfo(skb)->frags[j].page =
+                               ps_page->ps_page[j];
+                       ps_page->ps_page[j] = NULL;
+                       skb_shinfo(skb)->frags[j].page_offset = 0;
+                       skb_shinfo(skb)->frags[j].size = length;
+                       skb_shinfo(skb)->nr_frags++;
+                       skb->len += length;
+                       skb->data_len += length;
+               }
 
-       e1000_alloc_rx_buffers(adapter);
+               e1000_rx_checksum(adapter, staterr,
+                                 rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
+               skb->protocol = eth_type_trans(skb, netdev);
+
+#ifdef HAVE_RX_ZERO_COPY
+               if(likely(rx_desc->wb.upper.header_status &
+                         E1000_RXDPS_HDRSTAT_HDRSP))
+                       skb_shinfo(skb)->zero_copy = TRUE;
+#endif
+#ifdef CONFIG_E1000_NAPI
+               if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
+                       vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+                               le16_to_cpu(rx_desc->wb.middle.vlan &
+                                       E1000_RXD_SPC_VLAN_MASK));
+               } else {
+                       netif_receive_skb(skb);
+               }
+#else /* CONFIG_E1000_NAPI */
+               if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
+                       vlan_hwaccel_rx(skb, adapter->vlgrp,
+                               le16_to_cpu(rx_desc->wb.middle.vlan &
+                                       E1000_RXD_SPC_VLAN_MASK));
+               } else {
+                       netif_rx(skb);
+               }
+#endif /* CONFIG_E1000_NAPI */
+               netdev->last_rx = jiffies;
+
+next_desc:
+               rx_desc->wb.middle.status_error &= ~0xFF;
+               buffer_info->skb = NULL;
+               if(unlikely(++i == rx_ring->count)) i = 0;
+
+               rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
+               staterr = rx_desc->wb.middle.status_error;
+       }
+       rx_ring->next_to_clean = i;
+       adapter->alloc_rx_buf(adapter);
 
        return cleaned;
 }
 
 /**
- * e1000_alloc_rx_buffers - Replace used receive buffers
+ * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
  * @adapter: address of board private structure
  **/
 
@@ -2592,43 +3108,43 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
        struct e1000_rx_desc *rx_desc;
        struct e1000_buffer *buffer_info;
        struct sk_buff *skb;
-       unsigned int i, bufsz;
+       unsigned int i;
+       unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
 
        i = rx_ring->next_to_use;
        buffer_info = &rx_ring->buffer_info[i];
 
        while(!buffer_info->skb) {
-               bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
-
                skb = dev_alloc_skb(bufsz);
+
                if(unlikely(!skb)) {
                        /* Better luck next round */
                        break;
                }
 
-               /* fix for errata 23, cant cross 64kB boundary */
+               /* Fix for errata 23, can't cross 64kB boundary */
                if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
                        struct sk_buff *oldskb = skb;
-                       DPRINTK(RX_ERR,ERR,
-                               "skb align check failed: %u bytes at %p\n",
-                               bufsz, skb->data);
-                       /* try again, without freeing the previous */
+                       DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
+                                            "at %p\n", bufsz, skb->data);
+                       /* Try again, without freeing the previous */
                        skb = dev_alloc_skb(bufsz);
+                       /* Failed allocation, critical failure */
                        if (!skb) {
                                dev_kfree_skb(oldskb);
                                break;
                        }
+
                        if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
                                /* give up */
                                dev_kfree_skb(skb);
                                dev_kfree_skb(oldskb);
                                break; /* while !buffer_info->skb */
                        } else {
-                               /* move on with the new one */
+                               /* Use new allocation */
                                dev_kfree_skb(oldskb);
                        }
                }
-
                /* Make buffer alignment 2 beyond a 16 byte boundary
                 * this will result in a 16 byte aligned IP header after
                 * the 14 byte MAC header is removed
@@ -2644,25 +3160,23 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
                                                  adapter->rx_buffer_len,
                                                  PCI_DMA_FROMDEVICE);
 
-               /* fix for errata 23, cant cross 64kB boundary */
-               if(!e1000_check_64k_bound(adapter,
-                                              (void *)(unsigned long)buffer_info->dma,
-                                              adapter->rx_buffer_len)) {
-                       DPRINTK(RX_ERR,ERR,
-                               "dma align check failed: %u bytes at %ld\n",
-                               adapter->rx_buffer_len, (unsigned long)buffer_info->dma);
-
+               /* Fix for errata 23, can't cross 64kB boundary */
+               if (!e1000_check_64k_bound(adapter,
+                                       (void *)(unsigned long)buffer_info->dma,
+                                       adapter->rx_buffer_len)) {
+                       DPRINTK(RX_ERR, ERR,
+                               "dma align check failed: %u bytes at %p\n",
+                               adapter->rx_buffer_len,
+                               (void *)(unsigned long)buffer_info->dma);
                        dev_kfree_skb(skb);
                        buffer_info->skb = NULL;
 
-                       pci_unmap_single(pdev,
-                                        buffer_info->dma,
+                       pci_unmap_single(pdev, buffer_info->dma,
                                         adapter->rx_buffer_len,
                                         PCI_DMA_FROMDEVICE);
 
                        break; /* while !buffer_info->skb */
                }
-
                rx_desc = E1000_RX_DESC(*rx_ring, i);
                rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
 
@@ -2672,7 +3186,6 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
                         * applicable for weak-ordered memory model archs,
                         * such as IA-64). */
                        wmb();
-
                        E1000_WRITE_REG(&adapter->hw, RDT, i);
                }
 
@@ -2683,6 +3196,95 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
        rx_ring->next_to_use = i;
 }
 
+/**
+ * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
+ * @adapter: address of board private structure
+ **/
+
+static void
+e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
+{
+       struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev *pdev = adapter->pdev;
+       union e1000_rx_desc_packet_split *rx_desc;
+       struct e1000_buffer *buffer_info;
+       struct e1000_ps_page *ps_page;
+       struct e1000_ps_page_dma *ps_page_dma;
+       struct sk_buff *skb;
+       unsigned int i, j;
+
+       i = rx_ring->next_to_use;
+       buffer_info = &rx_ring->buffer_info[i];
+       ps_page = &rx_ring->ps_page[i];
+       ps_page_dma = &rx_ring->ps_page_dma[i];
+
+       while(!buffer_info->skb) {
+               rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
+
+               for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+                       if(unlikely(!ps_page->ps_page[j])) {
+                               ps_page->ps_page[j] =
+                                       alloc_page(GFP_ATOMIC);
+                               if(unlikely(!ps_page->ps_page[j]))
+                                       goto no_buffers;
+                               ps_page_dma->ps_page_dma[j] =
+                                       pci_map_page(pdev,
+                                                    ps_page->ps_page[j],
+                                                    0, PAGE_SIZE,
+                                                    PCI_DMA_FROMDEVICE);
+                       }
+                       /* Refresh the desc even if buffer_addrs didn't
+                        * change because each write-back erases this info.
+                        */
+                       rx_desc->read.buffer_addr[j+1] =
+                               cpu_to_le64(ps_page_dma->ps_page_dma[j]);
+               }
+
+               skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
+
+               if(unlikely(!skb))
+                       break;
+
+               /* Make buffer alignment 2 beyond a 16 byte boundary
+                * this will result in a 16 byte aligned IP header after
+                * the 14 byte MAC header is removed
+                */
+               skb_reserve(skb, NET_IP_ALIGN);
+
+               skb->dev = netdev;
+
+               buffer_info->skb = skb;
+               buffer_info->length = adapter->rx_ps_bsize0;
+               buffer_info->dma = pci_map_single(pdev, skb->data,
+                                                 adapter->rx_ps_bsize0,
+                                                 PCI_DMA_FROMDEVICE);
+
+               rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
+
+               if(unlikely((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i)) {
+                       /* Force memory writes to complete before letting h/w
+                        * know there are new descriptors to fetch.  (Only
+                        * applicable for weak-ordered memory model archs,
+                        * such as IA-64). */
+                       wmb();
+                       /* Hardware increments by 16 bytes, but packet split
+                        * descriptors are 32 bytes...so we increment tail
+                        * twice as much.
+                        */
+                       E1000_WRITE_REG(&adapter->hw, RDT, i<<1);
+               }
+
+               if(unlikely(++i == rx_ring->count)) i = 0;
+               buffer_info = &rx_ring->buffer_info[i];
+               ps_page = &rx_ring->ps_page[i];
+               ps_page_dma = &rx_ring->ps_page_dma[i];
+       }
+
+no_buffers:
+       rx_ring->next_to_use = i;
+}
+
 /**
  * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
  * @adapter:
@@ -2856,9 +3458,10 @@ void
 e1000_pci_set_mwi(struct e1000_hw *hw)
 {
        struct e1000_adapter *adapter = hw->back;
+       int ret_val = pci_set_mwi(adapter->pdev);
 
-       int ret;
-       ret = pci_set_mwi(adapter->pdev);
+       if(ret_val)
+               DPRINTK(PROBE, ERR, "Error in setting MWI\n");
 }
 
 void
@@ -2917,6 +3520,7 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
                rctl |= E1000_RCTL_VFE;
                rctl &= ~E1000_RCTL_CFIEN;
                E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+               e1000_update_mng_vlan(adapter);
        } else {
                /* disable VLAN tag insert/strip */
                ctrl = E1000_READ_REG(&adapter->hw, CTRL);
@@ -2927,6 +3531,10 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
                rctl = E1000_READ_REG(&adapter->hw, RCTL);
                rctl &= ~E1000_RCTL_VFE;
                E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+               if(adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) {
+                       e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+                       adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
+               }
        }
 
        e1000_irq_enable(adapter);
@@ -2937,7 +3545,10 @@ e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
 {
        struct e1000_adapter *adapter = netdev->priv;
        uint32_t vfta, index;
-
+       if((adapter->hw.mng_cookie.status &
+               E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+               (vid == adapter->mng_vlan_id))
+               return;
        /* add VID to filter table */
        index = (vid >> 5) & 0x7F;
        vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
@@ -2958,6 +3569,10 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
 
        e1000_irq_enable(adapter);
 
+       if((adapter->hw.mng_cookie.status &
+               E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+               (vid == adapter->mng_vlan_id))
+               return;
        /* remove VID from filter table */
        index = (vid >> 5) & 0x7F;
        vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
@@ -3004,8 +3619,7 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
                break;
        case SPEED_1000 + DUPLEX_HALF: /* not supported */
        default:
-               DPRINTK(PROBE, ERR, 
-                       "Unsupported Speed/Duplexity configuration\n");
+               DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
                return -EINVAL;
        }
        return 0;
@@ -3033,7 +3647,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev->priv;
-       uint32_t ctrl, ctrl_ext, rctl, manc, status;
+       uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm;
        uint32_t wufc = adapter->wol;
 
        netif_device_detach(netdev);
@@ -3075,6 +3689,9 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
                        E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);
                }
 
+               /* Allow time for pending master requests to run */
+               e1000_disable_pciex_master(&adapter->hw);
+
                E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
                E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
                pci_enable_wake(pdev, 3, 1);
@@ -3099,6 +3716,16 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
                }
        }
 
+       switch(adapter->hw.mac_type) {
+       case e1000_82573:
+               swsm = E1000_READ_REG(&adapter->hw, SWSM);
+               E1000_WRITE_REG(&adapter->hw, SWSM,
+                               swsm & ~E1000_SWSM_DRV_LOAD);
+               break;
+       default:
+               break;
+       }
+
        pci_disable_device(pdev);
 
        state = (state > 0) ? 3 : 0;
@@ -3113,13 +3740,12 @@ e1000_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev->priv;
-       uint32_t manc, ret;
+       uint32_t manc, ret, swsm;
 
        pci_set_power_state(pdev, 0);
        pci_restore_state(pdev);
        ret = pci_enable_device(pdev);
-       if (pdev->is_busmaster)
-               pci_set_master(pdev);
+       pci_set_master(pdev);
 
        pci_enable_wake(pdev, 3, 0);
        pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
@@ -3139,10 +3765,19 @@ e1000_resume(struct pci_dev *pdev)
                E1000_WRITE_REG(&adapter->hw, MANC, manc);
        }
 
+       switch(adapter->hw.mac_type) {
+       case e1000_82573:
+               swsm = E1000_READ_REG(&adapter->hw, SWSM);
+               E1000_WRITE_REG(&adapter->hw, SWSM,
+                               swsm | E1000_SWSM_DRV_LOAD);
+               break;
+       default:
+               break;
+       }
+
        return 0;
 }
 #endif
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /*
  * Polling 'interrupt' - used by things like netconsole to send skbs
@@ -3150,7 +3785,7 @@ e1000_resume(struct pci_dev *pdev)
  * the interrupt routine is executing.
  */
 static void
-e1000_netpoll (struct net_device *netdev)
+e1000_netpoll(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev->priv;
        disable_irq(adapter->pdev->irq);
index 970c656a517c196be5eb60258b874224227e3f8c..aac64de6143708b5c7aca85aaeb70a50f33188b4 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   This program is free software; you can redistribute it and/or modify it 
   under the terms of the GNU General Public License as published by the Free 
 #include <linux/sched.h>
 
 #ifndef msec_delay
-#define msec_delay(x) msleep(x)
+#define msec_delay(x)  do { if(in_interrupt()) { \
+                               /* Don't mdelay in interrupt context! */ \
+                               BUG(); \
+                       } else { \
+                               msleep(x); \
+                       } } while(0)
 
 /* Some workarounds require millisecond delays and are run during interrupt
  * context.  Most notably, when establishing link, the phy may need tweaking
@@ -96,6 +101,29 @@ typedef enum {
         (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
         ((offset) << 2)))
 
+#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
+#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
+
+#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) ( \
+    writew((value), ((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        ((offset) << 1))))
+
+#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \
+    readw((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        ((offset) << 1)))
+
+#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \
+    writeb((value), ((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        (offset))))
+
+#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \
+    readb((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        (offset)))
+
 #define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
 
 #endif /* _E1000_OSDEP_H_ */
index e914d09fe6f9364ced28259879dfebfff125d048..676247f9f1cca054967d604547f005d1340b5eee 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   This program is free software; you can redistribute it and/or modify it 
   under the terms of the GNU General Public License as published by the Free 
@@ -478,7 +478,6 @@ e1000_check_options(struct e1000_adapter *adapter)
                                DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", 
                                        opt.name);
                                break;
-                       case -1:
                        default:
                                e1000_validate_option(&adapter->itr, &opt, 
                                        adapter);
index cda48c5d72a91f59fc806f7fb834d73491c60a57..4ebcd052e15093b0c6e59c5880d974cf06f108dc 100644 (file)
@@ -81,6 +81,7 @@
  *                        cause DMA to kfree'd memory.
  *     0.31: 14 Nov 2004: ethtool support for getting/setting link
  *                        capabilities.
+ *     0.32: 16 Apr 2005: RX_ERROR4 handling added.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -92,7 +93,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION              "0.31"
+#define FORCEDETH_VERSION              "0.32"
 #define DRV_NAME                       "forcedeth"
 
 #include <linux/module.h>
 #include <linux/mii.h>
 #include <linux/random.h>
 #include <linux/init.h>
+#include <linux/if_vlan.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -1013,6 +1015,59 @@ static void nv_tx_timeout(struct net_device *dev)
        spin_unlock_irq(&np->lock);
 }
 
+/*
+ * Called when the nic notices a mismatch between the actual data len on the
+ * wire and the len indicated in the 802 header
+ */
+static int nv_getlen(struct net_device *dev, void *packet, int datalen)
+{
+       int hdrlen;     /* length of the 802 header */
+       int protolen;   /* length as stored in the proto field */
+
+       /* 1) calculate len according to header */
+       if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == __constant_htons(ETH_P_8021Q)) {
+               protolen = ntohs( ((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto );
+               hdrlen = VLAN_HLEN;
+       } else {
+               protolen = ntohs( ((struct ethhdr *)packet)->h_proto);
+               hdrlen = ETH_HLEN;
+       }
+       dprintk(KERN_DEBUG "%s: nv_getlen: datalen %d, protolen %d, hdrlen %d\n",
+                               dev->name, datalen, protolen, hdrlen);
+       if (protolen > ETH_DATA_LEN)
+               return datalen; /* Value in proto field not a len, no checks possible */
+
+       protolen += hdrlen;
+       /* consistency checks: */
+       if (datalen > ETH_ZLEN) {
+               if (datalen >= protolen) {
+                       /* more data on wire than in 802 header, trim of
+                        * additional data.
+                        */
+                       dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n",
+                                       dev->name, protolen);
+                       return protolen;
+               } else {
+                       /* less data on wire than mentioned in header.
+                        * Discard the packet.
+                        */
+                       dprintk(KERN_DEBUG "%s: nv_getlen: discarding long packet.\n",
+                                       dev->name);
+                       return -1;
+               }
+       } else {
+               /* short packet. Accept only if 802 values are also short */
+               if (protolen > ETH_ZLEN) {
+                       dprintk(KERN_DEBUG "%s: nv_getlen: discarding short packet.\n",
+                                       dev->name);
+                       return -1;
+               }
+               dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n",
+                               dev->name, datalen);
+               return datalen;
+       }
+}
+
 static void nv_rx_process(struct net_device *dev)
 {
        struct fe_priv *np = get_nvpriv(dev);
@@ -1064,7 +1119,7 @@ static void nv_rx_process(struct net_device *dev)
                                np->stats.rx_errors++;
                                goto next_pkt;
                        }
-                       if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) {
+                       if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {
                                np->stats.rx_errors++;
                                goto next_pkt;
                        }
@@ -1078,22 +1133,24 @@ static void nv_rx_process(struct net_device *dev)
                                np->stats.rx_errors++;
                                goto next_pkt;
                        }
-                       if (Flags & NV_RX_ERROR) {
-                               /* framing errors are soft errors, the rest is fatal. */
-                               if (Flags & NV_RX_FRAMINGERR) {
-                                       if (Flags & NV_RX_SUBSTRACT1) {
-                                               len--;
-                                       }
-                               } else {
+                       if (Flags & NV_RX_ERROR4) {
+                               len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
+                               if (len < 0) {
                                        np->stats.rx_errors++;
                                        goto next_pkt;
                                }
                        }
+                       /* framing errors are soft errors. */
+                       if (Flags & NV_RX_FRAMINGERR) {
+                               if (Flags & NV_RX_SUBSTRACT1) {
+                                       len--;
+                               }
+                       }
                } else {
                        if (!(Flags & NV_RX2_DESCRIPTORVALID))
                                goto next_pkt;
 
-                       if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3|NV_RX2_ERROR4)) {
+                       if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {
                                np->stats.rx_errors++;
                                goto next_pkt;
                        }
@@ -1107,17 +1164,19 @@ static void nv_rx_process(struct net_device *dev)
                                np->stats.rx_errors++;
                                goto next_pkt;
                        }
-                       if (Flags & NV_RX2_ERROR) {
-                               /* framing errors are soft errors, the rest is fatal. */
-                               if (Flags & NV_RX2_FRAMINGERR) {
-                                       if (Flags & NV_RX2_SUBSTRACT1) {
-                                               len--;
-                                       }
-                               } else {
+                       if (Flags & NV_RX2_ERROR4) {
+                               len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
+                               if (len < 0) {
                                        np->stats.rx_errors++;
                                        goto next_pkt;
                                }
                        }
+                       /* framing errors are soft errors */
+                       if (Flags & NV_RX2_FRAMINGERR) {
+                               if (Flags & NV_RX2_SUBSTRACT1) {
+                                       len--;
+                               }
+                       }
                        Flags &= NV_RX2_CHECKSUMMASK;
                        if (Flags == NV_RX2_CHECKSUMOK1 ||
                                        Flags == NV_RX2_CHECKSUMOK2 ||
@@ -1480,6 +1539,13 @@ static void nv_do_nic_poll(unsigned long data)
        enable_irq(dev->irq);
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void nv_poll_controller(struct net_device *dev)
+{
+       nv_do_nic_poll((unsigned long) dev);
+}
+#endif
+
 static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
        struct fe_priv *np = get_nvpriv(dev);
@@ -1962,6 +2028,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        dev->get_stats = nv_get_stats;
        dev->change_mtu = nv_change_mtu;
        dev->set_multicast_list = nv_set_multicast;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = nv_poll_controller;
+#endif
        SET_ETHTOOL_OPS(dev, &ops);
        dev->tx_timeout = nv_tx_timeout;
        dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
index 34068f81d45ef1c2d200ed77b661b7b341118046..7cdebe1a0b6198264f06cbb13020132d41ca40d4 100644 (file)
@@ -45,7 +45,7 @@ config BPQETHER
 
 config DMASCC
        tristate "High-speed (DMA) SCC driver for AX.25"
-       depends on ISA && AX25 && BROKEN_ON_SMP
+       depends on ISA && AX25 && BROKEN_ON_SMP && ISA_DMA_API
        ---help---
          This is a driver for high-speed SCC boards, i.e. those supporting
          DMA on one port. You usually use those boards to connect your
@@ -78,7 +78,7 @@ config DMASCC
 
 config SCC
        tristate "Z8530 SCC driver"
-       depends on ISA && AX25
+       depends on ISA && AX25 && ISA_DMA_API
        ---help---
          These cards are used to connect your Linux box to an amateur radio
          in order to communicate with other computers. If you want to use
index 1c563f905a5964fb094d40ab6626e4b590a6bcb2..a7f15d9f13e5ccd04faa36b6dda826c20e750fbb 100644 (file)
@@ -374,29 +374,6 @@ static inline void do_kiss_params(struct baycom_state *bc,
 }
 
 /* --------------------------------------------------------------------- */
-/*
- * high performance HDLC encoder
- * yes, it's ugly, but generates pretty good code
- */
-
-#define ENCODEITERA(j)                         \
-({                                             \
-        if (!(notbitstream & (0x1f0 << j)))    \
-                goto stuff##j;                 \
-  encodeend##j:        ;                      \
-})
-
-#define ENCODEITERB(j)                                          \
-({                                                              \
-  stuff##j:                                                     \
-        bitstream &= ~(0x100 << j);                             \
-        bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) |        \
-                ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1);  \
-        numbit++;                                               \
-        notbitstream = ~bitstream;                              \
-        goto encodeend##j;                                      \
-})
-
 
 static void encode_hdlc(struct baycom_state *bc)
 {
@@ -405,6 +382,7 @@ static void encode_hdlc(struct baycom_state *bc)
        int pkt_len;
         unsigned bitstream, notbitstream, bitbuf, numbit, crc;
        unsigned char crcarr[2];
+       int j;
        
        if (bc->hdlctx.bufcnt > 0)
                return;
@@ -429,24 +407,14 @@ static void encode_hdlc(struct baycom_state *bc)
                pkt_len--;
                if (!pkt_len)
                        bp = crcarr;
-               ENCODEITERA(0);
-               ENCODEITERA(1);
-               ENCODEITERA(2);
-               ENCODEITERA(3);
-               ENCODEITERA(4);
-               ENCODEITERA(5);
-               ENCODEITERA(6);
-               ENCODEITERA(7);
-               goto enditer;
-               ENCODEITERB(0);
-               ENCODEITERB(1);
-               ENCODEITERB(2);
-               ENCODEITERB(3);
-               ENCODEITERB(4);
-               ENCODEITERB(5);
-               ENCODEITERB(6);
-               ENCODEITERB(7);
-       enditer:
+               for (j = 0; j < 8; j++)
+                       if (unlikely(!(notbitstream & (0x1f0 << j)))) {
+                               bitstream &= ~(0x100 << j);
+                               bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) |
+                                       ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1);
+                               numbit++;
+                               notbitstream = ~bitstream;
+                       }
                numbit += 8;
                while (numbit >= 8) {
                        *wp++ = bitbuf;
@@ -610,37 +578,6 @@ static void do_rxpacket(struct net_device *dev)
        bc->stats.rx_packets++;
 }
 
-#define DECODEITERA(j)                                                        \
-({                                                                            \
-        if (!(notbitstream & (0x0fc << j)))              /* flag or abort */  \
-                goto flgabrt##j;                                              \
-        if ((bitstream & (0x1f8 << j)) == (0xf8 << j))   /* stuffed bit */    \
-                goto stuff##j;                                                \
-  enditer##j:      ;                                                           \
-})
-
-#define DECODEITERB(j)                                                                 \
-({                                                                                     \
-  flgabrt##j:                                                                          \
-        if (!(notbitstream & (0x1fc << j))) {              /* abort received */        \
-                state = 0;                                                             \
-                goto enditer##j;                                                       \
-        }                                                                              \
-        if ((bitstream & (0x1fe << j)) != (0x0fc << j))   /* flag received */          \
-                goto enditer##j;                                                       \
-        if (state)                                                                     \
-                do_rxpacket(dev);                                                      \
-        bc->hdlcrx.bufcnt = 0;                                                         \
-        bc->hdlcrx.bufptr = bc->hdlcrx.buf;                                            \
-        state = 1;                                                                     \
-        numbits = 7-j;                                                                 \
-        goto enditer##j;                                                               \
-  stuff##j:                                                                            \
-        numbits--;                                                                     \
-        bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1);        \
-        goto enditer##j;                                                               \
-})
-        
 static int receive(struct net_device *dev, int cnt)
 {
        struct baycom_state *bc = netdev_priv(dev);
@@ -649,6 +586,7 @@ static int receive(struct net_device *dev, int cnt)
        unsigned char tmp[128];
         unsigned char *cp;
        int cnt2, ret = 0;
+       int j;
         
         numbits = bc->hdlcrx.numbits;
        state = bc->hdlcrx.state;
@@ -669,24 +607,32 @@ static int receive(struct net_device *dev, int cnt)
                        bitbuf |= (*cp) << 8;
                        numbits += 8;
                        notbitstream = ~bitstream;
-                       DECODEITERA(0);
-                       DECODEITERA(1);
-                       DECODEITERA(2);
-                       DECODEITERA(3);
-                       DECODEITERA(4);
-                       DECODEITERA(5);
-                       DECODEITERA(6);
-                       DECODEITERA(7);
-                       goto enddec;
-                       DECODEITERB(0);
-                       DECODEITERB(1);
-                       DECODEITERB(2);
-                       DECODEITERB(3);
-                       DECODEITERB(4);
-                       DECODEITERB(5);
-                       DECODEITERB(6);
-                       DECODEITERB(7);
-               enddec:
+                       for (j = 0; j < 8; j++) {
+
+                               /* flag or abort */
+                               if (unlikely(!(notbitstream & (0x0fc << j)))) {
+
+                                       /* abort received */
+                                       if (!(notbitstream & (0x1fc << j)))
+                                               state = 0;
+
+                                       /* not flag received */
+                                       else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) {
+                                               if (state)
+                                                       do_rxpacket(dev);
+                                               bc->hdlcrx.bufcnt = 0;
+                                               bc->hdlcrx.bufptr = bc->hdlcrx.buf;
+                                               state = 1;
+                                               numbits = 7-j;
+                                               }
+                                       }
+
+                               /* stuffed bit */
+                               else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) {
+                                       numbits--;
+                                       bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1);
+                                       }
+                               }
                        while (state && numbits >= 8) {
                                if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) {
                                        state = 0;
index ab44358ddbfc9a7c2a618a24fe820e8239bdcf32..6482d994d4899aef539f2639bd70703c306d3c90 100644 (file)
@@ -1595,7 +1595,7 @@ static struct ethtool_ops emac_ethtool_ops = {
 static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct ocp_enet_private *fep = dev->priv;
-       uint *data = (uint *) & rq->ifr_ifru;
+       uint16_t *data = (uint16_t *) & rq->ifr_ifru;
 
        switch (cmd) {
        case SIOCGMIIPHY:
index 6bf76a444d483a375dede2ba44b04a952d79ed2b..ca5914091d3afb9550a80b571312700492d85693 100644 (file)
@@ -310,7 +310,7 @@ config SIGMATEL_FIR
 
 config NSC_FIR
        tristate "NSC PC87108/PC87338"
-       depends on IRDA
+       depends on IRDA && ISA_DMA_API
        help
          Say Y here if you want to build support for the NSC PC87108 and
          PC87338 IrDA chipsets.  This driver supports SIR,
@@ -321,7 +321,7 @@ config NSC_FIR
 
 config WINBOND_FIR
        tristate "Winbond W83977AF (IR)"
-       depends on IRDA
+       depends on IRDA && ISA_DMA_API
        help
          Say Y here if you want to build IrDA support for the Winbond
          W83977AF super-io chipset.  This driver should be used for the IrDA
@@ -347,7 +347,7 @@ config AU1000_FIR
 
 config SMC_IRCC_FIR
        tristate "SMSC IrCC (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && IRDA
+       depends on EXPERIMENTAL && IRDA && ISA_DMA_API
        help
          Say Y here if you want to build support for the SMC Infrared
          Communications Controller.  It is used in a wide variety of
@@ -357,7 +357,7 @@ config SMC_IRCC_FIR
 
 config ALI_FIR
        tristate "ALi M5123 FIR (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && IRDA
+       depends on EXPERIMENTAL && IRDA && ISA_DMA_API
        help
          Say Y here if you want to build support for the ALi M5123 FIR
          Controller.  The ALi M5123 FIR Controller is embedded in ALi M1543C,
@@ -385,11 +385,11 @@ config SA1100_FIR
 
 config VIA_FIR
        tristate "VIA VT8231/VT1211 SIR/MIR/FIR"
-       depends on IRDA
+       depends on IRDA && ISA_DMA_API
        help
          Say Y here if you want to build support for the VIA VT8231
          and VIA VT1211 IrDA controllers, found on the motherboards using
-         those those VIA chipsets. To use this controller, you will need
+         those VIA chipsets. To use this controller, you will need
          to plug a specific 5 pins FIR IrDA dongle in the specific
          motherboard connector. The driver provides support for SIR, MIR
          and FIR (4Mbps) speeds.
index 855f8b2cf13b6f83d1b41011253d514b22e5cc2c..55af32e9bf082ad7f8d88b96b2e068eb0e35304f 100644 (file)
@@ -802,13 +802,14 @@ static void veth_tx_timeout(struct net_device *dev)
 
        spin_lock_irqsave(&port->pending_gate, flags);
 
+       if (!port->pending_lpmask) {
+               spin_unlock_irqrestore(&port->pending_gate, flags);
+               return;
+       }
+
        printk(KERN_WARNING "%s: Tx timeout!  Resetting lp connections: %08x\n",
               dev->name, port->pending_lpmask);
 
-       /* If we've timed out the queue must be stopped, which should
-        * only ever happen when there is a pending packet. */
-       WARN_ON(! port->pending_lpmask);
-
        for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
                struct veth_lpar_connection *cnx = veth_cnx[i];
 
@@ -924,7 +925,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
 
        spin_lock_irqsave(&cnx->lock, flags);
 
-       if (! cnx->state & VETH_STATE_READY)
+       if (! (cnx->state & VETH_STATE_READY))
                goto drop;
 
        if ((skb->len - 14) > VETH_MAX_MTU)
@@ -1023,6 +1024,8 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        lpmask = veth_transmit_to_many(skb, lpmask, dev);
 
+       dev->trans_start = jiffies;
+
        if (! lpmask) {
                dev_kfree_skb(skb);
        } else {
@@ -1262,13 +1265,18 @@ static void veth_receive(struct veth_lpar_connection *cnx,
 
                vlan = skb->data[9];
                dev = veth_dev[vlan];
-               if (! dev)
-                       /* Some earlier versions of the driver sent
-                          broadcasts down all connections, even to
-                          lpars that weren't on the relevant vlan.
-                          So ignore packets belonging to a vlan we're
-                          not on. */
+               if (! dev) {
+                       /*
+                        * Some earlier versions of the driver sent
+                        * broadcasts down all connections, even to lpars
+                        * that weren't on the relevant vlan. So ignore
+                        * packets belonging to a vlan we're not on.
+                        * We can also be here if we receive packets while
+                        * the driver is going down, because then dev is NULL.
+                        */
+                       dev_kfree_skb_irq(skb);
                        continue;
+               }
 
                port = (struct veth_port *)dev->priv;
                dest = *((u64 *) skb->data) & 0xFFFFFFFFFFFF0000;
@@ -1381,18 +1389,25 @@ void __exit veth_module_cleanup(void)
 {
        int i;
 
-       vio_unregister_driver(&veth_driver);
+       /* Stop the queues first to stop any new packets being sent. */
+       for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++)
+               if (veth_dev[i])
+                       netif_stop_queue(veth_dev[i]);
 
+       /* Stop the connections before we unregister the driver. This
+        * ensures there's no skbs lying around holding the device open. */
        for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
                veth_stop_connection(i);
 
        HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
 
        /* Hypervisor callbacks may have scheduled more work while we
-        * were destroying connections. Now that we've disconnected from
+        * were stoping connections. Now that we've disconnected from
         * the hypervisor make sure everything's finished. */
        flush_scheduled_work();
 
+       vio_unregister_driver(&veth_driver);
+
        for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
                veth_destroy_connection(i);
 
index 26c4f15f7fc0b329ebc4f875dbf546932ad8b6b5..f8d3385c7842d3fe6f34b6d672da43353ce139a4 100644 (file)
@@ -110,7 +110,7 @@ struct ixgb_adapter;
 #define IXGB_TX_QUEUE_WAKE 16
 
 /* How many Rx Buffers do we bundle into one write to the hardware ? */
-#define IXGB_RX_BUFFER_WRITE   16      /* Must be power of 2 */
+#define IXGB_RX_BUFFER_WRITE         /* Must be power of 2 */
 
 /* only works for sizes that are powers of 2 */
 #define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
index 653e99f919cee638c23be7da3f02dc734b4ea00f..3aae110c55606ced13769acddf7d87c2649d1a4f 100644 (file)
@@ -411,7 +411,7 @@ ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t offset, uint16_t data)
        ixgb_cleanup_eeprom(hw);
 
        /* clear the init_ctrl_reg_1 to signify that the cache is invalidated */
-       ee_map->init_ctrl_reg_1 = EEPROM_ICW1_SIGNATURE_CLEAR;
+       ee_map->init_ctrl_reg_1 = le16_to_cpu(EEPROM_ICW1_SIGNATURE_CLEAR);
 
        return;
 }
@@ -483,7 +483,7 @@ ixgb_get_eeprom_data(struct ixgb_hw *hw)
                DEBUGOUT("ixgb_ee: Checksum invalid.\n");
                /* clear the init_ctrl_reg_1 to signify that the cache is
                 * invalidated */
-               ee_map->init_ctrl_reg_1 = EEPROM_ICW1_SIGNATURE_CLEAR;
+               ee_map->init_ctrl_reg_1 = le16_to_cpu(EEPROM_ICW1_SIGNATURE_CLEAR);
                return (FALSE);
        }
 
@@ -579,7 +579,7 @@ ixgb_get_ee_compatibility(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-               return(ee_map->compatibility);
+               return (le16_to_cpu(ee_map->compatibility));
 
        return(0);
 }
@@ -616,7 +616,7 @@ ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-               return(ee_map->init_ctrl_reg_1);
+               return (le16_to_cpu(ee_map->init_ctrl_reg_1));
 
        return(0);
 }
@@ -635,7 +635,7 @@ ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-               return(ee_map->init_ctrl_reg_2);
+               return (le16_to_cpu(ee_map->init_ctrl_reg_2));
 
        return(0);
 }
@@ -654,7 +654,7 @@ ixgb_get_ee_subsystem_id(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-          return(ee_map->subsystem_id);
+               return (le16_to_cpu(ee_map->subsystem_id));
 
        return(0);
 }
@@ -673,7 +673,7 @@ ixgb_get_ee_subvendor_id(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-               return(ee_map->subvendor_id);
+               return (le16_to_cpu(ee_map->subvendor_id));
 
        return(0);
 }
@@ -692,7 +692,7 @@ ixgb_get_ee_device_id(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-               return(ee_map->device_id);
+               return (le16_to_cpu(ee_map->device_id));
 
        return(0);
 }
@@ -711,7 +711,7 @@ ixgb_get_ee_vendor_id(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-               return(ee_map->vendor_id);
+               return (le16_to_cpu(ee_map->vendor_id));
 
        return(0);
 }
@@ -730,7 +730,7 @@ ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-               return(ee_map->swdpins_reg);
+               return (le16_to_cpu(ee_map->swdpins_reg));
 
        return(0);
 }
@@ -749,7 +749,7 @@ ixgb_get_ee_d3_power(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-               return(ee_map->d3_power);
+               return (le16_to_cpu(ee_map->d3_power));
 
        return(0);
 }
@@ -768,7 +768,7 @@ ixgb_get_ee_d0_power(struct ixgb_hw *hw)
        struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
        if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
-               return(ee_map->d0_power);
+               return (le16_to_cpu(ee_map->d0_power));
 
        return(0);
 }
index aea10e8aaa7220092491cec24691273dd47e2781..3fa113854eebc3d27c8cda25e0d5600a30a48e0e 100644 (file)
@@ -252,7 +252,9 @@ ixgb_get_regs(struct net_device *netdev,
        uint32_t *reg_start = reg;
        uint8_t i;
 
-       regs->version = (adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
+       /* the 1 (one) below indicates an attempt at versioning, if the
+        * interface in ethtool or the driver this 1 should be incremented */
+       regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id;
 
        /* General Registers */
        *reg++ = IXGB_READ_REG(hw, CTRL0);      /*   0 */
index 7d26623d859278bd1ad6369648de9ed41a112493..35f6a7c271a2be3a1f749716cbe27b1bffc66b98 100644 (file)
@@ -47,7 +47,7 @@ char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-char ixgb_driver_version[] = "1.0.90-k2"DRIVERNAPI;
+char ixgb_driver_version[] = "1.0.95-k2"DRIVERNAPI;
 char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
 
 /* ixgb_pci_tbl - PCI Device ID Table
@@ -103,6 +103,7 @@ static int ixgb_change_mtu(struct net_device *netdev, int new_mtu);
 static int ixgb_set_mac(struct net_device *netdev, void *p);
 static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs);
 static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
+
 #ifdef CONFIG_IXGB_NAPI
 static int ixgb_clean(struct net_device *netdev, int *budget);
 static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter,
@@ -120,33 +121,20 @@ static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
 static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
 static void ixgb_restore_vlan(struct ixgb_adapter *adapter);
 
-static int ixgb_notify_reboot(struct notifier_block *, unsigned long event,
-                             void *ptr);
-static int ixgb_suspend(struct pci_dev *pdev, uint32_t state);
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /* for netdump / net console */
 static void ixgb_netpoll(struct net_device *dev);
 #endif
 
-struct notifier_block ixgb_notifier_reboot = {
-       .notifier_call = ixgb_notify_reboot,
-       .next = NULL,
-       .priority = 0
-};
-
 /* Exported from other modules */
 
 extern void ixgb_check_options(struct ixgb_adapter *adapter);
 
 static struct pci_driver ixgb_driver = {
-       .name = ixgb_driver_name,
+       .name     = ixgb_driver_name,
        .id_table = ixgb_pci_tbl,
-       .probe = ixgb_probe,
-       .remove = __devexit_p(ixgb_remove),
-       /* Power Managment Hooks */
-       .suspend = NULL,
-       .resume = NULL
+       .probe    = ixgb_probe,
+       .remove   = __devexit_p(ixgb_remove),
 };
 
 MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
@@ -169,17 +157,12 @@ MODULE_LICENSE("GPL");
 static int __init
 ixgb_init_module(void)
 {
-       int ret;
        printk(KERN_INFO "%s - version %s\n",
               ixgb_driver_string, ixgb_driver_version);
 
        printk(KERN_INFO "%s\n", ixgb_copyright);
 
-       ret = pci_module_init(&ixgb_driver);
-       if(ret >= 0) {
-               register_reboot_notifier(&ixgb_notifier_reboot);
-       }
-       return ret;
+       return pci_module_init(&ixgb_driver);
 }
 
 module_init(ixgb_init_module);
@@ -194,7 +177,6 @@ module_init(ixgb_init_module);
 static void __exit
 ixgb_exit_module(void)
 {
-       unregister_reboot_notifier(&ixgb_notifier_reboot);
        pci_unregister_driver(&ixgb_driver);
 }
 
@@ -224,8 +206,8 @@ ixgb_irq_enable(struct ixgb_adapter *adapter)
 {
        if(atomic_dec_and_test(&adapter->irq_sem)) {
                IXGB_WRITE_REG(&adapter->hw, IMS,
-                          IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
-                          IXGB_INT_RXO | IXGB_INT_LSC);
+                              IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
+                              IXGB_INT_LSC);
                IXGB_WRITE_FLUSH(&adapter->hw);
        }
 }
@@ -1209,10 +1191,10 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
                                                | IXGB_CONTEXT_DESC_CMD_TSE
                                                | IXGB_CONTEXT_DESC_CMD_IP
                                                | IXGB_CONTEXT_DESC_CMD_TCP
-                                               | IXGB_CONTEXT_DESC_CMD_RS
                                                | IXGB_CONTEXT_DESC_CMD_IDE
                                                | (skb->len - (hdr_len)));
 
+
                if(++i == adapter->tx_ring.count) i = 0;
                adapter->tx_ring.next_to_use = i;
 
@@ -1247,8 +1229,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
                context_desc->mss = 0;
                context_desc->cmd_type_len =
                        cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
-                                       | IXGB_TX_DESC_CMD_RS 
-                                       | IXGB_TX_DESC_CMD_IDE);
+                                   | IXGB_TX_DESC_CMD_IDE);
 
                if(++i == adapter->tx_ring.count) i = 0;
                adapter->tx_ring.next_to_use = i;
@@ -1273,6 +1254,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
 
        unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
        unsigned int f;
+
        len -= skb->data_len;
 
        i = tx_ring->next_to_use;
@@ -1526,14 +1508,33 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu)
 void
 ixgb_update_stats(struct ixgb_adapter *adapter)
 {
+       struct net_device *netdev = adapter->netdev;
+
+       if((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) ||
+          (netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES)) {
+               u64 multi = IXGB_READ_REG(&adapter->hw, MPRCL);
+               u32 bcast_l = IXGB_READ_REG(&adapter->hw, BPRCL);
+               u32 bcast_h = IXGB_READ_REG(&adapter->hw, BPRCH);
+               u64 bcast = ((u64)bcast_h << 32) | bcast_l; 
+
+               multi |= ((u64)IXGB_READ_REG(&adapter->hw, MPRCH) << 32);
+               /* fix up multicast stats by removing broadcasts */
+               multi -= bcast;
+               
+               adapter->stats.mprcl += (multi & 0xFFFFFFFF);
+               adapter->stats.mprch += (multi >> 32);
+               adapter->stats.bprcl += bcast_l; 
+               adapter->stats.bprch += bcast_h;
+       } else {
+               adapter->stats.mprcl += IXGB_READ_REG(&adapter->hw, MPRCL);
+               adapter->stats.mprch += IXGB_READ_REG(&adapter->hw, MPRCH);
+               adapter->stats.bprcl += IXGB_READ_REG(&adapter->hw, BPRCL);
+               adapter->stats.bprch += IXGB_READ_REG(&adapter->hw, BPRCH);
+       }
        adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL);
        adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH);
        adapter->stats.gprcl += IXGB_READ_REG(&adapter->hw, GPRCL);
        adapter->stats.gprch += IXGB_READ_REG(&adapter->hw, GPRCH);
-       adapter->stats.bprcl += IXGB_READ_REG(&adapter->hw, BPRCL);
-       adapter->stats.bprch += IXGB_READ_REG(&adapter->hw, BPRCH);
-       adapter->stats.mprcl += IXGB_READ_REG(&adapter->hw, MPRCL);
-       adapter->stats.mprch += IXGB_READ_REG(&adapter->hw, MPRCH);
        adapter->stats.uprcl += IXGB_READ_REG(&adapter->hw, UPRCL);
        adapter->stats.uprch += IXGB_READ_REG(&adapter->hw, UPRCH);
        adapter->stats.vprcl += IXGB_READ_REG(&adapter->hw, VPRCL);
@@ -1823,7 +1824,6 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
        struct pci_dev *pdev = adapter->pdev;
        struct ixgb_rx_desc *rx_desc, *next_rxd;
        struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer;
-       struct sk_buff *skb, *next_skb;
        uint32_t length;
        unsigned int i, j;
        boolean_t cleaned = FALSE;
@@ -1833,6 +1833,8 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
        buffer_info = &rx_ring->buffer_info[i];
 
        while(rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
+               struct sk_buff *skb, *next_skb;
+               u8 status;
 
 #ifdef CONFIG_IXGB_NAPI
                if(*work_done >= work_to_do)
@@ -1840,7 +1842,9 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
 
                (*work_done)++;
 #endif
+               status = rx_desc->status;
                skb = buffer_info->skb;
+
                prefetch(skb->data);
 
                if(++i == rx_ring->count) i = 0;
@@ -1855,7 +1859,6 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
                next_skb = next_buffer->skb;
                prefetch(next_skb);
 
-
                cleaned = TRUE;
 
                pci_unmap_single(pdev,
@@ -1865,7 +1868,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
 
                length = le16_to_cpu(rx_desc->length);
 
-               if(unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) {
+               if(unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) {
 
                        /* All receives must fit into a single buffer */
 
@@ -1873,12 +1876,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
                                         "length<%x>\n", length);
 
                        dev_kfree_skb_irq(skb);
-                       rx_desc->status = 0;
-                       buffer_info->skb = NULL;
-
-                       rx_desc = next_rxd;
-                       buffer_info = next_buffer;
-                       continue;
+                       goto rxdesc_done;
                }
 
                if (unlikely(rx_desc->errors
@@ -1887,12 +1885,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
                                IXGB_RX_DESC_ERRORS_RXE))) {
 
                        dev_kfree_skb_irq(skb);
-                       rx_desc->status = 0;
-                       buffer_info->skb = NULL;
-
-                       rx_desc = next_rxd;
-                       buffer_info = next_buffer;
-                       continue;
+                       goto rxdesc_done;
                }
 
                /* Good Receive */
@@ -1903,7 +1896,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
 
                skb->protocol = eth_type_trans(skb, netdev);
 #ifdef CONFIG_IXGB_NAPI
-               if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
+               if(adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) {
                        vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
                                le16_to_cpu(rx_desc->special) &
                                        IXGB_RX_DESC_SPECIAL_VLAN_MASK);
@@ -1911,7 +1904,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
                        netif_receive_skb(skb);
                }
 #else /* CONFIG_IXGB_NAPI */
-               if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
+               if(adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) {
                        vlan_hwaccel_rx(skb, adapter->vlgrp,
                                le16_to_cpu(rx_desc->special) &
                                        IXGB_RX_DESC_SPECIAL_VLAN_MASK);
@@ -1921,9 +1914,12 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
 #endif /* CONFIG_IXGB_NAPI */
                netdev->last_rx = jiffies;
 
+rxdesc_done:
+               /* clean up descriptor, might be written over by hw */
                rx_desc->status = 0;
                buffer_info->skb = NULL;
 
+               /* use prefetched values */
                rx_desc = next_rxd;
                buffer_info = next_buffer;
        }
@@ -1959,8 +1955,8 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
 
        num_group_tail_writes = IXGB_RX_BUFFER_WRITE;
 
-       /* leave one descriptor unused */
-       while(--cleancount > 0) {
+       /* leave three descriptors unused */
+       while(--cleancount > 2) {
                rx_desc = IXGB_RX_DESC(*rx_ring, i);
 
                skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
@@ -1987,6 +1983,10 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
                                   PCI_DMA_FROMDEVICE);
 
                rx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
+               /* guarantee DD bit not set now before h/w gets descriptor
+                * this is the rest of the workaround for h/w double 
+                * writeback. */
+               rx_desc->status = 0;
 
                if((i & ~(num_group_tail_writes- 1)) == i) {
                        /* Force memory writes to complete before letting h/w
@@ -2099,54 +2099,6 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter)
        }
 }
 
-/**
- * ixgb_notify_reboot - handles OS notification of reboot event.
- * @param nb notifier block, unused
- * @param event Event being passed to driver to act upon
- * @param p A pointer to our net device
- **/
-static int
-ixgb_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
-{
-       struct pci_dev *pdev = NULL;
-
-       switch(event) {
-       case SYS_DOWN:
-       case SYS_HALT:
-       case SYS_POWER_OFF:
-               while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
-                       if (pci_dev_driver(pdev) == &ixgb_driver)
-                               ixgb_suspend(pdev, 3);
-               }
-       }
-       return NOTIFY_DONE;
-}
-
-/**
- * ixgb_suspend - driver suspend function called from notify.
- * @param pdev pci driver structure used for passing to
- * @param state power state to enter 
- **/
-static int
-ixgb_suspend(struct pci_dev *pdev, uint32_t state)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgb_adapter *adapter = netdev->priv;
-
-       netif_device_detach(netdev);
-
-       if(netif_running(netdev))
-               ixgb_down(adapter, TRUE);
-
-       pci_save_state(pdev);
-
-       state = (state > 0) ? 3 : 0;
-       pci_set_power_state(pdev, state);
-       msec_delay(200);
-
-       return 0;
-}
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /*
  * Polling 'interrupt' - used by things like netconsole to send skbs
@@ -2157,6 +2109,7 @@ ixgb_suspend(struct pci_dev *pdev, uint32_t state)
 static void ixgb_netpoll(struct net_device *dev)
 {
        struct ixgb_adapter *adapter = dev->priv;
+
        disable_irq(adapter->pdev->irq);
        ixgb_intr(adapter->pdev->irq, dev, NULL);
        enable_irq(adapter->pdev->irq);
index 9eba9289190183934b7d2475950271b9f4b4cc72..dba20481ee80126e70d0876a5893892ce680ce27 100644 (file)
@@ -45,8 +45,7 @@
                                /* Don't mdelay in interrupt context! */ \
                                BUG(); \
                        } else { \
-                               set_current_state(TASK_UNINTERRUPTIBLE); \
-                               schedule_timeout((x * HZ)/1000 + 2); \
+                               msleep(x); \
                        } } while(0)
 #endif
 
index 2ffc31708d5f43df0ff7c5d8d9e6b2fa13ab5831..b33111e2131310e1d6b891772bcca697b2be2435 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)loopback.c  1.0.4b  08/16/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Donald Becker, <becker@scyld.com>
  *
index 223bdadd4c0d56ccca398fbbbb7d3c7a639b32b6..babb59e146ea62524fc00c50ee1d284502e69c56 100644 (file)
@@ -2433,9 +2433,9 @@ static void __set_rx_mode(struct net_device *dev)
                rx_mode = RxFilterEnable | AcceptBroadcast
                        | AcceptMulticast | AcceptMyPhys;
                for (i = 0; i < 64; i += 2) {
-                       writew(HASH_TABLE + i, ioaddr + RxFilterAddr);
-                       writew((mc_filter[i+1]<<8) + mc_filter[i],
-                               ioaddr + RxFilterData);
+                       writel(HASH_TABLE + i, ioaddr + RxFilterAddr);
+                       writel((mc_filter[i + 1] << 8) + mc_filter[i],
+                              ioaddr + RxFilterData);
                }
        }
        writel(rx_mode, ioaddr + RxFilterAddr);
index 2fcc181a8624c817504b32bd68d523620ccc1128..c336b46bd332676155f01fee160a63b590b30e9b 100644 (file)
@@ -1,4 +1,4 @@
-#define _VERSION "0.20"
+#define VERSION "0.22"
 /* ns83820.c by Benjamin LaHaise with contributions.
  *
  * Questions/comments/discussion to linux-ns83820@kvack.org.
  *                          -  fix missed txok introduced during performance
  *                             tuning
  *                     0.20 -  fix stupid RFEN thinko.  i am such a smurf.
- *
  *     20040828        0.21 -  add hardware vlan accleration
  *                             by Neil Horman <nhorman@redhat.com>
+ *     20050406        0.22 -  improved DAC ifdefs from Andi Kleen     
+ *                          -  removal of dead code from Adrian Bunk
+ *                          -  fix half duplex collision behaviour
  * Driver Overview
  * ===============
  *
@@ -129,18 +131,6 @@ static int lnksts = 0;             /* CFG_LNKSTS bit polarity */
 #undef Dprintk
 #define        Dprintk                 dprintk
 
-#if defined(CONFIG_HIGHMEM64G) || defined(__ia64__)
-#define USE_64BIT_ADDR "+"
-#endif
-
-#if defined(USE_64BIT_ADDR)
-#define        VERSION _VERSION USE_64BIT_ADDR
-#define TRY_DAC        1
-#else
-#define        VERSION _VERSION
-#define TRY_DAC        0
-#endif
-
 /* tunables */
 #define RX_BUF_SIZE    1500    /* 8192 */
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -386,22 +376,16 @@ static int lnksts = 0;            /* CFG_LNKSTS bit polarity */
 #define LINK_DOWN              0x02
 #define LINK_UP                        0x04
 
-#ifdef USE_64BIT_ADDR
-#define HW_ADDR_LEN    8
+#define HW_ADDR_LEN    sizeof(dma_addr_t) 
 #define desc_addr_set(desc, addr)                              \
        do {                                                    \
-               u64 __addr = (addr);                            \
-               (desc)[0] = cpu_to_le32(__addr);                \
-               (desc)[1] = cpu_to_le32(__addr >> 32);          \
+               ((desc)[0] = cpu_to_le32(addr));                \
+               if (HW_ADDR_LEN == 8)                           \
+                       (desc)[1] = cpu_to_le32(((u64)addr) >> 32);     \
        } while(0)
 #define desc_addr_get(desc)                                    \
-               (((u64)le32_to_cpu((desc)[1]) << 32)            \
-                    | le32_to_cpu((desc)[0]))
-#else
-#define HW_ADDR_LEN    4
-#define desc_addr_set(desc, addr)      ((desc)[0] = cpu_to_le32(addr))
-#define desc_addr_get(desc)            (le32_to_cpu((desc)[0]))
-#endif
+       (le32_to_cpu((desc)[0]) | \
+       (HW_ADDR_LEN == 8 ? ((dma_addr_t)le32_to_cpu((desc)[1]))<<32 : 0))
 
 #define DESC_LINK              0
 #define DESC_BUFPTR            (DESC_LINK + HW_ADDR_LEN/4)
@@ -727,11 +711,23 @@ static void fastcall phy_intr(struct net_device *ndev)
                speed = ((cfg / CFG_SPDSTS0) & 3);
                fullduplex = (cfg & CFG_DUPSTS);
 
-               if (fullduplex)
+               if (fullduplex) {
                        new_cfg |= CFG_SB;
+                       writel(readl(dev->base + TXCFG)
+                                       | TXCFG_CSI | TXCFG_HBI,
+                              dev->base + TXCFG);
+                       writel(readl(dev->base + RXCFG) | RXCFG_RX_FD,
+                              dev->base + RXCFG);
+               } else {
+                       writel(readl(dev->base + TXCFG)
+                                       & ~(TXCFG_CSI | TXCFG_HBI),
+                              dev->base + TXCFG);
+                       writel(readl(dev->base + RXCFG) & ~(RXCFG_RX_FD),
+                              dev->base + RXCFG);
+               }
 
                if ((cfg & CFG_LNKSTS) &&
-                   ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
+                   ((new_cfg ^ dev->CFG_cache) != 0)) {
                        writel(new_cfg, dev->base + CFG);
                        dev->CFG_cache = new_cfg;
                }
@@ -1189,7 +1185,6 @@ again:
 
        for (;;) {
                volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE);
-               u32 residue = 0;
 
                dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len,
                        (unsigned long long)buf);
@@ -1199,17 +1194,11 @@ again:
                desc_addr_set(desc + DESC_BUFPTR, buf);
                desc[DESC_EXTSTS] = cpu_to_le32(extsts);
 
-               cmdsts = ((nr_frags|residue) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0);
+               cmdsts = ((nr_frags) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0);
                cmdsts |= (desc == first_desc) ? 0 : CMDSTS_OWN;
                cmdsts |= len;
                desc[DESC_CMDSTS] = cpu_to_le32(cmdsts);
 
-               if (residue) {
-                       buf += len;
-                       len = residue;
-                       continue;
-               }
-
                if (!nr_frags)
                        break;
 
@@ -1841,7 +1830,8 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
        int using_dac = 0;
 
        /* See if we can set the dma mask early on; failure is fatal. */
-       if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffffULL)) {
+       if (sizeof(dma_addr_t) == 8 && 
+               !pci_set_dma_mask(pci_dev, 0xffffffffffffffffULL)) {
                using_dac = 1;
        } else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) {
                using_dac = 0;
@@ -1972,9 +1962,8 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
        /* When compiled with 64 bit addressing, we must always enable
         * the 64 bit descriptor format.
         */
-#ifdef USE_64BIT_ADDR
-       dev->CFG_cache |= CFG_M64ADDR;
-#endif
+       if (sizeof(dma_addr_t) == 8) 
+               dev->CFG_cache |= CFG_M64ADDR;
        if (using_dac)
                dev->CFG_cache |= CFG_T64ADDR;
 
index 41e517114807052707dad7bace8529f7080ba25a..c6e8b25f968529837ec3987baac52e7f55d73dea 100644 (file)
@@ -1274,6 +1274,9 @@ static int el3_close(struct net_device *dev)
                spin_lock_irqsave(&lp->window_lock, flags);
                update_stats(dev);
                spin_unlock_irqrestore(&lp->window_lock, flags);
+
+               /* force interrupts off */
+               outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
        }
 
        link->open--;
index 17947e6c8793796b78bc809240d480817d3a8a27..13f114876965ba1d26f3bc2c604037d409213fa5 100644 (file)
@@ -22,8 +22,8 @@
  *************************************************************************/
 
 #define DRV_NAME       "pcnet32"
-#define DRV_VERSION    "1.30i"
-#define DRV_RELDATE    "06.28.2004"
+#define DRV_VERSION    "1.30j"
+#define DRV_RELDATE    "29.04.2005"
 #define PFX            DRV_NAME ": "
 
 static const char *version =
@@ -256,6 +256,7 @@ static int homepna[MAX_UNITS];
  *        homepna for selecting HomePNA mode for PCNet/Home 79C978.
  * v1.30h  24 Jun 2004 Don Fry correctly select auto, speed, duplex in bcr32.
  * v1.30i  28 Jun 2004 Don Fry change to use module_param.
+ * v1.30j  29 Apr 2005 Don Fry fix skb/map leak with loopback test.
  */
 
 
@@ -395,6 +396,7 @@ static void pcnet32_led_blink_callback(struct net_device *dev);
 static int pcnet32_get_regs_len(struct net_device *dev);
 static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
        void *ptr);
+static void pcnet32_purge_tx_ring(struct net_device *dev);
 
 enum pci_flags_bit {
     PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
@@ -785,6 +787,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t *data1)
     }
 
 clean_up:
+    pcnet32_purge_tx_ring(dev);
     x = a->read_csr(ioaddr, 15) & 0xFFFF;
     a->write_csr(ioaddr, 15, (x & ~0x0044));   /* reset bits 6 and 2 */
 
index c59507f8a76befe001f1313f55b6780423d1e778..d6d0e43dab65cf55db1e6feedcfac4e0874f7898 100644 (file)
@@ -415,7 +415,7 @@ struct rtl8169_private {
        struct work_struct task;
 };
 
-MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@oss.sgi.com>");
+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_param(rx_copybreak, int, 0);
@@ -1585,8 +1585,8 @@ rtl8169_hw_start(struct net_device *dev)
        RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
        RTL_W8(EarlyTxThres, EarlyTxThld);
 
-       /* For gigabit rtl8169, MTU + header + CRC + VLAN */
-       RTL_W16(RxMaxSize, tp->rx_buf_sz);
+       /* Low hurts. Let's disable the filtering. */
+       RTL_W16(RxMaxSize, 16383);
 
        /* Set Rx Config register */
        i = rtl8169_rx_config |
@@ -2127,6 +2127,11 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
        }
 }
 
+static inline int rtl8169_fragmented_frame(u32 status)
+{
+       return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag);
+}
+
 static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
 {
        u32 opts1 = le32_to_cpu(desc->opts1);
@@ -2177,27 +2182,41 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
 
        while (rx_left > 0) {
                unsigned int entry = cur_rx % NUM_RX_DESC;
+               struct RxDesc *desc = tp->RxDescArray + entry;
                u32 status;
 
                rmb();
-               status = le32_to_cpu(tp->RxDescArray[entry].opts1);
+               status = le32_to_cpu(desc->opts1);
 
                if (status & DescOwn)
                        break;
                if (status & RxRES) {
-                       printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);
+                       printk(KERN_INFO "%s: Rx ERROR. status = %08x\n",
+                              dev->name, status);
                        tp->stats.rx_errors++;
                        if (status & (RxRWT | RxRUNT))
                                tp->stats.rx_length_errors++;
                        if (status & RxCRC)
                                tp->stats.rx_crc_errors++;
+                       rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
                } else {
-                       struct RxDesc *desc = tp->RxDescArray + entry;
                        struct sk_buff *skb = tp->Rx_skbuff[entry];
                        int pkt_size = (status & 0x00001FFF) - 4;
                        void (*pci_action)(struct pci_dev *, dma_addr_t,
                                size_t, int) = pci_dma_sync_single_for_device;
 
+                       /*
+                        * The driver does not support incoming fragmented
+                        * frames. They are seen as a symptom of over-mtu
+                        * sized frames.
+                        */
+                       if (unlikely(rtl8169_fragmented_frame(status))) {
+                               tp->stats.rx_dropped++;
+                               tp->stats.rx_length_errors++;
+                               rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
+                               goto move_on;
+                       }
+
                        rtl8169_rx_csum(skb, desc);
                        
                        pci_dma_sync_single_for_cpu(tp->pci_dev,
@@ -2224,7 +2243,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
                        tp->stats.rx_bytes += pkt_size;
                        tp->stats.rx_packets++;
                }
-               
+move_on:               
                cur_rx++; 
                rx_left--;
        }
index e68cf5fb4920fe70bfbcfb5c43680af523f7e24a..20edeb3457921e5377c68a6e7d69681682fca135 100644 (file)
@@ -100,35 +100,8 @@ static int sh_debug;               /* Debug flag */
 
 #define SHAPER_BANNER  "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n"
 
-/*
- *     Locking
- */
-static int shaper_lock(struct shaper *sh)
-{
-       /*
-        *      Lock in an interrupt must fail
-        */
-       while (test_and_set_bit(0, &sh->locked))
-       {
-               if (!in_interrupt())
-                       sleep_on(&sh->wait_queue);
-               else
-                       return 0;
-                       
-       }
-       return 1;
-}
-
 static void shaper_kick(struct shaper *sh);
 
-static void shaper_unlock(struct shaper *sh)
-{
-       clear_bit(0, &sh->locked);
-       wake_up(&sh->wait_queue);
-       shaper_kick(sh);
-}
-
 /*
  *     Compute clocks on a buffer
  */
@@ -157,17 +130,15 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec)
  *     Throw a frame at a shaper.
  */
   
-static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb)
+
+static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
+       struct shaper *shaper = dev->priv;
        struct sk_buff *ptr;
    
-       /*
-        *      Get ready to work on this shaper. Lock may fail if its
-        *      an interrupt and locked.
-        */
-        
-       if(!shaper_lock(shaper))
-               return -1;
+       if (down_trylock(&shaper->sem))
+               return -1;
+
        ptr=shaper->sendq.prev;
        
        /*
@@ -260,7 +231,8 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb)
                 dev_kfree_skb(ptr);
                 shaper->stats.collisions++;
        }
-       shaper_unlock(shaper);
+       shaper_kick(shaper);
+       up(&shaper->sem);
        return 0;
 }
 
@@ -297,8 +269,13 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb)
  
 static void shaper_timer(unsigned long data)
 {
-       struct shaper *sh=(struct shaper *)data;
-       shaper_kick(sh);
+       struct shaper *shaper = (struct shaper *)data;
+
+       if (!down_trylock(&shaper->sem)) {
+               shaper_kick(shaper);
+               up(&shaper->sem);
+       } else
+               mod_timer(&shaper->timer, jiffies);
 }
 
 /*
@@ -310,19 +287,6 @@ static void shaper_kick(struct shaper *shaper)
 {
        struct sk_buff *skb;
        
-       /*
-        *      Shaper unlock will kick
-        */
-        
-       if (test_and_set_bit(0, &shaper->locked))
-       {
-               if(sh_debug)
-                       printk("Shaper locked.\n");
-               mod_timer(&shaper->timer, jiffies);
-               return;
-       }
-
-               
        /*
         *      Walk the list (may be empty)
         */
@@ -364,8 +328,6 @@ static void shaper_kick(struct shaper *shaper)
         
        if(skb!=NULL)
                mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock);
-
-       clear_bit(0, &shaper->locked);
 }
 
 
@@ -376,14 +338,12 @@ static void shaper_kick(struct shaper *shaper)
 static void shaper_flush(struct shaper *shaper)
 {
        struct sk_buff *skb;
-       if(!shaper_lock(shaper))
-       {
-               printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n");
-               return;
-       }
+
+       down(&shaper->sem);
        while((skb=skb_dequeue(&shaper->sendq))!=NULL)
                dev_kfree_skb(skb);
-       shaper_unlock(shaper);
+       shaper_kick(shaper);
+       up(&shaper->sem);
 }
 
 /*
@@ -426,13 +386,6 @@ static int shaper_close(struct net_device *dev)
  *     ARP and other resolutions and not before.
  */
 
-
-static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct shaper *sh=dev->priv;
-       return shaper_qframe(sh, skb);
-}
-
 static struct net_device_stats *shaper_get_stats(struct net_device *dev)
 {
        struct shaper *sh=dev->priv;
@@ -623,7 +576,6 @@ static void shaper_init_priv(struct net_device *dev)
        init_timer(&sh->timer);
        sh->timer.function=shaper_timer;
        sh->timer.data=(unsigned long)sh;
-       init_waitqueue_head(&sh->wait_queue);
 }
 
 /*
index 3e9d9aab05887dc1a12e45fc27879fd0b3a985cd..3107aed0fb51958b01f7a860adc8d1771159adfc 100644 (file)
@@ -162,6 +162,7 @@ struct sis900_private {
        struct mii_phy * mii;
        struct mii_phy * first_mii; /* record the first mii structure */
        unsigned int cur_phy;
+       struct mii_if_info mii_info;
 
        struct timer_list timer; /* Link status detection timer. */
        u8 autong_complete; /* 1: auto-negotiate complete  */
@@ -203,7 +204,7 @@ static int sis900_open(struct net_device *net_dev);
 static int sis900_mii_probe (struct net_device * net_dev);
 static void sis900_init_rxfilter (struct net_device * net_dev);
 static u16 read_eeprom(long ioaddr, int location);
-static u16 mdio_read(struct net_device *net_dev, int phy_id, int location);
+static int mdio_read(struct net_device *net_dev, int phy_id, int location);
 static void mdio_write(struct net_device *net_dev, int phy_id, int location, int val);
 static void sis900_timer(unsigned long data);
 static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_phy);
@@ -478,7 +479,13 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
                sis_priv->msg_enable = sis900_debug;
        else
                sis_priv->msg_enable = SIS900_DEF_MSG;
-               
+
+       sis_priv->mii_info.dev = net_dev;
+       sis_priv->mii_info.mdio_read = mdio_read;
+       sis_priv->mii_info.mdio_write = mdio_write;
+       sis_priv->mii_info.phy_id_mask = 0x1f;
+       sis_priv->mii_info.reg_num_mask = 0x1f;
+
        /* Get Mac address according to the chip revision */
        pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &(sis_priv->chipset_rev));
        if(netif_msg_probe(sis_priv))
@@ -725,6 +732,8 @@ static u16 sis900_default_phy(struct net_device * net_dev)
                       pci_name(sis_priv->pci_dev), sis_priv->cur_phy);
        }
        
+       sis_priv->mii_info.phy_id = sis_priv->cur_phy;
+
        status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
        status &= (~MII_CNTL_ISOLATE);
 
@@ -852,7 +861,7 @@ static void mdio_reset(long mdio_addr)
  *     Please see SiS7014 or ICS spec
  */
 
-static u16 mdio_read(struct net_device *net_dev, int phy_id, int location)
+static int mdio_read(struct net_device *net_dev, int phy_id, int location)
 {
        long mdio_addr = net_dev->base_addr + mear;
        int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
@@ -1966,10 +1975,47 @@ static void sis900_set_msglevel(struct net_device *net_dev, u32 value)
        sis_priv->msg_enable = value;
 }
 
+static u32 sis900_get_link(struct net_device *net_dev)
+{
+       struct sis900_private *sis_priv = net_dev->priv;
+       return mii_link_ok(&sis_priv->mii_info);
+}
+
+static int sis900_get_settings(struct net_device *net_dev,
+                               struct ethtool_cmd *cmd)
+{
+       struct sis900_private *sis_priv = net_dev->priv;
+       spin_lock_irq(&sis_priv->lock);
+       mii_ethtool_gset(&sis_priv->mii_info, cmd);
+       spin_unlock_irq(&sis_priv->lock);
+       return 0;
+}
+
+static int sis900_set_settings(struct net_device *net_dev,
+                               struct ethtool_cmd *cmd)
+{
+       struct sis900_private *sis_priv = net_dev->priv;
+       int rt;
+       spin_lock_irq(&sis_priv->lock);
+       rt = mii_ethtool_sset(&sis_priv->mii_info, cmd);
+       spin_unlock_irq(&sis_priv->lock);
+       return rt;
+}
+
+static int sis900_nway_reset(struct net_device *net_dev)
+{
+       struct sis900_private *sis_priv = net_dev->priv;
+       return mii_nway_restart(&sis_priv->mii_info);
+}
+
 static struct ethtool_ops sis900_ethtool_ops = {
        .get_drvinfo    = sis900_get_drvinfo,
        .get_msglevel   = sis900_get_msglevel,
        .set_msglevel   = sis900_set_msglevel,
+       .get_link       = sis900_get_link,
+       .get_settings   = sis900_get_settings,
+       .set_settings   = sis900_set_settings,
+       .nway_reset     = sis900_nway_reset,
 };
 
 /**
index 058c70c6f1ac32b5672fea3674dd6950fd03dd62..a0b8848049c9ede346a9160c370d0b1df49c2798 100644 (file)
@@ -7,7 +7,12 @@
  * Copyright (C) 2005 Broadcom Corporation.
  *
  * Firmware is:
- *     Copyright (C) 2000-2003 Broadcom Corporation.
+ *     Derived from proprietary unpublished source code,
+ *     Copyright (C) 2000-2003 Broadcom Corporation.
+ *
+ *     Permission is hereby granted for the distribution of this firmware
+ *     data in hexadecimal or equivalent format, provided this copyright
+ *     notice is accompanying it.
  */
 
 #include <linux/config.h>
@@ -61,8 +66,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.26"
-#define DRV_MODULE_RELDATE     "April 24, 2005"
+#define DRV_MODULE_VERSION     "3.31"
+#define DRV_MODULE_RELDATE     "June 8, 2005"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
 /* number of ETHTOOL_GSTATS u64's */
 #define TG3_NUM_STATS          (sizeof(struct tg3_ethtool_stats)/sizeof(u64))
 
+#define TG3_NUM_TEST           6
+
 static char version[] __devinitdata =
        DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
@@ -206,6 +213,8 @@ static struct pci_device_id tg3_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752M,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753M,
@@ -314,6 +323,17 @@ static struct {
        { "nic_tx_threshold_hit" }
 };
 
+static struct {
+       const char string[ETH_GSTRING_LEN];
+} ethtool_test_keys[TG3_NUM_TEST] = {
+       { "nvram test     (online) " },
+       { "link test      (online) " },
+       { "register test  (offline)" },
+       { "memory test    (offline)" },
+       { "loopback test  (offline)" },
+       { "interrupt test (offline)" },
+};
+
 static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
 {
        if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
@@ -420,7 +440,8 @@ static void tg3_enable_ints(struct tg3 *tp)
 {
        tw32(TG3PCI_MISC_HOST_CTRL,
             (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
-       tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000);
+       tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+                    (tp->last_tag << 24));
        tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
 
        tg3_cond_int(tp);
@@ -455,10 +476,16 @@ static void tg3_restart_ints(struct tg3 *tp)
 {
        tw32(TG3PCI_MISC_HOST_CTRL,
                (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
-       tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000);
+       tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+                    tp->last_tag << 24);
        mmiowb();
 
-       if (tg3_has_work(tp))
+       /* When doing tagged status, this work check is unnecessary.
+        * The last_tag we write above tells the chip which piece of
+        * work we've completed.
+        */
+       if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
+           tg3_has_work(tp))
                tw32(HOSTCC_MODE, tp->coalesce_mode |
                     (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
 }
@@ -2500,7 +2527,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
                if (netif_carrier_ok(tp->dev)) {
                        tw32(HOSTCC_STAT_COAL_TICKS,
-                            DEFAULT_STAT_COAL_TICKS);
+                            tp->coal.stats_block_coalesce_usecs);
                } else {
                        tw32(HOSTCC_STAT_COAL_TICKS, 0);
                }
@@ -2886,7 +2913,6 @@ static int tg3_poll(struct net_device *netdev, int *budget)
         * All RX "locking" is done by ensuring outside
         * code synchronizes with dev->poll()
         */
-       done = 1;
        if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) {
                int orig_budget = *budget;
                int work_done;
@@ -2898,12 +2924,14 @@ static int tg3_poll(struct net_device *netdev, int *budget)
 
                *budget -= work_done;
                netdev->quota -= work_done;
-
-               if (work_done >= orig_budget)
-                       done = 0;
        }
 
+       if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+               tp->last_tag = sblk->status_tag;
+       rmb();
+
        /* if no more work, tell net stack and NIC we're done */
+       done = !tg3_has_work(tp);
        if (done) {
                spin_lock_irqsave(&tp->lock, flags);
                __netif_rx_complete(netdev);
@@ -2928,22 +2956,21 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
        spin_lock_irqsave(&tp->lock, flags);
 
        /*
-        * writing any value to intr-mbox-0 clears PCI INTA# and
+        * Writing any value to intr-mbox-0 clears PCI INTA# and
         * chip-internal interrupt pending events.
-        * writing non-zero to intr-mbox-0 additional tells the
+        * Writing non-zero to intr-mbox-0 additional tells the
         * NIC to stop sending us irqs, engaging "in-intr-handler"
         * event coalescing.
         */
        tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+       tp->last_tag = sblk->status_tag;
        sblk->status &= ~SD_STATUS_UPDATED;
-
        if (likely(tg3_has_work(tp)))
                netif_rx_schedule(dev);         /* schedule NAPI poll */
        else {
-               /* no work, re-enable interrupts
-                */
+               /* No work, re-enable interrupts.  */
                tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-                            0x00000000);
+                            tp->last_tag << 24);
        }
 
        spin_unlock_irqrestore(&tp->lock, flags);
@@ -2969,21 +2996,62 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        if ((sblk->status & SD_STATUS_UPDATED) ||
            !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
                /*
-                * writing any value to intr-mbox-0 clears PCI INTA# and
+                * Writing any value to intr-mbox-0 clears PCI INTA# and
                 * chip-internal interrupt pending events.
-                * writing non-zero to intr-mbox-0 additional tells the
+                * Writing non-zero to intr-mbox-0 additional tells the
                 * NIC to stop sending us irqs, engaging "in-intr-handler"
                 * event coalescing.
                 */
                tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
                             0x00000001);
+               sblk->status &= ~SD_STATUS_UPDATED;
+               if (likely(tg3_has_work(tp)))
+                       netif_rx_schedule(dev);         /* schedule NAPI poll */
+               else {
+                       /* No work, shared interrupt perhaps?  re-enable
+                        * interrupts, and flush that PCI write
+                        */
+                       tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+                               0x00000000);
+                       tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+               }
+       } else {        /* shared interrupt */
+               handled = 0;
+       }
+
+       spin_unlock_irqrestore(&tp->lock, flags);
+
+       return IRQ_RETVAL(handled);
+}
+
+static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct net_device *dev = dev_id;
+       struct tg3 *tp = netdev_priv(dev);
+       struct tg3_hw_status *sblk = tp->hw_status;
+       unsigned long flags;
+       unsigned int handled = 1;
+
+       spin_lock_irqsave(&tp->lock, flags);
+
+       /* In INTx mode, it is possible for the interrupt to arrive at
+        * the CPU before the status block posted prior to the interrupt.
+        * Reading the PCI State register will confirm whether the
+        * interrupt is ours and will flush the status block.
+        */
+       if ((sblk->status & SD_STATUS_UPDATED) ||
+           !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
                /*
-                * Flush PCI write.  This also guarantees that our
-                * status block has been flushed to host memory.
+                * writing any value to intr-mbox-0 clears PCI INTA# and
+                * chip-internal interrupt pending events.
+                * writing non-zero to intr-mbox-0 additional tells the
+                * NIC to stop sending us irqs, engaging "in-intr-handler"
+                * event coalescing.
                 */
-               tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+               tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+                            0x00000001);
+               tp->last_tag = sblk->status_tag;
                sblk->status &= ~SD_STATUS_UPDATED;
-
                if (likely(tg3_has_work(tp)))
                        netif_rx_schedule(dev);         /* schedule NAPI poll */
                else {
@@ -2991,7 +3059,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                         * interrupts, and flush that PCI write
                         */
                        tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-                               0x00000000);
+                                    tp->last_tag << 24);
                        tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
                }
        } else {        /* shared interrupt */
@@ -3020,7 +3088,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
 }
 
 static int tg3_init_hw(struct tg3 *);
-static int tg3_halt(struct tg3 *);
+static int tg3_halt(struct tg3 *, int, int);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void tg3_poll_controller(struct net_device *dev)
@@ -3044,7 +3112,7 @@ static void tg3_reset_task(void *_data)
        restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
        tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
 
-       tg3_halt(tp);
+       tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
        tg3_init_hw(tp);
 
        tg3_netif_start(tp);
@@ -3390,7 +3458,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
        spin_lock_irq(&tp->lock);
        spin_lock(&tp->tx_lock);
 
-       tg3_halt(tp);
+       tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 
        tg3_set_mtu(dev, tp, new_mtu);
 
@@ -3657,7 +3725,7 @@ err_out:
 /* To stop a block, clear the enable bit and poll till it
  * clears.  tp->lock is held.
  */
-static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit)
+static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int silent)
 {
        unsigned int i;
        u32 val;
@@ -3690,7 +3758,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit)
                        break;
        }
 
-       if (i == MAX_WAIT_CNT) {
+       if (i == MAX_WAIT_CNT && !silent) {
                printk(KERN_ERR PFX "tg3_stop_block timed out, "
                       "ofs=%lx enable_bit=%x\n",
                       ofs, enable_bit);
@@ -3701,7 +3769,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit)
 }
 
 /* tp->lock is held. */
-static int tg3_abort_hw(struct tg3 *tp)
+static int tg3_abort_hw(struct tg3 *tp, int silent)
 {
        int i, err;
 
@@ -3711,22 +3779,20 @@ static int tg3_abort_hw(struct tg3 *tp)
        tw32_f(MAC_RX_MODE, tp->rx_mode);
        udelay(10);
 
-       err  = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE);
-       err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE);
-       err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE);
-       err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE);
-       err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE);
-       err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE);
-
-       err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE);
-       err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE);
-       err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
-       err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE);
-       err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE);
-       err |= tg3_stop_block(tp, DMAC_MODE, DMAC_MODE_ENABLE);
-       err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE);
-       if (err)
-               goto out;
+       err  = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE, silent);
+
+       err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, DMAC_MODE, DMAC_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE, silent);
 
        tp->mac_mode &= ~MAC_MODE_TDE_ENABLE;
        tw32_f(MAC_MODE, tp->mac_mode);
@@ -3744,27 +3810,24 @@ static int tg3_abort_hw(struct tg3 *tp)
                printk(KERN_ERR PFX "tg3_abort_hw timed out for %s, "
                       "TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n",
                       tp->dev->name, tr32(MAC_TX_MODE));
-               return -ENODEV;
+               err |= -ENODEV;
        }
 
-       err  = tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE);
-       err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE);
-       err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE);
+       err |= tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE, silent);
 
        tw32(FTQ_RESET, 0xffffffff);
        tw32(FTQ_RESET, 0x00000000);
 
-       err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE);
-       err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE);
-       if (err)
-               goto out;
+       err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent);
+       err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent);
 
        if (tp->hw_status)
                memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
        if (tp->hw_stats)
                memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
 
-out:
        return err;
 }
 
@@ -4086,19 +4149,19 @@ static void tg3_stop_fw(struct tg3 *tp)
 }
 
 /* tp->lock is held. */
-static int tg3_halt(struct tg3 *tp)
+static int tg3_halt(struct tg3 *tp, int kind, int silent)
 {
        int err;
 
        tg3_stop_fw(tp);
 
-       tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN);
+       tg3_write_sig_pre_reset(tp, kind);
 
-       tg3_abort_hw(tp);
+       tg3_abort_hw(tp, silent);
        err = tg3_chip_reset(tp);
 
-       tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN);
-       tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
+       tg3_write_sig_legacy(tp, kind);
+       tg3_write_sig_post_reset(tp, kind);
 
        if (err)
                return err;
@@ -4312,7 +4375,12 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
         */
        tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
 
+       /* It is possible that bootcode is still loading at this point.
+        * Get the nvram lock first before halting the cpu.
+        */
+       tg3_nvram_lock(tp);
        err = tg3_halt_cpu(tp, cpu_base);
+       tg3_nvram_unlock(tp);
        if (err)
                goto out;
 
@@ -5049,6 +5117,27 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr,
 }
 
 static void __tg3_set_rx_mode(struct net_device *);
+static void tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
+{
+       tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
+       tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
+       tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
+       tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames);
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+               tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
+               tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq);
+       }
+       tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
+       tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq);
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+               u32 val = ec->stats_block_coalesce_usecs;
+
+               if (!netif_carrier_ok(tp->dev))
+                       val = 0;
+
+               tw32(HOSTCC_STAT_COAL_TICKS, val);
+       }
+}
 
 /* tp->lock is held. */
 static int tg3_reset_hw(struct tg3 *tp)
@@ -5063,9 +5152,7 @@ static int tg3_reset_hw(struct tg3 *tp)
        tg3_write_sig_pre_reset(tp, RESET_KIND_INIT);
 
        if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) {
-               err = tg3_abort_hw(tp);
-               if (err)
-                       return err;
+               tg3_abort_hw(tp, 1);
        }
 
        err = tg3_chip_reset(tp);
@@ -5373,16 +5460,7 @@ static int tg3_reset_hw(struct tg3 *tp)
                udelay(10);
        }
 
-       tw32(HOSTCC_RXCOL_TICKS, 0);
-       tw32(HOSTCC_TXCOL_TICKS, LOW_TXCOL_TICKS);
-       tw32(HOSTCC_RXMAX_FRAMES, 1);
-       tw32(HOSTCC_TXMAX_FRAMES, LOW_RXMAX_FRAMES);
-       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
-               tw32(HOSTCC_RXCOAL_TICK_INT, 0);
-               tw32(HOSTCC_TXCOAL_TICK_INT, 0);
-       }
-       tw32(HOSTCC_RXCOAL_MAXF_INT, 1);
-       tw32(HOSTCC_TXCOAL_MAXF_INT, 0);
+       tg3_set_coalesce(tp, &tp->coal);
 
        /* set status block DMA address */
        tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
@@ -5395,8 +5473,6 @@ static int tg3_reset_hw(struct tg3 *tp)
                 * the tg3_periodic_fetch_stats call there, and
                 * tg3_get_stats to see how this works for 5705/5750 chips.
                 */
-               tw32(HOSTCC_STAT_COAL_TICKS,
-                    DEFAULT_STAT_COAL_TICKS);
                tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
                     ((u64) tp->stats_mapping >> 32));
                tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
@@ -5452,7 +5528,8 @@ static int tg3_reset_hw(struct tg3 *tp)
        udelay(100);
 
        tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
-       tr32(MAILBOX_INTERRUPT_0);
+       tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+       tp->last_tag = 0;
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
                tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
@@ -5730,31 +5807,33 @@ static void tg3_timer(unsigned long __opaque)
        spin_lock_irqsave(&tp->lock, flags);
        spin_lock(&tp->tx_lock);
 
-       /* All of this garbage is because when using non-tagged
-        * IRQ status the mailbox/status_block protocol the chip
-        * uses with the cpu is race prone.
-        */
-       if (tp->hw_status->status & SD_STATUS_UPDATED) {
-               tw32(GRC_LOCAL_CTRL,
-                    tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
-       } else {
-               tw32(HOSTCC_MODE, tp->coalesce_mode |
-                    (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
-       }
+       if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
+               /* All of this garbage is because when using non-tagged
+                * IRQ status the mailbox/status_block protocol the chip
+                * uses with the cpu is race prone.
+                */
+               if (tp->hw_status->status & SD_STATUS_UPDATED) {
+                       tw32(GRC_LOCAL_CTRL,
+                            tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+               } else {
+                       tw32(HOSTCC_MODE, tp->coalesce_mode |
+                            (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
+               }
 
-       if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
-               tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
-               spin_unlock(&tp->tx_lock);
-               spin_unlock_irqrestore(&tp->lock, flags);
-               schedule_work(&tp->reset_task);
-               return;
+               if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
+                       tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
+                       spin_unlock(&tp->tx_lock);
+                       spin_unlock_irqrestore(&tp->lock, flags);
+                       schedule_work(&tp->reset_task);
+                       return;
+               }
        }
 
-       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
-               tg3_periodic_fetch_stats(tp);
-
        /* This part only runs once per second. */
        if (!--tp->timer_counter) {
+               if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+                       tg3_periodic_fetch_stats(tp);
+
                if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
                        u32 mac_stat;
                        int phy_event;
@@ -5825,6 +5904,9 @@ static int tg3_test_interrupt(struct tg3 *tp)
        int err, i;
        u32 int_mbox = 0;
 
+       if (!netif_running(dev))
+               return -ENODEV;
+
        tg3_disable_ints(tp);
 
        free_irq(tp->pdev->irq, dev);
@@ -5853,9 +5935,13 @@ static int tg3_test_interrupt(struct tg3 *tp)
        if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
                err = request_irq(tp->pdev->irq, tg3_msi,
                                  SA_SAMPLE_RANDOM, dev->name, dev);
-       else
-               err = request_irq(tp->pdev->irq, tg3_interrupt,
+       else {
+               irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt;
+               if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+                       fn = tg3_interrupt_tagged;
+               err = request_irq(tp->pdev->irq, fn,
                                  SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+       }
 
        if (err)
                return err;
@@ -5907,9 +5993,14 @@ static int tg3_test_msi(struct tg3 *tp)
 
        tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
 
-       err = request_irq(tp->pdev->irq, tg3_interrupt,
-                         SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+       {
+               irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt;
+               if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+                       fn = tg3_interrupt_tagged;
 
+               err = request_irq(tp->pdev->irq, fn,
+                                 SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+       }
        if (err)
                return err;
 
@@ -5919,7 +6010,7 @@ static int tg3_test_msi(struct tg3 *tp)
        spin_lock_irq(&tp->lock);
        spin_lock(&tp->tx_lock);
 
-       tg3_halt(tp);
+       tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
        err = tg3_init_hw(tp);
 
        spin_unlock(&tp->tx_lock);
@@ -5955,7 +6046,13 @@ static int tg3_open(struct net_device *dev)
        if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
            (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) &&
            (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX)) {
-               if (pci_enable_msi(tp->pdev) == 0) {
+               /* All MSI supporting chips should support tagged
+                * status.  Assert that this is the case.
+                */
+               if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
+                       printk(KERN_WARNING PFX "%s: MSI without TAGGED? "
+                              "Not using MSI.\n", tp->dev->name);
+               } else if (pci_enable_msi(tp->pdev) == 0) {
                        u32 msi_mode;
 
                        msi_mode = tr32(MSGINT_MODE);
@@ -5966,9 +6063,14 @@ static int tg3_open(struct net_device *dev)
        if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
                err = request_irq(tp->pdev->irq, tg3_msi,
                                  SA_SAMPLE_RANDOM, dev->name, dev);
-       else
-               err = request_irq(tp->pdev->irq, tg3_interrupt,
+       else {
+               irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt;
+               if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+                       fn = tg3_interrupt_tagged;
+
+               err = request_irq(tp->pdev->irq, fn,
                                  SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+       }
 
        if (err) {
                if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
@@ -5984,12 +6086,19 @@ static int tg3_open(struct net_device *dev)
 
        err = tg3_init_hw(tp);
        if (err) {
-               tg3_halt(tp);
+               tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                tg3_free_rings(tp);
        } else {
-               tp->timer_offset = HZ / 10;
-               tp->timer_counter = tp->timer_multiplier = 10;
-               tp->asf_counter = tp->asf_multiplier = (10 * 120);
+               if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+                       tp->timer_offset = HZ;
+               else
+                       tp->timer_offset = HZ / 10;
+
+               BUG_ON(tp->timer_offset > HZ);
+               tp->timer_counter = tp->timer_multiplier =
+                       (HZ / tp->timer_offset);
+               tp->asf_counter = tp->asf_multiplier =
+                       ((HZ / tp->timer_offset) * 120);
 
                init_timer(&tp->timer);
                tp->timer.expires = jiffies + tp->timer_offset;
@@ -6012,6 +6121,7 @@ static int tg3_open(struct net_device *dev)
 
        if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
                err = tg3_test_msi(tp);
+
                if (err) {
                        spin_lock_irq(&tp->lock);
                        spin_lock(&tp->tx_lock);
@@ -6020,7 +6130,7 @@ static int tg3_open(struct net_device *dev)
                                pci_disable_msi(tp->pdev);
                                tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
                        }
-                       tg3_halt(tp);
+                       tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                        tg3_free_rings(tp);
                        tg3_free_consistent(tp);
 
@@ -6293,7 +6403,7 @@ static int tg3_close(struct net_device *dev)
 
        tg3_disable_ints(tp);
 
-       tg3_halt(tp);
+       tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
        tg3_free_rings(tp);
        tp->tg3_flags &=
                ~(TG3_FLAG_INIT_COMPLETE |
@@ -7013,7 +7123,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
        tp->tx_pending = ering->tx_pending;
 
        if (netif_running(dev)) {
-               tg3_halt(tp);
+               tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                tg3_init_hw(tp);
                tg3_netif_start(tp);
        }
@@ -7056,7 +7166,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
                tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE;
 
        if (netif_running(dev)) {
-               tg3_halt(tp);
+               tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                tg3_init_hw(tp);
                tg3_netif_start(tp);
        }
@@ -7115,12 +7225,20 @@ static int tg3_get_stats_count (struct net_device *dev)
        return TG3_NUM_STATS;
 }
 
+static int tg3_get_test_count (struct net_device *dev)
+{
+       return TG3_NUM_TEST;
+}
+
 static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf)
 {
        switch (stringset) {
        case ETH_SS_STATS:
                memcpy(buf, &ethtool_stats_keys, sizeof(ethtool_stats_keys));
                break;
+       case ETH_SS_TEST:
+               memcpy(buf, &ethtool_test_keys, sizeof(ethtool_test_keys));
+               break;
        default:
                WARN_ON(1);     /* we need a WARN() */
                break;
@@ -7134,6 +7252,516 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
        memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats));
 }
 
+#define NVRAM_TEST_SIZE 0x100
+
+static int tg3_test_nvram(struct tg3 *tp)
+{
+       u32 *buf, csum;
+       int i, j, err = 0;
+
+       buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) {
+               u32 val;
+
+               if ((err = tg3_nvram_read(tp, i, &val)) != 0)
+                       break;
+               buf[j] = cpu_to_le32(val);
+       }
+       if (i < NVRAM_TEST_SIZE)
+               goto out;
+
+       err = -EIO;
+       if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC)
+               goto out;
+
+       /* Bootstrap checksum at offset 0x10 */
+       csum = calc_crc((unsigned char *) buf, 0x10);
+       if(csum != cpu_to_le32(buf[0x10/4]))
+               goto out;
+
+       /* Manufacturing block starts at offset 0x74, checksum at 0xfc */
+       csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88);
+       if (csum != cpu_to_le32(buf[0xfc/4]))
+                goto out;
+
+       err = 0;
+
+out:
+       kfree(buf);
+       return err;
+}
+
+#define TG3_SERDES_TIMEOUT_SEC 2
+#define TG3_COPPER_TIMEOUT_SEC 6
+
+static int tg3_test_link(struct tg3 *tp)
+{
+       int i, max;
+
+       if (!netif_running(tp->dev))
+               return -ENODEV;
+
+       if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+               max = TG3_SERDES_TIMEOUT_SEC;
+       else
+               max = TG3_COPPER_TIMEOUT_SEC;
+
+       for (i = 0; i < max; i++) {
+               if (netif_carrier_ok(tp->dev))
+                       return 0;
+
+               if (msleep_interruptible(1000))
+                       break;
+       }
+
+       return -EIO;
+}
+
+/* Only test the commonly used registers */
+static int tg3_test_registers(struct tg3 *tp)
+{
+       int i, is_5705;
+       u32 offset, read_mask, write_mask, val, save_val, read_val;
+       static struct {
+               u16 offset;
+               u16 flags;
+#define TG3_FL_5705    0x1
+#define TG3_FL_NOT_5705        0x2
+#define TG3_FL_NOT_5788        0x4
+               u32 read_mask;
+               u32 write_mask;
+       } reg_tbl[] = {
+               /* MAC Control Registers */
+               { MAC_MODE, TG3_FL_NOT_5705,
+                       0x00000000, 0x00ef6f8c },
+               { MAC_MODE, TG3_FL_5705,
+                       0x00000000, 0x01ef6b8c },
+               { MAC_STATUS, TG3_FL_NOT_5705,
+                       0x03800107, 0x00000000 },
+               { MAC_STATUS, TG3_FL_5705,
+                       0x03800100, 0x00000000 },
+               { MAC_ADDR_0_HIGH, 0x0000,
+                       0x00000000, 0x0000ffff },
+               { MAC_ADDR_0_LOW, 0x0000,
+                       0x00000000, 0xffffffff },
+               { MAC_RX_MTU_SIZE, 0x0000,
+                       0x00000000, 0x0000ffff },
+               { MAC_TX_MODE, 0x0000,
+                       0x00000000, 0x00000070 },
+               { MAC_TX_LENGTHS, 0x0000,
+                       0x00000000, 0x00003fff },
+               { MAC_RX_MODE, TG3_FL_NOT_5705,
+                       0x00000000, 0x000007fc },
+               { MAC_RX_MODE, TG3_FL_5705,
+                       0x00000000, 0x000007dc },
+               { MAC_HASH_REG_0, 0x0000,
+                       0x00000000, 0xffffffff },
+               { MAC_HASH_REG_1, 0x0000,
+                       0x00000000, 0xffffffff },
+               { MAC_HASH_REG_2, 0x0000,
+                       0x00000000, 0xffffffff },
+               { MAC_HASH_REG_3, 0x0000,
+                       0x00000000, 0xffffffff },
+
+               /* Receive Data and Receive BD Initiator Control Registers. */
+               { RCVDBDI_JUMBO_BD+0, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { RCVDBDI_JUMBO_BD+4, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { RCVDBDI_JUMBO_BD+8, TG3_FL_NOT_5705,
+                       0x00000000, 0x00000003 },
+               { RCVDBDI_JUMBO_BD+0xc, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { RCVDBDI_STD_BD+0, 0x0000,
+                       0x00000000, 0xffffffff },
+               { RCVDBDI_STD_BD+4, 0x0000,
+                       0x00000000, 0xffffffff },
+               { RCVDBDI_STD_BD+8, 0x0000,
+                       0x00000000, 0xffff0002 },
+               { RCVDBDI_STD_BD+0xc, 0x0000,
+                       0x00000000, 0xffffffff },
+       
+               /* Receive BD Initiator Control Registers. */
+               { RCVBDI_STD_THRESH, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { RCVBDI_STD_THRESH, TG3_FL_5705,
+                       0x00000000, 0x000003ff },
+               { RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+       
+               /* Host Coalescing Control Registers. */
+               { HOSTCC_MODE, TG3_FL_NOT_5705,
+                       0x00000000, 0x00000004 },
+               { HOSTCC_MODE, TG3_FL_5705,
+                       0x00000000, 0x000000f6 },
+               { HOSTCC_RXCOL_TICKS, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_RXCOL_TICKS, TG3_FL_5705,
+                       0x00000000, 0x000003ff },
+               { HOSTCC_TXCOL_TICKS, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_TXCOL_TICKS, TG3_FL_5705,
+                       0x00000000, 0x000003ff },
+               { HOSTCC_RXMAX_FRAMES, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_RXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788,
+                       0x00000000, 0x000000ff },
+               { HOSTCC_TXMAX_FRAMES, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_TXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788,
+                       0x00000000, 0x000000ff },
+               { HOSTCC_RXCOAL_TICK_INT, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_TXCOAL_TICK_INT, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788,
+                       0x00000000, 0x000000ff },
+               { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788,
+                       0x00000000, 0x000000ff },
+               { HOSTCC_STAT_COAL_TICKS, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_STATS_BLK_HOST_ADDR, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_STATS_BLK_HOST_ADDR+4, TG3_FL_NOT_5705,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_STATUS_BLK_HOST_ADDR, 0x0000,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_STATUS_BLK_HOST_ADDR+4, 0x0000,
+                       0x00000000, 0xffffffff },
+               { HOSTCC_STATS_BLK_NIC_ADDR, 0x0000,
+                       0xffffffff, 0x00000000 },
+               { HOSTCC_STATUS_BLK_NIC_ADDR, 0x0000,
+                       0xffffffff, 0x00000000 },
+
+               /* Buffer Manager Control Registers. */
+               { BUFMGR_MB_POOL_ADDR, 0x0000,
+                       0x00000000, 0x007fff80 },
+               { BUFMGR_MB_POOL_SIZE, 0x0000,
+                       0x00000000, 0x007fffff },
+               { BUFMGR_MB_RDMA_LOW_WATER, 0x0000,
+                       0x00000000, 0x0000003f },
+               { BUFMGR_MB_MACRX_LOW_WATER, 0x0000,
+                       0x00000000, 0x000001ff },
+               { BUFMGR_MB_HIGH_WATER, 0x0000,
+                       0x00000000, 0x000001ff },
+               { BUFMGR_DMA_DESC_POOL_ADDR, TG3_FL_NOT_5705,
+                       0xffffffff, 0x00000000 },
+               { BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705,
+                       0xffffffff, 0x00000000 },
+       
+               /* Mailbox Registers */
+               { GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000,
+                       0x00000000, 0x000001ff },
+               { GRCMBOX_RCVJUMBO_PROD_IDX+4, TG3_FL_NOT_5705,
+                       0x00000000, 0x000001ff },
+               { GRCMBOX_RCVRET_CON_IDX_0+4, 0x0000,
+                       0x00000000, 0x000007ff },
+               { GRCMBOX_SNDHOST_PROD_IDX_0+4, 0x0000,
+                       0x00000000, 0x000001ff },
+
+               { 0xffff, 0x0000, 0x00000000, 0x00000000 },
+       };
+
+       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+               is_5705 = 1;
+       else
+               is_5705 = 0;
+
+       for (i = 0; reg_tbl[i].offset != 0xffff; i++) {
+               if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705))
+                       continue;
+
+               if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705))
+                       continue;
+
+               if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
+                   (reg_tbl[i].flags & TG3_FL_NOT_5788))
+                       continue;
+
+               offset = (u32) reg_tbl[i].offset;
+               read_mask = reg_tbl[i].read_mask;
+               write_mask = reg_tbl[i].write_mask;
+
+               /* Save the original register content */
+               save_val = tr32(offset);
+
+               /* Determine the read-only value. */
+               read_val = save_val & read_mask;
+
+               /* Write zero to the register, then make sure the read-only bits
+                * are not changed and the read/write bits are all zeros.
+                */
+               tw32(offset, 0);
+
+               val = tr32(offset);
+
+               /* Test the read-only and read/write bits. */
+               if (((val & read_mask) != read_val) || (val & write_mask))
+                       goto out;
+
+               /* Write ones to all the bits defined by RdMask and WrMask, then
+                * make sure the read-only bits are not changed and the
+                * read/write bits are all ones.
+                */
+               tw32(offset, read_mask | write_mask);
+
+               val = tr32(offset);
+
+               /* Test the read-only bits. */
+               if ((val & read_mask) != read_val)
+                       goto out;
+
+               /* Test the read/write bits. */
+               if ((val & write_mask) != write_mask)
+                       goto out;
+
+               tw32(offset, save_val);
+       }
+
+       return 0;
+
+out:
+       printk(KERN_ERR PFX "Register test failed at offset %x\n", offset);
+       tw32(offset, save_val);
+       return -EIO;
+}
+
+static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len)
+{
+       static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a };
+       int i;
+       u32 j;
+
+       for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) {
+               for (j = 0; j < len; j += 4) {
+                       u32 val;
+
+                       tg3_write_mem(tp, offset + j, test_pattern[i]);
+                       tg3_read_mem(tp, offset + j, &val);
+                       if (val != test_pattern[i])
+                               return -EIO;
+               }
+       }
+       return 0;
+}
+
+static int tg3_test_memory(struct tg3 *tp)
+{
+       static struct mem_entry {
+               u32 offset;
+               u32 len;
+       } mem_tbl_570x[] = {
+               { 0x00000000, 0x01000},
+               { 0x00002000, 0x1c000},
+               { 0xffffffff, 0x00000}
+       }, mem_tbl_5705[] = {
+               { 0x00000100, 0x0000c},
+               { 0x00000200, 0x00008},
+               { 0x00000b50, 0x00400},
+               { 0x00004000, 0x00800},
+               { 0x00006000, 0x01000},
+               { 0x00008000, 0x02000},
+               { 0x00010000, 0x0e000},
+               { 0xffffffff, 0x00000}
+       };
+       struct mem_entry *mem_tbl;
+       int err = 0;
+       int i;
+
+       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+               mem_tbl = mem_tbl_5705;
+       else
+               mem_tbl = mem_tbl_570x;
+
+       for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
+               if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset,
+                   mem_tbl[i].len)) != 0)
+                       break;
+       }
+       
+       return err;
+}
+
+static int tg3_test_loopback(struct tg3 *tp)
+{
+       u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key;
+       u32 desc_idx;
+       struct sk_buff *skb, *rx_skb;
+       u8 *tx_data;
+       dma_addr_t map;
+       int num_pkts, tx_len, rx_len, i, err;
+       struct tg3_rx_buffer_desc *desc;
+
+       if (!netif_running(tp->dev))
+               return -ENODEV;
+
+       err = -EIO;
+
+       tg3_abort_hw(tp, 1);
+
+       /* Clearing this flag to keep interrupts disabled */
+       tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+       tg3_reset_hw(tp);
+
+       mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
+                  MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY |
+                  MAC_MODE_PORT_MODE_GMII;
+       tw32(MAC_MODE, mac_mode);
+
+       tx_len = 1514;
+       skb = dev_alloc_skb(tx_len);
+       tx_data = skb_put(skb, tx_len);
+       memcpy(tx_data, tp->dev->dev_addr, 6);
+       memset(tx_data + 6, 0x0, 8);
+
+       tw32(MAC_RX_MTU_SIZE, tx_len + 4);
+
+       for (i = 14; i < tx_len; i++)
+               tx_data[i] = (u8) (i & 0xff);
+
+       map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
+
+       tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
+            HOSTCC_MODE_NOW);
+
+       udelay(10);
+
+       rx_start_idx = tp->hw_status->idx[0].rx_producer;
+
+       send_idx = 0;
+       num_pkts = 0;
+
+       tg3_set_txd(tp, send_idx, map, tx_len, 0, 1);
+
+       send_idx++;
+       num_pkts++;
+
+       tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx);
+       tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
+
+       udelay(10);
+
+       for (i = 0; i < 10; i++) {
+               tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
+                      HOSTCC_MODE_NOW);
+
+               udelay(10);
+
+               tx_idx = tp->hw_status->idx[0].tx_consumer;
+               rx_idx = tp->hw_status->idx[0].rx_producer;
+               if ((tx_idx == send_idx) &&
+                   (rx_idx == (rx_start_idx + num_pkts)))
+                       break;
+       }
+
+       pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE);
+       dev_kfree_skb(skb);
+
+       if (tx_idx != send_idx)
+               goto out;
+
+       if (rx_idx != rx_start_idx + num_pkts)
+               goto out;
+
+       desc = &tp->rx_rcb[rx_start_idx];
+       desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
+       opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
+       if (opaque_key != RXD_OPAQUE_RING_STD)
+               goto out;
+
+       if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
+           (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII))
+               goto out;
+
+       rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4;
+       if (rx_len != tx_len)
+               goto out;
+
+       rx_skb = tp->rx_std_buffers[desc_idx].skb;
+
+       map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping);
+       pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE);
+
+       for (i = 14; i < tx_len; i++) {
+               if (*(rx_skb->data + i) != (u8) (i & 0xff))
+                       goto out;
+       }
+       err = 0;
+       
+       /* tg3_free_rings will unmap and free the rx_skb */
+out:
+       return err;
+}
+
+static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
+                         u64 *data)
+{
+       struct tg3 *tp = netdev_priv(dev);
+
+       memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
+
+       if (tg3_test_nvram(tp) != 0) {
+               etest->flags |= ETH_TEST_FL_FAILED;
+               data[0] = 1;
+       }
+       if (tg3_test_link(tp) != 0) {
+               etest->flags |= ETH_TEST_FL_FAILED;
+               data[1] = 1;
+       }
+       if (etest->flags & ETH_TEST_FL_OFFLINE) {
+               if (netif_running(dev))
+                       tg3_netif_stop(tp);
+
+               spin_lock_irq(&tp->lock);
+               spin_lock(&tp->tx_lock);
+
+               tg3_halt(tp, RESET_KIND_SUSPEND, 1);
+               tg3_nvram_lock(tp);
+               tg3_halt_cpu(tp, RX_CPU_BASE);
+               if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+                       tg3_halt_cpu(tp, TX_CPU_BASE);
+               tg3_nvram_unlock(tp);
+
+               if (tg3_test_registers(tp) != 0) {
+                       etest->flags |= ETH_TEST_FL_FAILED;
+                       data[2] = 1;
+               }
+               if (tg3_test_memory(tp) != 0) {
+                       etest->flags |= ETH_TEST_FL_FAILED;
+                       data[3] = 1;
+               }
+               if (tg3_test_loopback(tp) != 0) {
+                       etest->flags |= ETH_TEST_FL_FAILED;
+                       data[4] = 1;
+               }
+
+               spin_unlock(&tp->tx_lock);
+               spin_unlock_irq(&tp->lock);
+               if (tg3_test_interrupt(tp) != 0) {
+                       etest->flags |= ETH_TEST_FL_FAILED;
+                       data[5] = 1;
+               }
+               spin_lock_irq(&tp->lock);
+               spin_lock(&tp->tx_lock);
+
+               tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+               if (netif_running(dev)) {
+                       tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+                       tg3_init_hw(tp);
+                       tg3_netif_start(tp);
+               }
+               spin_unlock(&tp->tx_lock);
+               spin_unlock_irq(&tp->lock);
+       }
+}
+
 static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct mii_ioctl_data *data = if_mii(ifr);
@@ -7210,6 +7838,14 @@ static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
 }
 #endif
 
+static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+       struct tg3 *tp = netdev_priv(dev);
+
+       memcpy(ec, &tp->coal, sizeof(*ec));
+       return 0;
+}
+
 static struct ethtool_ops tg3_ethtool_ops = {
        .get_settings           = tg3_get_settings,
        .set_settings           = tg3_set_settings,
@@ -7239,9 +7875,12 @@ static struct ethtool_ops tg3_ethtool_ops = {
        .get_tso                = ethtool_op_get_tso,
        .set_tso                = tg3_set_tso,
 #endif
+       .self_test_count        = tg3_get_test_count,
+       .self_test              = tg3_self_test,
        .get_strings            = tg3_get_strings,
        .get_stats_count        = tg3_get_stats_count,
        .get_ethtool_stats      = tg3_get_ethtool_stats,
+       .get_coalesce           = tg3_get_coalesce,
 };
 
 static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
@@ -7921,6 +8560,16 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
 
                case NIC_SRAM_DATA_CFG_LED_MODE_MAC:
                        tp->led_ctrl = LED_CTRL_MODE_MAC;
+
+                       /* Default to PHY_1_MODE if 0 (MAC_MODE) is
+                        * read on some older 5700/5701 bootcode.
+                        */
+                       if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+                           ASIC_REV_5700 ||
+                           GET_ASIC_REV(tp->pci_chip_rev_id) ==
+                           ASIC_REV_5701)
+                               tp->led_ctrl = LED_CTRL_MODE_PHY_1;
+
                        break;
 
                case SHASTA_EXT_LED_SHARED:
@@ -8429,15 +9078,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
                tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
 
-       /* Only 5701 and later support tagged irq status mode.
-        * Also, 5788 chips cannot use tagged irq status.
-        *
-        * However, since we are using NAPI avoid tagged irq status
-        * because the interrupt condition is more difficult to
-        * fully clear in that mode.
-        */
        tp->coalesce_mode = 0;
-
        if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX &&
            GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
                tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
@@ -8501,6 +9142,18 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
             grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
                tp->tg3_flags2 |= TG3_FLG2_IS_5788;
 
+       if (!(tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
+           (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700))
+               tp->tg3_flags |= TG3_FLAG_TAGGED_STATUS;
+       if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
+               tp->coalesce_mode |= (HOSTCC_MODE_CLRTICK_RXBD |
+                                     HOSTCC_MODE_CLRTICK_TXBD);
+
+               tp->misc_host_ctrl |= MISC_HOST_CTRL_TAGGED_STATUS;
+               pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
+                                      tp->misc_host_ctrl);
+       }
+
        /* these are limited to 10/100 only */
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
             (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) ||
@@ -8678,6 +9331,146 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
        return 0;
 }
 
+#define BOUNDARY_SINGLE_CACHELINE      1
+#define BOUNDARY_MULTI_CACHELINE       2
+
+static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
+{
+       int cacheline_size;
+       u8 byte;
+       int goal;
+
+       pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, &byte);
+       if (byte == 0)
+               cacheline_size = 1024;
+       else
+               cacheline_size = (int) byte * 4;
+
+       /* On 5703 and later chips, the boundary bits have no
+        * effect.
+        */
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
+           !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
+               goto out;
+
+#if defined(CONFIG_PPC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC)
+       goal = BOUNDARY_MULTI_CACHELINE;
+#else
+#if defined(CONFIG_SPARC64) || defined(CONFIG_ALPHA)
+       goal = BOUNDARY_SINGLE_CACHELINE;
+#else
+       goal = 0;
+#endif
+#endif
+
+       if (!goal)
+               goto out;
+
+       /* PCI controllers on most RISC systems tend to disconnect
+        * when a device tries to burst across a cache-line boundary.
+        * Therefore, letting tg3 do so just wastes PCI bandwidth.
+        *
+        * Unfortunately, for PCI-E there are only limited
+        * write-side controls for this, and thus for reads
+        * we will still get the disconnects.  We'll also waste
+        * these PCI cycles for both read and write for chips
+        * other than 5700 and 5701 which do not implement the
+        * boundary bits.
+        */
+       if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
+           !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
+               switch (cacheline_size) {
+               case 16:
+               case 32:
+               case 64:
+               case 128:
+                       if (goal == BOUNDARY_SINGLE_CACHELINE) {
+                               val |= (DMA_RWCTRL_READ_BNDRY_128_PCIX |
+                                       DMA_RWCTRL_WRITE_BNDRY_128_PCIX);
+                       } else {
+                               val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX |
+                                       DMA_RWCTRL_WRITE_BNDRY_384_PCIX);
+                       }
+                       break;
+
+               case 256:
+                       val |= (DMA_RWCTRL_READ_BNDRY_256_PCIX |
+                               DMA_RWCTRL_WRITE_BNDRY_256_PCIX);
+                       break;
+
+               default:
+                       val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX |
+                               DMA_RWCTRL_WRITE_BNDRY_384_PCIX);
+                       break;
+               };
+       } else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+               switch (cacheline_size) {
+               case 16:
+               case 32:
+               case 64:
+                       if (goal == BOUNDARY_SINGLE_CACHELINE) {
+                               val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE;
+                               val |= DMA_RWCTRL_WRITE_BNDRY_64_PCIE;
+                               break;
+                       }
+                       /* fallthrough */
+               case 128:
+               default:
+                       val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE;
+                       val |= DMA_RWCTRL_WRITE_BNDRY_128_PCIE;
+                       break;
+               };
+       } else {
+               switch (cacheline_size) {
+               case 16:
+                       if (goal == BOUNDARY_SINGLE_CACHELINE) {
+                               val |= (DMA_RWCTRL_READ_BNDRY_16 |
+                                       DMA_RWCTRL_WRITE_BNDRY_16);
+                               break;
+                       }
+                       /* fallthrough */
+               case 32:
+                       if (goal == BOUNDARY_SINGLE_CACHELINE) {
+                               val |= (DMA_RWCTRL_READ_BNDRY_32 |
+                                       DMA_RWCTRL_WRITE_BNDRY_32);
+                               break;
+                       }
+                       /* fallthrough */
+               case 64:
+                       if (goal == BOUNDARY_SINGLE_CACHELINE) {
+                               val |= (DMA_RWCTRL_READ_BNDRY_64 |
+                                       DMA_RWCTRL_WRITE_BNDRY_64);
+                               break;
+                       }
+                       /* fallthrough */
+               case 128:
+                       if (goal == BOUNDARY_SINGLE_CACHELINE) {
+                               val |= (DMA_RWCTRL_READ_BNDRY_128 |
+                                       DMA_RWCTRL_WRITE_BNDRY_128);
+                               break;
+                       }
+                       /* fallthrough */
+               case 256:
+                       val |= (DMA_RWCTRL_READ_BNDRY_256 |
+                               DMA_RWCTRL_WRITE_BNDRY_256);
+                       break;
+               case 512:
+                       val |= (DMA_RWCTRL_READ_BNDRY_512 |
+                               DMA_RWCTRL_WRITE_BNDRY_512);
+                       break;
+               case 1024:
+               default:
+                       val |= (DMA_RWCTRL_READ_BNDRY_1024 |
+                               DMA_RWCTRL_WRITE_BNDRY_1024);
+                       break;
+               };
+       }
+
+out:
+       return val;
+}
+
 static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dma, int size, int to_device)
 {
        struct tg3_internal_buffer_desc test_desc;
@@ -8759,12 +9552,12 @@ static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dm
        return ret;
 }
 
-#define TEST_BUFFER_SIZE       0x400
+#define TEST_BUFFER_SIZE       0x2000
 
 static int __devinit tg3_test_dma(struct tg3 *tp)
 {
        dma_addr_t buf_dma;
-       u32 *buf;
+       u32 *buf, saved_dma_rwctrl;
        int ret;
 
        buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma);
@@ -8776,46 +9569,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
        tp->dma_rwctrl = ((0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
                          (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT));
 
-#ifndef CONFIG_X86
-       {
-               u8 byte;
-               int cacheline_size;
-               pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, &byte);
-
-               if (byte == 0)
-                       cacheline_size = 1024;
-               else
-                       cacheline_size = (int) byte * 4;
-
-               switch (cacheline_size) {
-               case 16:
-               case 32:
-               case 64:
-               case 128:
-                       if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
-                           !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
-                               tp->dma_rwctrl |=
-                                       DMA_RWCTRL_WRITE_BNDRY_384_PCIX;
-                               break;
-                       } else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
-                               tp->dma_rwctrl &=
-                                       ~(DMA_RWCTRL_PCI_WRITE_CMD);
-                               tp->dma_rwctrl |=
-                                       DMA_RWCTRL_WRITE_BNDRY_128_PCIE;
-                               break;
-                       }
-                       /* fallthrough */
-               case 256:
-                       if (!(tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
-                           !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
-                               tp->dma_rwctrl |=
-                                       DMA_RWCTRL_WRITE_BNDRY_256;
-                       else if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
-                               tp->dma_rwctrl |=
-                                       DMA_RWCTRL_WRITE_BNDRY_256_PCIX;
-               };
-       }
-#endif
+       tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl);
 
        if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
                /* DMA read watermark not used on PCIE */
@@ -8834,7 +9588,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
                        if (ccval == 0x6 || ccval == 0x7)
                                tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
 
-                       /* Set bit 23 to renable PCIX hw bug fix */
+                       /* Set bit 23 to enable PCIX hw bug fix */
                        tp->dma_rwctrl |= 0x009f0000;
                } else {
                        tp->dma_rwctrl |= 0x001b000f;
@@ -8875,6 +9629,13 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
                goto out;
 
+       /* It is best to perform DMA test with maximum write burst size
+        * to expose the 5700/5701 write DMA bug.
+        */
+       saved_dma_rwctrl = tp->dma_rwctrl;
+       tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK;
+       tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
+
        while (1) {
                u32 *p = buf, i;
 
@@ -8913,8 +9674,9 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
                        if (p[i] == i)
                                continue;
 
-                       if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) ==
-                           DMA_RWCTRL_WRITE_BNDRY_DISAB) {
+                       if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) !=
+                           DMA_RWCTRL_WRITE_BNDRY_16) {
+                               tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK;
                                tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16;
                                tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
                                break;
@@ -8931,6 +9693,28 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
                        break;
                }
        }
+       if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) !=
+           DMA_RWCTRL_WRITE_BNDRY_16) {
+               static struct pci_device_id dma_wait_state_chipsets[] = {
+                       { PCI_DEVICE(PCI_VENDOR_ID_APPLE,
+                                    PCI_DEVICE_ID_APPLE_UNI_N_PCI15) },
+                       { },
+               };
+
+               /* DMA test passed without adjusting DMA boundary,
+                * now look for chipsets that are known to expose the
+                * DMA bug without failing the test.
+                */
+               if (pci_dev_present(dma_wait_state_chipsets)) {
+                       tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK;
+                       tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16;
+               }
+               else
+                       /* Safe to use the calculated DMA boundary. */
+                       tp->dma_rwctrl = saved_dma_rwctrl;
+
+               tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
+       }
 
 out:
        pci_free_consistent(tp->pdev, TEST_BUFFER_SIZE, buf, buf_dma);
@@ -9018,6 +9802,31 @@ static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp)
        return peer;
 }
 
+static void __devinit tg3_init_coal(struct tg3 *tp)
+{
+       struct ethtool_coalesce *ec = &tp->coal;
+
+       memset(ec, 0, sizeof(*ec));
+       ec->cmd = ETHTOOL_GCOALESCE;
+       ec->rx_coalesce_usecs = LOW_RXCOL_TICKS;
+       ec->tx_coalesce_usecs = LOW_TXCOL_TICKS;
+       ec->rx_max_coalesced_frames = LOW_RXMAX_FRAMES;
+       ec->tx_max_coalesced_frames = LOW_TXMAX_FRAMES;
+       ec->rx_coalesce_usecs_irq = DEFAULT_RXCOAL_TICK_INT;
+       ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT;
+       ec->rx_max_coalesced_frames_irq = DEFAULT_RXCOAL_MAXF_INT;
+       ec->tx_max_coalesced_frames_irq = DEFAULT_TXCOAL_MAXF_INT;
+       ec->stats_block_coalesce_usecs = DEFAULT_STAT_COAL_TICKS;
+
+       if (tp->coalesce_mode & (HOSTCC_MODE_CLRTICK_RXBD |
+                                HOSTCC_MODE_CLRTICK_TXBD)) {
+               ec->rx_coalesce_usecs = LOW_RXCOL_TICKS_CLRTCKS;
+               ec->rx_coalesce_usecs_irq = DEFAULT_RXCOAL_TICK_INT_CLRTCKS;
+               ec->tx_coalesce_usecs = LOW_TXCOL_TICKS_CLRTCKS;
+               ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS;
+       }
+}
+
 static int __devinit tg3_init_one(struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
@@ -9239,7 +10048,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
            (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
                pci_save_state(tp->pdev);
                tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
-               tg3_halt(tp);
+               tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
        }
 
        err = tg3_test_dma(tp);
@@ -9263,6 +10072,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        /* flow control autonegotiation is default behavior */
        tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
 
+       tg3_init_coal(tp);
+
        err = register_netdev(dev);
        if (err) {
                printk(KERN_ERR PFX "Cannot register net device, "
@@ -9305,6 +10116,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
               (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0,
               (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
               (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
+       printk(KERN_INFO "%s: dma_rwctrl[%08x]\n",
+              dev->name, tp->dma_rwctrl);
 
        return 0;
 
@@ -9362,7 +10175,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
 
        spin_lock_irq(&tp->lock);
        spin_lock(&tp->tx_lock);
-       tg3_halt(tp);
+       tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
        spin_unlock(&tp->tx_lock);
        spin_unlock_irq(&tp->lock);
 
index 8de6f21037bae13910b0f9c8f075a8d38b89db69..993f84c93dc41df662f0864e4a6bfb556051512e 100644 (file)
 #define  HOSTCC_STATUS_ERROR_ATTN       0x00000004
 #define HOSTCC_RXCOL_TICKS             0x00003c08
 #define  LOW_RXCOL_TICKS                0x00000032
+#define  LOW_RXCOL_TICKS_CLRTCKS        0x00000014
 #define  DEFAULT_RXCOL_TICKS            0x00000048
 #define  HIGH_RXCOL_TICKS               0x00000096
 #define HOSTCC_TXCOL_TICKS             0x00003c0c
 #define  LOW_TXCOL_TICKS                0x00000096
+#define  LOW_TXCOL_TICKS_CLRTCKS        0x00000048
 #define  DEFAULT_TXCOL_TICKS            0x0000012c
 #define  HIGH_TXCOL_TICKS               0x00000145
 #define HOSTCC_RXMAX_FRAMES            0x00003c10
 #define  HIGH_TXMAX_FRAMES              0x00000052
 #define HOSTCC_RXCOAL_TICK_INT         0x00003c18
 #define  DEFAULT_RXCOAL_TICK_INT        0x00000019
+#define  DEFAULT_RXCOAL_TICK_INT_CLRTCKS 0x00000014
 #define HOSTCC_TXCOAL_TICK_INT         0x00003c1c
 #define  DEFAULT_TXCOAL_TICK_INT        0x00000019
+#define  DEFAULT_TXCOAL_TICK_INT_CLRTCKS 0x00000014
 #define HOSTCC_RXCOAL_MAXF_INT         0x00003c20
 #define  DEFAULT_RXCOAL_MAXF_INT        0x00000005
 #define HOSTCC_TXCOAL_MAXF_INT         0x00003c24
@@ -2023,6 +2027,7 @@ struct tg3 {
 
        struct tg3_hw_status            *hw_status;
        dma_addr_t                      status_mapping;
+       u32                             last_tag;
 
        u32                             msg_enable;
 
@@ -2068,6 +2073,7 @@ struct tg3 {
 
        u32                             rx_offset;
        u32                             tg3_flags;
+#define TG3_FLAG_TAGGED_STATUS         0x00000001
 #define TG3_FLAG_TXD_MBOX_HWBUG                0x00000002
 #define TG3_FLAG_RX_CHECKSUMS          0x00000004
 #define TG3_FLAG_USE_LINKCHG_REG       0x00000008
@@ -2225,7 +2231,7 @@ struct tg3 {
 
 #define SST_25VF0X0_PAGE_SIZE          4098
 
-
+       struct ethtool_coalesce         coal;
 };
 
 #endif /* !(_T3_H) */
index a7ffa64502dd3a2074418392e1c4e576ee81517a..9680a308c62b1a69cc7926159ea85916a4a94e1b 100644 (file)
@@ -193,6 +193,12 @@ static  int aui[MAX_TLAN_BOARDS];
 static  int duplex[MAX_TLAN_BOARDS];
 static  int speed[MAX_TLAN_BOARDS];
 static  int boards_found;
+module_param_array(aui, int, NULL, 0);
+module_param_array(duplex, int, NULL, 0);
+module_param_array(speed, int, NULL, 0);
+MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
+MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
+MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
 
 MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
 MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
@@ -204,8 +210,13 @@ MODULE_LICENSE("GPL");
 
 /* Turn on debugging. See Documentation/networking/tlan.txt for details */
 static  int            debug;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
 
 static int             bbuf;
+module_param(bbuf, int, 0);
+MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)");
+
 static u8              *TLanPadBuffer;
 static  dma_addr_t     TLanPadBufferDMA;
 static char            TLanSignature[] = "TLAN";
@@ -2381,6 +2392,7 @@ TLan_FinishReset( struct net_device *dev )
                TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
                return;
        }
+       TLan_SetMulticastList(dev);
 
 } /* TLan_FinishReset */
 
index edae09a4b021e353ab4fbba756e31492fbb8fd2e..919c40cd635cbb9a0286f0486e706a0c5e1aeb16 100644 (file)
@@ -174,6 +174,7 @@ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val)
                                break;
                }
                spin_unlock_irqrestore(&tp->mii_lock, flags);
+               return;
        }
                
        /* Establish sync by sending 32 logic ones. */
index d098b3ba35384fb912989348fd6da59820711ca4..e0ae3ed6e5785832794a8cb32dec13d1d592f5cc 100644 (file)
@@ -1104,7 +1104,7 @@ static void set_rx_mode(struct net_device *dev)
                        if (entry != 0) {
                                /* Avoid a chip errata by prefixing a dummy entry. Don't do
                                   this on the ULI526X as it triggers a different problem */
-                               if (!(tp->chip_id == ULI526X && (tp->revision = 0x40 || tp->revision == 0x50))) {
+                               if (!(tp->chip_id == ULI526X && (tp->revision == 0x40 || tp->revision == 0x50))) {
                                        tp->tx_buffers[entry].skb = NULL;
                                        tp->tx_buffers[entry].mapping = 0;
                                        tp->tx_ring[entry].length =
index 35791934a602e3f2dd9371fe3b7548c2f38f6920..66b94668ddd8a69241d2535ce4726cc74f4d92f2 100644 (file)
@@ -26,7 +26,7 @@ config WAN
 # There is no way to detect a comtrol sv11 - force it modular for now.
 config HOSTESS_SV11
        tristate "Comtrol Hostess SV-11 support"
-       depends on WAN && ISA && m
+       depends on WAN && ISA && m && ISA_DMA_API
        help
          Driver for Comtrol Hostess SV-11 network card which
          operates on low speed synchronous serial links at up to
@@ -38,7 +38,7 @@ config HOSTESS_SV11
 # The COSA/SRP driver has not been tested as non-modular yet.
 config COSA
        tristate "COSA/SRP sync serial boards support"
-       depends on WAN && ISA && m
+       depends on WAN && ISA && m && ISA_DMA_API
        ---help---
          Driver for COSA and SRP synchronous serial boards.
 
@@ -127,7 +127,7 @@ config LANMEDIA
 # There is no way to detect a Sealevel board. Force it modular
 config SEALEVEL_4021
        tristate "Sealevel Systems 4021 support"
-       depends on WAN && ISA && m
+       depends on WAN && ISA && m && ISA_DMA_API
        help
          This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
 
index 0aaa12c0c098ae48d48cac1535abf92e7c0880f9..1d3231cc471acff346ef9dd6425d66c1b96c4276 100644 (file)
@@ -323,7 +323,7 @@ config PRISM54
          For a complete list of supported cards visit <http://prism54.org>.
          Here is the latest confirmed list of supported cards:
 
-         3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72
+         3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72 (version 1)
          Allnet ALL0271 PCI Card
          Compex WL54G Cardbus Card
          Corega CG-WLCB54GT Cardbus Card
index 463c789cdc77c5e9705e656277050a47b76523ee..fb10a2db63ad018623c2781be4da42db970cf434 100644 (file)
@@ -754,7 +754,7 @@ typedef struct {
   u8 zero;
   u8 ssidLen;
   u8 ssid[32];
-  u16 rssi;
+  u16 dBm;
 #define CAP_ESS (1<<0)
 #define CAP_IBSS (1<<1)
 #define CAP_PRIVACY (1<<4)
@@ -1125,6 +1125,9 @@ static int micsetup(struct airo_info *ai);
 static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
 
+static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
+static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
+
 #include <linux/crypto.h>
 #endif
 
@@ -1713,6 +1716,7 @@ static int readBSSListRid(struct airo_info *ai, int first,
        list->fh.dwell = le16_to_cpu(list->fh.dwell);
        list->dsChannel = le16_to_cpu(list->dsChannel);
        list->atimWindow = le16_to_cpu(list->atimWindow);
+       list->dBm = le16_to_cpu(list->dBm);
        return rc;
 }
 
@@ -3245,7 +3249,10 @@ badrx:
                                        wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
                                else
                                        wstats.level = (hdr.rssi[1] + 321) / 2;
-                               wstats.updated = 3;     
+                               wstats.noise = apriv->wstats.qual.noise;
+                               wstats.updated = IW_QUAL_LEVEL_UPDATED
+                                       | IW_QUAL_QUAL_UPDATED
+                                       | IW_QUAL_NOISE_UPDATED;
                                /* Update spy records */
                                wireless_spy_update(dev, sa, &wstats);
                        }
@@ -3588,7 +3595,10 @@ void mpi_receive_802_11 (struct airo_info *ai)
                        wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
                else
                        wstats.level = (hdr.rssi[1] + 321) / 2;
-               wstats.updated = 3;
+               wstats.noise = ai->wstats.qual.noise;
+               wstats.updated = IW_QUAL_QUAL_UPDATED
+                       | IW_QUAL_LEVEL_UPDATED
+                       | IW_QUAL_NOISE_UPDATED;
                /* Update spy records */
                wireless_spy_update(ai->dev, sa, &wstats);
        }
@@ -3679,7 +3689,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
                status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
                if ( status == SUCCESS ) {
                        if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
-                               memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512);
+                               memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
                }
                else {
                        if (ai->rssi) {
@@ -5348,7 +5358,7 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
                                (int)BSSList_rid.bssid[5],
                                (int)BSSList_rid.ssidLen,
                                BSSList_rid.ssid,
-                               (int)BSSList_rid.rssi);
+                               (int)BSSList_rid.dBm);
                ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
                                (int)BSSList_rid.dsChannel,
                                BSSList_rid.cap & CAP_ESS ? "ESS" : "",
@@ -5593,6 +5603,29 @@ static void __exit airo_cleanup_module( void )
  * would not work at all... - Jean II
  */
 
+static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
+{
+       if( !rssi_rid )
+               return 0;
+
+       return (0x100 - rssi_rid[rssi].rssidBm);
+}
+
+static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
+{
+       int i;
+
+       if( !rssi_rid )
+               return 0;
+
+       for( i = 0; i < 256; i++ )
+               if (rssi_rid[i].rssidBm == dbm)
+                       return rssi_rid[i].rssipct;
+
+       return 0;
+}
+
+
 static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
 {
        int quality = 0;
@@ -6443,11 +6476,29 @@ static int airo_get_range(struct net_device *dev,
        }
        range->num_frequency = k;
 
+       range->sensitivity = 65535;
+
        /* Hum... Should put the right values there */
-       range->max_qual.qual = airo_get_max_quality(&cap_rid);
-       range->max_qual.level = 0x100 - 120;    /* -120 dBm */
+       if (local->rssi)
+               range->max_qual.qual = 100;     /* % */
+       else
+               range->max_qual.qual = airo_get_max_quality(&cap_rid);
+       range->max_qual.level = 0;      /* 0 means we use dBm  */
        range->max_qual.noise = 0;
-       range->sensitivity = 65535;
+       range->max_qual.updated = 0;
+
+       /* Experimental measurements - boundary 11/5.5 Mb/s */
+       /* Note : with or without the (local->rssi), results
+        * are somewhat different. - Jean II */
+       if (local->rssi) {
+               range->avg_qual.qual = 50;      /* % */
+               range->avg_qual.level = 186;    /* -70 dBm */
+       } else {
+               range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
+               range->avg_qual.level = 176;    /* -80 dBm */
+       }
+       range->avg_qual.noise = 0;
+       range->avg_qual.updated = 0;
 
        for(i = 0 ; i < 8 ; i++) {
                range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
@@ -6508,15 +6559,6 @@ static int airo_get_range(struct net_device *dev,
        range->max_retry = 65535;
        range->min_r_time = 1024;
        range->max_r_time = 65535 * 1024;
-       /* Experimental measurements - boundary 11/5.5 Mb/s */
-       /* Note : with or without the (local->rssi), results
-        * are somewhat different. - Jean II */
-       range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
-       if (local->rssi)
-               range->avg_qual.level = 186;    /* -70 dBm */
-       else
-               range->avg_qual.level = 176;    /* -80 dBm */
-       range->avg_qual.noise = 0;
 
        /* Event capability (kernel + driver) */
        range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
@@ -6676,12 +6718,18 @@ static int airo_get_aplist(struct net_device *dev,
                loseSync = 0;
                memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
                address[i].sa_family = ARPHRD_ETHER;
-               if (local->rssi)
-                       qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm;
-               else
-                       qual[i].level = (BSSList.rssi + 321) / 2;
-               qual[i].qual = qual[i].noise = 0;
-               qual[i].updated = 2;
+               if (local->rssi) {
+                       qual[i].level = 0x100 - BSSList.dBm;
+                       qual[i].qual = airo_dbm_to_pct( local->rssi, BSSList.dBm );
+                       qual[i].updated = IW_QUAL_QUAL_UPDATED;
+               } else {
+                       qual[i].level = (BSSList.dBm + 321) / 2;
+                       qual[i].qual = 0;
+                       qual[i].updated = IW_QUAL_QUAL_INVALID;
+               }
+               qual[i].noise = local->wstats.qual.noise;
+               qual[i].updated = IW_QUAL_LEVEL_UPDATED
+                               | IW_QUAL_NOISE_UPDATED;
                if (BSSList.index == 0xffff)
                        break;
        }
@@ -6760,7 +6808,7 @@ static int airo_set_scan(struct net_device *dev,
 static inline char *airo_translate_scan(struct net_device *dev,
                                        char *current_ev,
                                        char *end_buf,
-                                       BSSListRid *list)
+                                       BSSListRid *bss)
 {
        struct airo_info *ai = dev->priv;
        struct iw_event         iwe;            /* Temporary buffer */
@@ -6771,22 +6819,22 @@ static inline char *airo_translate_scan(struct net_device *dev,
        /* First entry *MUST* be the AP MAC address */
        iwe.cmd = SIOCGIWAP;
        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-       memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
+       memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
 
        /* Other entries will be displayed in the order we give them */
 
        /* Add the ESSID */
-       iwe.u.data.length = list->ssidLen;
+       iwe.u.data.length = bss->ssidLen;
        if(iwe.u.data.length > 32)
                iwe.u.data.length = 32;
        iwe.cmd = SIOCGIWESSID;
        iwe.u.data.flags = 1;
-       current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
+       current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
 
        /* Add mode */
        iwe.cmd = SIOCGIWMODE;
-       capabilities = le16_to_cpu(list->cap);
+       capabilities = le16_to_cpu(bss->cap);
        if(capabilities & (CAP_ESS | CAP_IBSS)) {
                if(capabilities & CAP_ESS)
                        iwe.u.mode = IW_MODE_MASTER;
@@ -6797,19 +6845,25 @@ static inline char *airo_translate_scan(struct net_device *dev,
 
        /* Add frequency */
        iwe.cmd = SIOCGIWFREQ;
-       iwe.u.freq.m = le16_to_cpu(list->dsChannel);
+       iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
        iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
        iwe.u.freq.e = 1;
        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
 
        /* Add quality statistics */
        iwe.cmd = IWEVQUAL;
-       if (ai->rssi)
-               iwe.u.qual.level = 0x100 - ai->rssi[list->rssi].rssidBm;
-       else
-               iwe.u.qual.level = (list->rssi + 321) / 2;
-       iwe.u.qual.noise = 0;
-       iwe.u.qual.qual = 0;
+       if (ai->rssi) {
+               iwe.u.qual.level = 0x100 - bss->dBm;
+               iwe.u.qual.qual = airo_dbm_to_pct( ai->rssi, bss->dBm );
+               iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED;
+       } else {
+               iwe.u.qual.level = (bss->dBm + 321) / 2;
+               iwe.u.qual.qual = 0;
+               iwe.u.qual.updated = IW_QUAL_QUAL_INVALID;
+       }
+       iwe.u.qual.noise = ai->wstats.qual.noise;
+       iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
+                       | IW_QUAL_NOISE_UPDATED;
        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
 
        /* Add encryption capability */
@@ -6819,7 +6873,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
        else
                iwe.u.data.flags = IW_ENCODE_DISABLED;
        iwe.u.data.length = 0;
-       current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
+       current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
 
        /* Rate : stuffing multiple values in a single event require a bit
         * more of magic - Jean II */
@@ -6831,10 +6885,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
        /* Max 8 values */
        for(i = 0 ; i < 8 ; i++) {
                /* NULL terminated */
-               if(list->rates[i] == 0)
+               if(bss->rates[i] == 0)
                        break;
                /* Bit rate given in 500 kb/s units (+ 0x80) */
-               iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000);
+               iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
                /* Add new value to event */
                current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
        }
@@ -7153,18 +7207,22 @@ static void airo_read_wireless_stats(struct airo_info *local)
        /* The status */
        local->wstats.status = status_rid.mode;
 
-       /* Signal quality and co. But where is the noise level ??? */
-       local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
-       if (local->rssi)
-               local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm;
-       else
+       /* Signal quality and co */
+       if (local->rssi) {
+               local->wstats.qual.level = airo_rssi_to_dbm( local->rssi, status_rid.sigQuality );
+               /* normalizedSignalStrength appears to be a percentage */
+               local->wstats.qual.qual = status_rid.normalizedSignalStrength;
+       } else {
                local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
+               local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
+       }
+       local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED;
        if (status_rid.len >= 124) {
-               local->wstats.qual.noise = 256 - status_rid.noisedBm;
-               local->wstats.qual.updated = 7;
+               local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
+               local->wstats.qual.updated |= IW_QUAL_NOISE_UPDATED;
        } else {
                local->wstats.qual.noise = 0;
-               local->wstats.qual.updated = 3;
+               local->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
        }
 
        /* Packets discarded in the wireless adapter due to wireless
index a91b507e0a7a279b18104b5472e66766b6cdb08b..a4ed28d9c7837227774c1d629a3a638989a8ac07 100644 (file)
@@ -321,6 +321,7 @@ static struct {
        { 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" }, 
        { 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" },
        { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" },
+       { 0, 0, "IEEE 802.11b/Wireless LAN Card S", ATMEL_FW_TYPE_504_2958, "Siemens Gigaset PC Card II" },
        { 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" },
        { 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" },
        { 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" },
index 731010e0e6f6aea8fc063c105138fc9ce756c36c..16a2e6ae37f4b579bad45b50617d0ab62f524e4f 100644 (file)
@@ -34,7 +34,7 @@ config PARPORT
 
 config PARPORT_PC
        tristate "PC-style hardware"
-       depends on PARPORT && (!SPARC64 || PCI) && (!SPARC32 || BROKEN)
+       depends on PARPORT && (!SPARC64 || PCI) && !SPARC32
        ---help---
          You should say Y here if you have a PC-style parallel port. All
          IBM PC compatible computers and some Alphas have PC-style
index c5774e7855d0362acbea8c7c5eb32049e0332612..e7f3bcb790006417c5567712cca71930274fa26d 100644 (file)
 
 #define PARPORT_PC_MAX_PORTS PARPORT_MAX
 
+#ifdef CONFIG_ISA_DMA_API
+#define HAS_DMA
+#endif
+
 /* ECR modes */
 #define ECR_SPP 00
 #define ECR_PS2 01
@@ -610,6 +614,7 @@ dump_parport_state ("leave fifo_write_block_pio", port);
        return length - left;
 }
 
+#ifdef HAS_DMA
 static size_t parport_pc_fifo_write_block_dma (struct parport *port,
                                               const void *buf, size_t length)
 {
@@ -732,6 +737,17 @@ dump_parport_state ("enter fifo_write_block_dma", port);
 dump_parport_state ("leave fifo_write_block_dma", port);
        return length - left;
 }
+#endif
+
+static inline size_t parport_pc_fifo_write_block(struct parport *port,
+                                              const void *buf, size_t length)
+{
+#ifdef HAS_DMA
+       if (port->dma != PARPORT_DMA_NONE)
+               return parport_pc_fifo_write_block_dma (port, buf, length);
+#endif
+       return parport_pc_fifo_write_block_pio (port, buf, length);
+}
 
 /* Parallel Port FIFO mode (ECP chipsets) */
 static size_t parport_pc_compat_write_block_pio (struct parport *port,
@@ -758,10 +774,7 @@ static size_t parport_pc_compat_write_block_pio (struct parport *port,
        port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
 
        /* Write the data to the FIFO. */
-       if (port->dma != PARPORT_DMA_NONE)
-               written = parport_pc_fifo_write_block_dma (port, buf, length);
-       else
-               written = parport_pc_fifo_write_block_pio (port, buf, length);
+       written = parport_pc_fifo_write_block(port, buf, length);
 
        /* Finish up. */
        /* For some hardware we don't want to touch the mode until
@@ -856,10 +869,7 @@ static size_t parport_pc_ecp_write_block_pio (struct parport *port,
        port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
 
        /* Write the data to the FIFO. */
-       if (port->dma != PARPORT_DMA_NONE)
-               written = parport_pc_fifo_write_block_dma (port, buf, length);
-       else
-               written = parport_pc_fifo_write_block_pio (port, buf, length);
+       written = parport_pc_fifo_write_block(port, buf, length);
 
        /* Finish up. */
        /* For some hardware we don't want to touch the mode until
@@ -2285,6 +2295,7 @@ struct parport *parport_pc_probe_port (unsigned long int base,
                }
 
 #ifdef CONFIG_PARPORT_PC_FIFO
+#ifdef HAS_DMA
                if (p->dma != PARPORT_DMA_NONE) {
                        if (request_dma (p->dma, p->name)) {
                                printk (KERN_WARNING "%s: dma %d in use, "
@@ -2306,7 +2317,8 @@ struct parport *parport_pc_probe_port (unsigned long int base,
                                }
                        }
                }
-#endif /* CONFIG_PARPORT_PC_FIFO */
+#endif
+#endif
        }
 
        /* Done probing.  Now put the port into a sensible start-up state. */
@@ -2367,11 +2379,13 @@ void parport_pc_unregister_port (struct parport *p)
        if (p->modes & PARPORT_MODE_ECP)
                release_region(p->base_hi, 3);
 #ifdef CONFIG_PARPORT_PC_FIFO
+#ifdef HAS_DMA
        if (priv->dma_buf)
                pci_free_consistent(priv->dev, PAGE_SIZE,
                                    priv->dma_buf,
                                    priv->dma_handle);
-#endif /* CONFIG_PARPORT_PC_FIFO */
+#endif
+#endif
        kfree (p->private_data);
        parport_put_port(p);
        kfree (ops); /* hope no-one cached it */
index 021d0f76bc4c4db9b914c194c4a97103ed4e34b0..3903f8c559b603989068767f30bae7fceb2144f6 100644 (file)
@@ -52,116 +52,17 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
        if ((buffer_size - length <= 0) || (i >= num_envp))
                return -ENOMEM;
 
+       envp[i++] = scratch;
+       length += scnprintf (scratch, buffer_size - length,
+                           "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
+                           pdev->vendor, pdev->device,
+                           pdev->subsystem_vendor, pdev->subsystem_device,
+                           (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
+                           (u8)(pdev->class));
+       if ((buffer_size - length <= 0) || (i >= num_envp))
+               return -ENOMEM;
+
        envp[i] = NULL;
 
        return 0;
 }
-
-static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
-{
-       struct list_head *ln;
-       struct pci_dev *dev;
-       struct pci_dev_wrapped wrapped_dev;
-       int result = 0;
-
-       pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(wrapped_bus->bus),
-               wrapped_bus->bus->number);
-
-       if (fn->pre_visit_pci_bus) {
-               result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
-               if (result)
-                       return result;
-       }
-
-       ln = wrapped_bus->bus->devices.next; 
-       while (ln != &wrapped_bus->bus->devices) {
-               dev = pci_dev_b(ln);
-               ln = ln->next;
-
-               memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-               wrapped_dev.dev = dev;
-
-               result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
-               if (result)
-                       return result;
-       }
-
-       if (fn->post_visit_pci_bus)
-               result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
-
-       return result;
-}
-
-static int pci_visit_bridge (struct pci_visit * fn,
-                            struct pci_dev_wrapped *wrapped_dev,
-                            struct pci_bus_wrapped *wrapped_parent)
-{
-       struct pci_bus *bus;
-       struct pci_bus_wrapped wrapped_bus;
-       int result = 0;
-
-       pr_debug("PCI: Scanning bridge %s\n", pci_name(wrapped_dev->dev));
-
-       if (fn->visit_pci_dev) {
-               result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
-               if (result)
-                       return result;
-       }
-
-       bus = wrapped_dev->dev->subordinate;
-       if (bus) {
-               memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-               wrapped_bus.bus = bus;
-
-               result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
-       }
-       return result;
-}
-
-/**
- * pci_visit_dev - scans the pci buses.
- * @fn: callback functions that are called while visiting
- * @wrapped_dev: the device to scan
- * @wrapped_parent: the bus where @wrapped_dev is connected to
- *
- * Every bus and every function is presented to a custom
- * function that can act upon it.
- */
-int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,
-                 struct pci_bus_wrapped *wrapped_parent)
-{
-       struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
-       int result = 0;
-
-       if (!dev)
-               return 0;
-
-       if (fn->pre_visit_pci_dev) {
-               result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
-               if (result)
-                       return result;
-       }
-
-       switch (dev->class >> 8) {
-               case PCI_CLASS_BRIDGE_PCI:
-                       result = pci_visit_bridge(fn, wrapped_dev,
-                                                 wrapped_parent);
-                       if (result)
-                               return result;
-                       break;
-               default:
-                       pr_debug("PCI: Scanning device %s\n", pci_name(dev));
-                       if (fn->visit_pci_dev) {
-                               result = fn->visit_pci_dev (wrapped_dev,
-                                                           wrapped_parent);
-                               if (result)
-                                       return result;
-                       }
-       }
-
-       if (fn->post_visit_pci_dev)
-               result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
-
-       return result;
-}
-EXPORT_SYMBOL(pci_visit_dev);
index 3ddd75937a40e3d089f5ed2b964c0336bb80564e..d9769b30be9a6f175a89c68340b0526c885ec5f2 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 
-/* PICMG 2.12 R2.0 HS CSR bits: */
+/* PICMG 2.1 R2.0 HS CSR bits: */
 #define HS_CSR_INS     0x0080
 #define HS_CSR_EXT     0x0040
 #define HS_CSR_PI      0x0030
index ed243605dc7b36bd687fb72b0d96de3aa8f1c2f4..30af105271a2883d559c7ec89a2f5b0efe8f3ed6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * CompactPCI Hot Plug Driver
  *
- * Copyright (C) 2002 SOMA Networks, Inc.
+ * Copyright (C) 2002,2005 SOMA Networks, Inc.
  * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
  * Copyright (C) 2001 IBM Corp.
  *
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
+#include <asm/atomic.h>
 #include <linux/delay.h>
 #include "pci_hotplug.h"
 #include "cpci_hotplug.h"
 
-#define DRIVER_VERSION "0.2"
 #define DRIVER_AUTHOR  "Scott Murray <scottm@somanetworks.com>"
 #define DRIVER_DESC    "CompactPCI Hot Plug Core"
 
 
 #define dbg(format, arg...)                                    \
        do {                                                    \
-               if(cpci_debug)                                  \
+               if (cpci_debug)                                 \
                        printk (KERN_DEBUG "%s: " format "\n",  \
                                MY_NAME , ## arg);              \
-       } while(0)
+       } while (0)
 #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
 #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)
 
 /* local variables */
-static spinlock_t list_lock;
+static DECLARE_RWSEM(list_rwsem);
 static LIST_HEAD(slot_list);
 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) */
@@ -68,6 +69,8 @@ static int disable_slot(struct hotplug_slot *slot);
 static int set_attention_status(struct hotplug_slot *slot, u8 value);
 static int get_power_status(struct hotplug_slot *slot, u8 * value);
 static int get_attention_status(struct hotplug_slot *slot, u8 * value);
+static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
+static int get_latch_status(struct hotplug_slot *slot, u8 * value);
 
 static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
        .owner = THIS_MODULE,
@@ -76,6 +79,8 @@ static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
        .set_attention_status = set_attention_status,
        .get_power_status = get_power_status,
        .get_attention_status = get_attention_status,
+       .get_adapter_status = get_adapter_status,
+       .get_latch_status = get_latch_status,
 };
 
 static int
@@ -106,10 +111,8 @@ enable_slot(struct hotplug_slot *hotplug_slot)
 
        dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
 
-       if(controller->ops->set_power) {
+       if (controller->ops->set_power)
                retval = controller->ops->set_power(slot, 1);
-       }
-
        return retval;
 }
 
@@ -121,35 +124,41 @@ disable_slot(struct hotplug_slot *hotplug_slot)
 
        dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
 
+       down_write(&list_rwsem);
+
        /* Unconfigure device */
        dbg("%s - unconfiguring slot %s",
            __FUNCTION__, slot->hotplug_slot->name);
-       if((retval = cpci_unconfigure_slot(slot))) {
+       if ((retval = cpci_unconfigure_slot(slot))) {
                err("%s - could not unconfigure slot %s",
                    __FUNCTION__, slot->hotplug_slot->name);
-               return retval;
+               goto disable_error;
        }
        dbg("%s - finished unconfiguring slot %s",
            __FUNCTION__, slot->hotplug_slot->name);
 
        /* Clear EXT (by setting it) */
-       if(cpci_clear_ext(slot)) {
+       if (cpci_clear_ext(slot)) {
                err("%s - could not clear EXT for slot %s",
                    __FUNCTION__, slot->hotplug_slot->name);
                retval = -ENODEV;
+               goto disable_error;
        }
        cpci_led_on(slot);
 
-       if(controller->ops->set_power) {
-               retval = controller->ops->set_power(slot, 0);
-       }
+       if (controller->ops->set_power)
+               if ((retval = controller->ops->set_power(slot, 0)))
+                       goto disable_error;
 
-       if(update_adapter_status(slot->hotplug_slot, 0)) {
+       if (update_adapter_status(slot->hotplug_slot, 0))
                warn("failure to update adapter file");
-       }
-
-       slot->extracting = 0;
 
+       if (slot->extracting) {
+               slot->extracting = 0;
+               atomic_dec(&extracting);
+       }
+disable_error:
+       up_write(&list_rwsem);
        return retval;
 }
 
@@ -158,9 +167,8 @@ cpci_get_power_status(struct slot *slot)
 {
        u8 power = 1;
 
-       if(controller->ops->get_power) {
+       if (controller->ops->get_power)
                power = controller->ops->get_power(slot);
-       }
        return power;
 }
 
@@ -188,6 +196,20 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
        return cpci_set_attention_status(hotplug_slot->private, status);
 }
 
+static int
+get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
+{
+       *value = hotplug_slot->info->adapter_status;
+       return 0;
+}
+
+static int
+get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
+{
+       *value = hotplug_slot->info->latch_status;
+       return 0;
+}
+
 static void release_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
@@ -195,6 +217,8 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
        kfree(slot->hotplug_slot->info);
        kfree(slot->hotplug_slot->name);
        kfree(slot->hotplug_slot);
+       if (slot->dev)
+               pci_dev_put(slot->dev);
        kfree(slot);
 }
 
@@ -216,9 +240,8 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
        int status = -ENOMEM;
        int i;
 
-       if(!(controller && bus)) {
+       if (!(controller && bus))
                return -ENODEV;
-       }
 
        /*
         * Create a structure for each slot, and register that slot
@@ -273,10 +296,10 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
                }
 
                /* Add slot to our internal list */
-               spin_lock(&list_lock);
+               down_write(&list_rwsem);
                list_add(&slot->slot_list, &slot_list);
                slots++;
-               spin_unlock(&list_lock);
+               up_write(&list_rwsem);
        }
        return 0;
 error_name:
@@ -295,32 +318,30 @@ int
 cpci_hp_unregister_bus(struct pci_bus *bus)
 {
        struct slot *slot;
-       struct list_head *tmp;
-       struct list_head *next;
-       int status;
+       struct slot *tmp;
+       int status = 0;
 
-       spin_lock(&list_lock);
-       if(!slots) {
-               spin_unlock(&list_lock);
+       down_write(&list_rwsem);
+       if (!slots) {
+               up_write(&list_rwsem);
                return -1;
        }
-       list_for_each_safe(tmp, next, &slot_list) {
-               slot = list_entry(tmp, struct slot, slot_list);
-               if(slot->bus == bus) {
+       list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) {
+               if (slot->bus == bus) {
+                       list_del(&slot->slot_list);
+                       slots--;
+
                        dbg("deregistering slot %s", slot->hotplug_slot->name);
                        status = pci_hp_deregister(slot->hotplug_slot);
-                       if(status) {
+                       if (status) {
                                err("pci_hp_deregister failed with error %d",
                                    status);
-                               return status;
+                               break;
                        }
-
-                       list_del(&slot->slot_list);
-                       slots--;
                }
        }
-       spin_unlock(&list_lock);
-       return 0;
+       up_write(&list_rwsem);
+       return status;
 }
 
 /* This is the interrupt mode interrupt handler */
@@ -330,7 +351,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
        dbg("entered cpci_hp_intr");
 
        /* Check to see if it was our interrupt */
-       if((controller->irq_flags & SA_SHIRQ) &&
+       if ((controller->irq_flags & SA_SHIRQ) &&
            !controller->ops->check_irq(controller->dev_id)) {
                dbg("exited cpci_hp_intr, not our interrupt");
                return IRQ_NONE;
@@ -347,46 +368,38 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
 }
 
 /*
- * According to PICMG 2.12 R2.0, section 6.3.2, upon
+ * According to PICMG 2.1 R2.0, section 6.3.2, upon
  * initialization, the system driver shall clear the
  * INS bits of the cold-inserted devices.
  */
 static int
-init_slots(void)
+init_slots(int clear_ins)
 {
        struct slot *slot;
-       struct list_head *tmp;
        struct pci_dev* dev;
 
        dbg("%s - enter", __FUNCTION__);
-       spin_lock(&list_lock);
-       if(!slots) {
-               spin_unlock(&list_lock);
+       down_read(&list_rwsem);
+       if (!slots) {
+               up_read(&list_rwsem);
                return -1;
        }
-       list_for_each(tmp, &slot_list) {
-               slot = list_entry(tmp, struct slot, slot_list);
+       list_for_each_entry(slot, &slot_list, slot_list) {
                dbg("%s - looking at slot %s",
                    __FUNCTION__, slot->hotplug_slot->name);
-               if(cpci_check_and_clear_ins(slot)) {
+               if (clear_ins && cpci_check_and_clear_ins(slot))
                        dbg("%s - cleared INS for slot %s",
                            __FUNCTION__, slot->hotplug_slot->name);
-                       dev = pci_find_slot(slot->bus->number, PCI_DEVFN(slot->number, 0));
-                       if(dev) {
-                               if(update_adapter_status(slot->hotplug_slot, 1)) {
-                                       warn("failure to update adapter file");
-                               }
-                               if(update_latch_status(slot->hotplug_slot, 1)) {
-                                       warn("failure to update latch file");
-                               }
-                               slot->dev = dev;
-                       } else {
-                               err("%s - no driver attached to device in slot %s",
-                                   __FUNCTION__, slot->hotplug_slot->name);
-                       }
+               dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0));
+               if (dev) {
+                       if (update_adapter_status(slot->hotplug_slot, 1))
+                               warn("failure to update adapter file");
+                       if (update_latch_status(slot->hotplug_slot, 1))
+                               warn("failure to update latch file");
+                       slot->dev = dev;
                }
        }
-       spin_unlock(&list_lock);
+       up_read(&list_rwsem);
        dbg("%s - exit", __FUNCTION__);
        return 0;
 }
@@ -395,27 +408,28 @@ static int
 check_slots(void)
 {
        struct slot *slot;
-       struct list_head *tmp;
        int extracted;
        int inserted;
+       u16 hs_csr;
 
-       spin_lock(&list_lock);
-       if(!slots) {
-               spin_unlock(&list_lock);
+       down_read(&list_rwsem);
+       if (!slots) {
+               up_read(&list_rwsem);
                err("no slots registered, shutting down");
                return -1;
        }
        extracted = inserted = 0;
-       list_for_each(tmp, &slot_list) {
-               slot = list_entry(tmp, struct slot, slot_list);
+       list_for_each_entry(slot, &slot_list, slot_list) {
                dbg("%s - looking at slot %s",
                    __FUNCTION__, slot->hotplug_slot->name);
-               if(cpci_check_and_clear_ins(slot)) {
-                       u16 hs_csr;
-
-                       /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */
-                       if(slot->dev) {
-                               warn("slot %s already inserted", slot->hotplug_slot->name);
+               if (cpci_check_and_clear_ins(slot)) {
+                       /*
+                        * Some broken hardware (e.g. PLX 9054AB) asserts
+                        * ENUM# twice...
+                        */
+                       if (slot->dev) {
+                               warn("slot %s already inserted",
+                                    slot->hotplug_slot->name);
                                inserted++;
                                continue;
                        }
@@ -432,7 +446,7 @@ check_slots(void)
                        /* Configure device */
                        dbg("%s - configuring slot %s",
                            __FUNCTION__, slot->hotplug_slot->name);
-                       if(cpci_configure_slot(slot)) {
+                       if (cpci_configure_slot(slot)) {
                                err("%s - could not configure slot %s",
                                    __FUNCTION__, slot->hotplug_slot->name);
                                continue;
@@ -445,13 +459,11 @@ check_slots(void)
                        dbg("%s - slot %s HS_CSR (2) = %04x",
                            __FUNCTION__, slot->hotplug_slot->name, hs_csr);
 
-                       if(update_latch_status(slot->hotplug_slot, 1)) {
+                       if (update_latch_status(slot->hotplug_slot, 1))
                                warn("failure to update latch file");
-                       }
 
-                       if(update_adapter_status(slot->hotplug_slot, 1)) {
+                       if (update_adapter_status(slot->hotplug_slot, 1))
                                warn("failure to update adapter file");
-                       }
 
                        cpci_led_off(slot);
 
@@ -461,9 +473,7 @@ check_slots(void)
                            __FUNCTION__, slot->hotplug_slot->name, hs_csr);
 
                        inserted++;
-               } else if(cpci_check_ext(slot)) {
-                       u16 hs_csr;
-
+               } else if (cpci_check_ext(slot)) {
                        /* Process extraction request */
                        dbg("%s - slot %s extracted",
                            __FUNCTION__, slot->hotplug_slot->name);
@@ -473,23 +483,40 @@ check_slots(void)
                        dbg("%s - slot %s HS_CSR = %04x",
                            __FUNCTION__, slot->hotplug_slot->name, hs_csr);
 
-                       if(!slot->extracting) {
-                               if(update_latch_status(slot->hotplug_slot, 0)) {
+                       if (!slot->extracting) {
+                               if (update_latch_status(slot->hotplug_slot, 0)) {
                                        warn("failure to update latch file");
                                }
                                slot->extracting = 1;
+                               atomic_inc(&extracting);
                        }
                        extracted++;
+               } else if (slot->extracting) {
+                       hs_csr = cpci_get_hs_csr(slot);
+                       if (hs_csr == 0xffff) {
+                               /*
+                                * Hmmm, we're likely hosed at this point, should we
+                                * bother trying to tell the driver or not?
+                                */
+                               err("card in slot %s was improperly removed",
+                                   slot->hotplug_slot->name);
+                               if (update_adapter_status(slot->hotplug_slot, 0))
+                                       warn("failure to update adapter file");
+                               slot->extracting = 0;
+                               atomic_dec(&extracting);
+                       }
                }
        }
-       spin_unlock(&list_lock);
-       if(inserted || extracted) {
+       up_read(&list_rwsem);
+       dbg("inserted=%d, extracted=%d, extracting=%d",
+           inserted, extracted, atomic_read(&extracting));
+       if (inserted || extracted)
                return extracted;
-       }
-       else {
+       else if (!atomic_read(&extracting)) {
                err("cannot find ENUM# source, shutting down");
                return -1;
        }
+       return 0;
 }
 
 /* This is the interrupt mode worker thread body */
@@ -497,54 +524,37 @@ static int
 event_thread(void *data)
 {
        int rc;
-       struct slot *slot;
-       struct list_head *tmp;
 
        lock_kernel();
        daemonize("cpci_hp_eventd");
        unlock_kernel();
 
        dbg("%s - event thread started", __FUNCTION__);
-       while(1) {
+       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))
+               if (thread_finished || signal_pending(current))
                        break;
-               while(controller->ops->query_enum()) {
+               do {
                        rc = check_slots();
-                       if (rc > 0)
+                       if (rc > 0) {
                                /* Give userspace a chance to handle extraction */
                                msleep(500);
-                       else if (rc < 0) {
+                       else if (rc < 0) {
                                dbg("%s - error checking slots", __FUNCTION__);
                                thread_finished = 1;
                                break;
                        }
-               }
-               /* Check for someone yanking out a board */
-               list_for_each(tmp, &slot_list) {
-                       slot = list_entry(tmp, struct slot, slot_list);
-                       if(slot->extracting) {
-                               /*
-                                * Hmmm, we're likely hosed at this point, should we
-                                * bother trying to tell the driver or not?
-                                */
-                               err("card in slot %s was improperly removed",
-                                   slot->hotplug_slot->name);
-                               if(update_adapter_status(slot->hotplug_slot, 0)) {
-                                       warn("failure to update adapter file");
-                               }
-                               slot->extracting = 0;
-                       }
-               }
+               } while (atomic_read(&extracting) && !thread_finished);
+               if (thread_finished)
+                       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);
        return 0;
@@ -555,45 +565,27 @@ static int
 poll_thread(void *data)
 {
        int rc;
-       struct slot *slot;
-       struct list_head *tmp;
 
        lock_kernel();
        daemonize("cpci_hp_polld");
        unlock_kernel();
 
-       while(1) {
-               if(thread_finished || signal_pending(current))
+       while (1) {
+               if (thread_finished || signal_pending(current))
                        break;
-
-               while(controller->ops->query_enum()) {
-                       rc = check_slots();
-                       if(rc > 0)
-                               /* Give userspace a chance to handle extraction */
-                               msleep(500);
-                       else if (rc < 0) {
-                               dbg("%s - error checking slots", __FUNCTION__);
-                               thread_finished = 1;
-                               break;
-                       }
-               }
-               /* Check for someone yanking out a board */
-               list_for_each(tmp, &slot_list) {
-                       slot = list_entry(tmp, struct slot, slot_list);
-                       if(slot->extracting) {
-                               /*
-                                * Hmmm, we're likely hosed at this point, should we
-                                * bother trying to tell the driver or not?
-                                */
-                               err("card in slot %s was improperly removed",
-                                   slot->hotplug_slot->name);
-                               if(update_adapter_status(slot->hotplug_slot, 0)) {
-                                       warn("failure to update adapter file");
+               if (controller->ops->query_enum()) {
+                       do {
+                               rc = check_slots();
+                               if (rc > 0) {
+                                       /* Give userspace a chance to handle extraction */
+                                       msleep(500);
+                               } else if (rc < 0) {
+                                       dbg("%s - error checking slots", __FUNCTION__);
+                                       thread_finished = 1;
+                                       break;
                                }
-                               slot->extracting = 0;
-                       }
+                       } while (atomic_read(&extracting) && !thread_finished);
                }
-
                msleep(100);
        }
        dbg("poll thread signals exit");
@@ -611,12 +603,11 @@ cpci_start_thread(void)
        init_MUTEX_LOCKED(&thread_exit);
        thread_finished = 0;
 
-       if(controller->irq) {
+       if (controller->irq)
                pid = kernel_thread(event_thread, NULL, 0);
-       } else {
+       else
                pid = kernel_thread(poll_thread, NULL, 0);
-       }
-       if(pid < 0) {
+       if (pid < 0) {
                err("Can't start up our thread");
                return -1;
        }
@@ -629,9 +620,8 @@ cpci_stop_thread(void)
 {
        thread_finished = 1;
        dbg("thread finish command given");
-       if(controller->irq) {
+       if (controller->irq)
                up(&event_semaphore);
-       }
        dbg("wait for thread to exit");
        down(&thread_exit);
 }
@@ -641,42 +631,67 @@ cpci_hp_register_controller(struct cpci_hp_controller *new_controller)
 {
        int status = 0;
 
-       if(!controller) {
-               controller = new_controller;
-               if(controller->irq) {
-                       if(request_irq(controller->irq,
-                                       cpci_hp_intr,
-                                       controller->irq_flags,
-                                       MY_NAME, controller->dev_id)) {
-                               err("Can't get irq %d for the hotplug cPCI controller", controller->irq);
-                               status = -ENODEV;
-                       }
-                       dbg("%s - acquired controller irq %d", __FUNCTION__,
-                           controller->irq);
+       if (controller)
+               return -1;
+       if (!(new_controller && new_controller->ops))
+               return -EINVAL;
+       if (new_controller->irq) {
+               if (!(new_controller->ops->enable_irq &&
+                    new_controller->ops->disable_irq))
+                       status = -EINVAL;
+               if (request_irq(new_controller->irq,
+                              cpci_hp_intr,
+                              new_controller->irq_flags,
+                              MY_NAME,
+                              new_controller->dev_id)) {
+                       err("Can't get irq %d for the hotplug cPCI controller",
+                           new_controller->irq);
+                       status = -ENODEV;
                }
-       } else {
-               err("cPCI hotplug controller already registered");
-               status = -1;
+               dbg("%s - acquired controller irq %d",
+                   __FUNCTION__, new_controller->irq);
        }
+       if (!status)
+               controller = new_controller;
        return status;
 }
 
+static void
+cleanup_slots(void)
+{
+       struct slot *slot;
+       struct slot *tmp;
+
+       /*
+        * Unregister all of our slots with the pci_hotplug subsystem,
+        * and free up all memory that we had allocated.
+        */
+       down_write(&list_rwsem);
+       if (!slots)
+               goto cleanup_null;
+       list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) {
+               list_del(&slot->slot_list);
+               pci_hp_deregister(slot->hotplug_slot);
+       }
+cleanup_null:
+       up_write(&list_rwsem);
+       return;
+}
+
 int
 cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
 {
        int status = 0;
 
-       if(controller) {
-               if(!thread_finished) {
+       if (controller) {
+               if (!thread_finished)
                        cpci_stop_thread();
-               }
-               if(controller->irq) {
+               if (controller->irq)
                        free_irq(controller->irq, controller->dev_id);
-               }
                controller = NULL;
-       } else {
+               cleanup_slots();
+       } else
                status = -ENODEV;
-       }
        return status;
 }
 
@@ -687,32 +702,28 @@ cpci_hp_start(void)
        int status;
 
        dbg("%s - enter", __FUNCTION__);
-       if(!controller) {
+       if (!controller)
                return -ENODEV;
-       }
 
-       spin_lock(&list_lock);
-       if(!slots) {
-               spin_unlock(&list_lock);
+       down_read(&list_rwsem);
+       if (list_empty(&slot_list)) {
+               up_read(&list_rwsem);
                return -ENODEV;
        }
-       spin_unlock(&list_lock);
+       up_read(&list_rwsem);
 
-       if(first) {
-               status = init_slots();
-               if(status) {
-                       return status;
-               }
+       status = init_slots(first);
+       if (first)
                first = 0;
-       }
+       if (status)
+               return status;
 
        status = cpci_start_thread();
-       if(status) {
+       if (status)
                return status;
-       }
        dbg("%s - thread started", __FUNCTION__);
 
-       if(controller->irq) {
+       if (controller->irq) {
                /* Start enum interrupt processing */
                dbg("%s - enabling irq", __FUNCTION__);
                controller->ops->enable_irq();
@@ -724,11 +735,9 @@ cpci_hp_start(void)
 int
 cpci_hp_stop(void)
 {
-       if(!controller) {
+       if (!controller)
                return -ENODEV;
-       }
-
-       if(controller->irq) {
+       if (controller->irq) {
                /* Stop enum interrupt processing */
                dbg("%s - disabling irq", __FUNCTION__);
                controller->ops->disable_irq();
@@ -737,41 +746,10 @@ cpci_hp_stop(void)
        return 0;
 }
 
-static void __exit
-cleanup_slots(void)
-{
-       struct list_head *tmp;
-       struct slot *slot;
-
-       /*
-        * Unregister all of our slots with the pci_hotplug subsystem,
-        * and free up all memory that we had allocated.
-        */
-       spin_lock(&list_lock);
-       if(!slots) {
-               goto null_cleanup;
-       }
-       list_for_each(tmp, &slot_list) {
-               slot = list_entry(tmp, struct slot, slot_list);
-               list_del(&slot->slot_list);
-               pci_hp_deregister(slot->hotplug_slot);
-               kfree(slot->hotplug_slot->info);
-               kfree(slot->hotplug_slot->name);
-               kfree(slot->hotplug_slot);
-               kfree(slot);
-       }
-      null_cleanup:
-       spin_unlock(&list_lock);
-       return;
-}
-
 int __init
 cpci_hotplug_init(int debug)
 {
-       spin_lock_init(&list_lock);
        cpci_debug = debug;
-
-       info(DRIVER_DESC " version: " DRIVER_VERSION);
        return 0;
 }
 
@@ -781,7 +759,8 @@ cpci_hotplug_exit(void)
        /*
         * Clean everything up.
         */
-       cleanup_slots();
+       cpci_hp_stop();
+       cpci_hp_unregister_controller(controller);
 }
 
 EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
index 2e969616f298d620fc0b62876460e557d7505058..225b5e551dd6f53133b982087624b541310bc0ee 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * CompactPCI Hot Plug Driver PCI functions
  *
- * Copyright (C) 2002 by SOMA Networks, Inc.
+ * Copyright (C) 2002,2005 by SOMA Networks, Inc.
  *
  * All rights reserved.
  *
 #include "pci_hotplug.h"
 #include "cpci_hotplug.h"
 
-#if !defined(MODULE)
 #define MY_NAME        "cpci_hotplug"
-#else
-#define MY_NAME        THIS_MODULE->name
-#endif
 
 extern int cpci_debug;
 
 #define dbg(format, arg...)                                    \
        do {                                                    \
-               if(cpci_debug)                                  \
+               if (cpci_debug)                                 \
                        printk (KERN_DEBUG "%s: " format "\n",  \
                                MY_NAME , ## arg);              \
-       } while(0)
+       } while (0)
 #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
 #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)
@@ -61,16 +57,15 @@ u8 cpci_get_attention_status(struct slot* slot)
        hs_cap = pci_bus_find_capability(slot->bus,
                                         slot->devfn,
                                         PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
+       if (!hs_cap)
                return 0;
-       }
 
-       if(pci_bus_read_config_word(slot->bus,
+       if (pci_bus_read_config_word(slot->bus,
                                     slot->devfn,
                                     hs_cap + 2,
-                                    &hs_csr)) {
+                                    &hs_csr))
                return 0;
-       }
+
        return hs_csr & 0x0008 ? 1 : 0;
 }
 
@@ -82,27 +77,22 @@ int cpci_set_attention_status(struct slot* slot, int status)
        hs_cap = pci_bus_find_capability(slot->bus,
                                         slot->devfn,
                                         PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
+       if (!hs_cap)
                return 0;
-       }
-
-       if(pci_bus_read_config_word(slot->bus,
+       if (pci_bus_read_config_word(slot->bus,
                                     slot->devfn,
                                     hs_cap + 2,
-                                    &hs_csr)) {
+                                    &hs_csr))
                return 0;
-       }
-       if(status) {
+       if (status)
                hs_csr |= HS_CSR_LOO;
-       } else {
+       else
                hs_csr &= ~HS_CSR_LOO;
-       }
-       if(pci_bus_write_config_word(slot->bus,
+       if (pci_bus_write_config_word(slot->bus,
                                      slot->devfn,
                                      hs_cap + 2,
-                                     hs_csr)) {
+                                     hs_csr))
                return 0;
-       }
        return 1;
 }
 
@@ -114,51 +104,16 @@ u16 cpci_get_hs_csr(struct slot* slot)
        hs_cap = pci_bus_find_capability(slot->bus,
                                         slot->devfn,
                                         PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
+       if (!hs_cap)
                return 0xFFFF;
-       }
-
-       if(pci_bus_read_config_word(slot->bus,
+       if (pci_bus_read_config_word(slot->bus,
                                     slot->devfn,
                                     hs_cap + 2,
-                                    &hs_csr)) {
+                                    &hs_csr))
                return 0xFFFF;
-       }
        return hs_csr;
 }
 
-#if 0
-u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
-{
-       int hs_cap;
-       u16 new_hs_csr;
-
-       hs_cap = pci_bus_find_capability(slot->bus,
-                                        slot->devfn,
-                                        PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
-               return 0xFFFF;
-       }
-
-       /* Write out the new value */
-       if(pci_bus_write_config_word(slot->bus,
-                                     slot->devfn,
-                                     hs_cap + 2,
-                                     hs_csr)) {
-               return 0xFFFF;
-       }
-
-       /* Read back what we just wrote out */
-       if(pci_bus_read_config_word(slot->bus,
-                                    slot->devfn,
-                                    hs_cap + 2,
-                                    &new_hs_csr)) {
-               return 0xFFFF;
-       }
-       return new_hs_csr;
-}
-#endif
-
 int cpci_check_and_clear_ins(struct slot* slot)
 {
        int hs_cap;
@@ -168,24 +123,22 @@ int cpci_check_and_clear_ins(struct slot* slot)
        hs_cap = pci_bus_find_capability(slot->bus,
                                         slot->devfn,
                                         PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
+       if (!hs_cap)
                return 0;
-       }
-       if(pci_bus_read_config_word(slot->bus,
+       if (pci_bus_read_config_word(slot->bus,
                                     slot->devfn,
                                     hs_cap + 2,
-                                    &hs_csr)) {
+                                    &hs_csr))
                return 0;
-       }
-       if(hs_csr & HS_CSR_INS) {
+       if (hs_csr & HS_CSR_INS) {
                /* Clear INS (by setting it) */
-               if(pci_bus_write_config_word(slot->bus,
+               if (pci_bus_write_config_word(slot->bus,
                                              slot->devfn,
                                              hs_cap + 2,
-                                             hs_csr)) {
+                                             hs_csr))
                        ins = 0;
-               }
-               ins = 1;
+               else
+                       ins = 1;
        }
        return ins;
 }
@@ -199,18 +152,15 @@ int cpci_check_ext(struct slot* slot)
        hs_cap = pci_bus_find_capability(slot->bus,
                                         slot->devfn,
                                         PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
+       if (!hs_cap)
                return 0;
-       }
-       if(pci_bus_read_config_word(slot->bus,
+       if (pci_bus_read_config_word(slot->bus,
                                     slot->devfn,
                                     hs_cap + 2,
-                                    &hs_csr)) {
+                                    &hs_csr))
                return 0;
-       }
-       if(hs_csr & HS_CSR_EXT) {
+       if (hs_csr & HS_CSR_EXT)
                ext = 1;
-       }
        return ext;
 }
 
@@ -222,23 +172,20 @@ int cpci_clear_ext(struct slot* slot)
        hs_cap = pci_bus_find_capability(slot->bus,
                                         slot->devfn,
                                         PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
+       if (!hs_cap)
                return -ENODEV;
-       }
-       if(pci_bus_read_config_word(slot->bus,
+       if (pci_bus_read_config_word(slot->bus,
                                     slot->devfn,
                                     hs_cap + 2,
-                                    &hs_csr)) {
+                                    &hs_csr))
                return -ENODEV;
-       }
-       if(hs_csr & HS_CSR_EXT) {
+       if (hs_csr & HS_CSR_EXT) {
                /* Clear EXT (by setting it) */
-               if(pci_bus_write_config_word(slot->bus,
+               if (pci_bus_write_config_word(slot->bus,
                                              slot->devfn,
                                              hs_cap + 2,
-                                             hs_csr)) {
+                                             hs_csr))
                        return -ENODEV;
-               }
        }
        return 0;
 }
@@ -251,19 +198,16 @@ int cpci_led_on(struct slot* slot)
        hs_cap = pci_bus_find_capability(slot->bus,
                                         slot->devfn,
                                         PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
+       if (!hs_cap)
                return -ENODEV;
-       }
-       if(pci_bus_read_config_word(slot->bus,
+       if (pci_bus_read_config_word(slot->bus,
                                     slot->devfn,
                                     hs_cap + 2,
-                                    &hs_csr)) {
+                                    &hs_csr))
                return -ENODEV;
-       }
-       if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
-               /* Set LOO */
+       if ((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
                hs_csr |= HS_CSR_LOO;
-               if(pci_bus_write_config_word(slot->bus,
+               if (pci_bus_write_config_word(slot->bus,
                                              slot->devfn,
                                              hs_cap + 2,
                                              hs_csr)) {
@@ -283,19 +227,16 @@ int cpci_led_off(struct slot* slot)
        hs_cap = pci_bus_find_capability(slot->bus,
                                         slot->devfn,
                                         PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
+       if (!hs_cap)
                return -ENODEV;
-       }
-       if(pci_bus_read_config_word(slot->bus,
+       if (pci_bus_read_config_word(slot->bus,
                                     slot->devfn,
                                     hs_cap + 2,
-                                    &hs_csr)) {
+                                    &hs_csr))
                return -ENODEV;
-       }
-       if(hs_csr & HS_CSR_LOO) {
-               /* Clear LOO */
+       if (hs_csr & HS_CSR_LOO) {
                hs_csr &= ~HS_CSR_LOO;
-               if(pci_bus_write_config_word(slot->bus,
+               if (pci_bus_write_config_word(slot->bus,
                                              slot->devfn,
                                              hs_cap + 2,
                                              hs_csr)) {
@@ -312,268 +253,21 @@ int cpci_led_off(struct slot* slot)
  * Device configuration functions
  */
 
-static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev)
-{
-       u8 irq_pin;
-       int r;
-
-       dbg("%s - enter", __FUNCTION__);
-
-       /* NOTE: device already setup from prior scan */
-
-       /* FIXME: How would we know if we need to enable the expansion ROM? */
-       pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
-
-       /* Assign resources */
-       dbg("assigning resources for %02x:%02x.%x",
-           dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       for (r = 0; r < 6; r++) {
-               struct resource *res = dev->resource + r;
-               if(res->flags)
-                       pci_assign_resource(dev, r);
-       }
-       dbg("finished assigning resources for %02x:%02x.%x",
-           dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-
-       /* Does this function have an interrupt at all? */
-       dbg("checking for function interrupt");
-       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
-       if(irq_pin) {
-               dbg("function uses interrupt pin %d", irq_pin);
-       }
-
-       /*
-        * Need to explicitly set irq field to 0 so that it'll get assigned
-        * by the pcibios platform dependent code called by pci_enable_device.
-        */
-       dev->irq = 0;
-
-       dbg("enabling device");
-       pci_enable_device(dev); /* XXX check return */
-       dbg("now dev->irq = %d", dev->irq);
-       if(irq_pin && dev->irq) {
-               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-       }
-
-       /* Can't use pci_insert_device at the moment, do it manually for now */
-       pci_proc_attach_device(dev);
-       dbg("notifying drivers");
-       //pci_announce_device_to_drivers(dev);
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
-}
-
-static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
-{
-       int rc;
-       struct pci_bus* child;
-       struct resource* r;
-       u8 max, n;
-       u16 command;
-
-       dbg("%s - enter", __FUNCTION__);
-
-       /* Do basic bridge initialization */
-       rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
-       if(rc) {
-               printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
-       }
-       rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
-       if(rc) {
-               printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
-       }
-       rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
-       if(rc) {
-               printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
-       }
-
-       /*
-        * Set parent bridge's subordinate field so that configuration space
-        * access will work in pci_scan_bridge and friends.
-        */
-       max = pci_max_busnr();
-       bus->subordinate = max + 1;
-       pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
-
-       /* Scan behind bridge */
-       n = pci_scan_bridge(bus, dev, max, 2);
-       child = pci_find_bus(0, max + 1);
-       if (!child)
-               return -ENODEV;
-       pci_proc_attach_bus(child);
-
-       /*
-        * Update parent bridge's subordinate field if there were more bridges
-        * behind the bridge that was scanned.
-        */
-       if(n > max) {
-               bus->subordinate = n;
-               pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
-       }
-
-       /*
-        * Update the bridge resources of the bridge to accommodate devices
-        * behind it.
-        */
-       pci_bus_size_bridges(child);
-       pci_bus_assign_resources(child);
-
-       /* Enable resource mapping via command register */
-       command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
-       r = child->resource[0];
-       if(r && r->start) {
-               command |= PCI_COMMAND_IO;
-       }
-       r = child->resource[1];
-       if(r && r->start) {
-               command |= PCI_COMMAND_MEMORY;
-       }
-       r = child->resource[2];
-       if(r && r->start) {
-               command |= PCI_COMMAND_MEMORY;
-       }
-       rc = pci_write_config_word(dev, PCI_COMMAND, command);
-       if(rc) {
-               err("Error setting command register");
-               return rc;
-       }
-
-       /* Set bridge control register */
-       command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
-       rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
-       if(rc) {
-               err("Error setting bridge control register");
-               return rc;
-       }
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
-}
-
-static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
-                                  struct pci_bus_wrapped *wrapped_bus)
-{
-       int rc;
-       struct pci_dev *dev = wrapped_dev->dev;
-       struct pci_bus *bus = wrapped_bus->bus;
-       struct slot* slot;
-
-       dbg("%s - enter", __FUNCTION__);
-
-       /*
-        * We need to fix up the hotplug representation with the Linux
-        * representation.
-        */
-       if(wrapped_dev->data) {
-               slot = (struct slot*) wrapped_dev->data;
-               slot->dev = dev;
-       }
-
-       /* If it's a bridge, scan behind it for devices */
-       if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-               rc = cpci_configure_bridge(bus, dev);
-               if(rc)
-                       return rc;
-       }
-
-       /* Actually configure device */
-       if(dev) {
-               rc = cpci_configure_dev(bus, dev);
-               if(rc)
-                       return rc;
-       }
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
-}
-
-static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
-                                           struct pci_bus_wrapped *wrapped_bus)
-{
-       struct pci_dev *dev = wrapped_dev->dev;
-       struct slot* slot;
-
-       dbg("%s - enter", __FUNCTION__);
-       if(!dev)
-               return -ENODEV;
-
-       /* Remove the Linux representation */
-       if(pci_remove_device_safe(dev)) {
-               err("Could not remove device\n");
-               return -1;
-       }
-
-       /*
-        * Now remove the hotplug representation.
-        */
-       if(wrapped_dev->data) {
-               slot = (struct slot*) wrapped_dev->data;
-               slot->dev = NULL;
-       } else {
-               dbg("No hotplug representation for %02x:%02x.%x",
-                   dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       }
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
-}
-
-static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
-                                           struct pci_dev_wrapped *wrapped_dev)
-{
-       struct pci_bus *bus = wrapped_bus->bus;
-       struct pci_bus *parent = bus->self->bus;
-
-       dbg("%s - enter", __FUNCTION__);
-
-       /* The cleanup code for proc entries regarding buses should be in the kernel... */
-       if(bus->procdir)
-               dbg("detach_pci_bus %s", bus->procdir->name);
-       pci_proc_detach_bus(bus);
-
-       /* The cleanup code should live in the kernel... */
-       bus->self->subordinate = NULL;
-
-       /* unlink from parent bus */
-       list_del(&bus->node);
-
-       /* Now, remove */
-       if(bus)
-               kfree(bus);
-
-       /* Update parent's subordinate field */
-       if(parent) {
-               u8 n = pci_bus_max_busnr(parent);
-               if(n < parent->subordinate) {
-                       parent->subordinate = n;
-                       pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
-               }
-       }
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
-}
-
-static struct pci_visit configure_functions = {
-       .visit_pci_dev = configure_visit_pci_dev,
-};
-
-static struct pci_visit unconfigure_functions_phase2 = {
-       .post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
-       .post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
-};
-
-
 int cpci_configure_slot(struct slot* slot)
 {
-       int rc = 0;
+       unsigned char busnr;
+       struct pci_bus *child;
 
        dbg("%s - enter", __FUNCTION__);
 
-       if(slot->dev == NULL) {
+       if (slot->dev == NULL) {
                dbg("pci_dev null, finding %02x:%02x:%x",
                    slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
-               slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
+               slot->dev = pci_get_slot(slot->bus, slot->devfn);
        }
 
        /* Still NULL? Well then scan for it! */
-       if(slot->dev == NULL) {
+       if (slot->dev == NULL) {
                int n;
                dbg("pci_dev still null");
 
@@ -583,79 +277,50 @@ int cpci_configure_slot(struct slot* slot)
                 */
                n = pci_scan_slot(slot->bus, slot->devfn);
                dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n);
-               if(n > 0)
+               if (n > 0)
                        pci_bus_add_devices(slot->bus);
-               slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
-               if(slot->dev == NULL) {
+               slot->dev = pci_get_slot(slot->bus, slot->devfn);
+               if (slot->dev == NULL) {
                        err("Could not find PCI device for slot %02x", slot->number);
-                       return 0;
+                       return 1;
                }
        }
-       dbg("slot->dev = %p", slot->dev);
-       if(slot->dev) {
-               struct pci_dev *dev;
-               struct pci_dev_wrapped wrapped_dev;
-               struct pci_bus_wrapped wrapped_bus;
-               int i;
-
-               memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-               memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
-
-               for (i = 0; i < 8; i++) {
-                       dev = pci_find_slot(slot->bus->number,
-                                           PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
-                       if(!dev)
-                               continue;
-                       wrapped_dev.dev = dev;
-                       wrapped_bus.bus = slot->dev->bus;
-                       if(i)
-                               wrapped_dev.data = NULL;
-                       else
-                               wrapped_dev.data = (void*) slot;
-                       rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
-               }
+
+       if (slot->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+               pci_read_config_byte(slot->dev, PCI_SECONDARY_BUS, &busnr);
+               child = pci_add_new_bus(slot->dev->bus, slot->dev, busnr);
+               pci_do_scan_bus(child);
+               pci_bus_size_bridges(child);
        }
 
-       dbg("%s - exit, rc = %d", __FUNCTION__, rc);
-       return rc;
+       pci_bus_assign_resources(slot->dev->bus);
+
+       dbg("%s - exit", __FUNCTION__);
+       return 0;
 }
 
 int cpci_unconfigure_slot(struct slot* slot)
 {
-       int rc = 0;
        int i;
-       struct pci_dev_wrapped wrapped_dev;
-       struct pci_bus_wrapped wrapped_bus;
        struct pci_dev *dev;
 
        dbg("%s - enter", __FUNCTION__);
-
-       if(!slot->dev) {
+       if (!slot->dev) {
                err("No device for slot %02x\n", slot->number);
                return -ENODEV;
        }
 
-       memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-       memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
-
        for (i = 0; i < 8; i++) {
-               dev = pci_find_slot(slot->bus->number,
+               dev = pci_get_slot(slot->bus,
                                    PCI_DEVFN(PCI_SLOT(slot->devfn), i));
-               if(dev) {
-                       wrapped_dev.dev = dev;
-                       wrapped_bus.bus = dev->bus;
-                       if(i)
-                               wrapped_dev.data = NULL;
-                       else
-                               wrapped_dev.data = (void*) slot;
-                       dbg("%s - unconfigure phase 2", __FUNCTION__);
-                       rc = pci_visit_dev(&unconfigure_functions_phase2,
-                                          &wrapped_dev,
-                                          &wrapped_bus);
-                       if(rc)
-                               break;
+               if (dev) {
+                       pci_remove_bus_device(dev);
+                       pci_dev_put(dev);
                }
        }
-       dbg("%s - exit, rc = %d", __FUNCTION__, rc);
-       return rc;
+       pci_dev_put(slot->dev);
+       slot->dev = NULL;
+
+       dbg("%s - exit", __FUNCTION__);
+       return 0;
 }
index 5bc039da647f1e36f6d450a2bb7f8ecb07ab7e96..c22e0284d7b143fb9588182e15010788b9142ebe 100644 (file)
@@ -196,7 +196,7 @@ struct ebda_hpc_bus {
 
 
 /********************************************************************
-*   THREE TYPE OF HOT PLUG CONTROLER                                *
+*   THREE TYPE OF HOT PLUG CONTROLLER                                *
 ********************************************************************/
 
 struct isa_ctlr_access {
index 6894b548c8cab0a0a9847cee6f6b03fd5808b2a6..1a3eb8d3d4cbd8b5bbeeb277a14124a992e5c7f2 100644 (file)
@@ -64,7 +64,7 @@ static int to_debug = FALSE;
 #define WPG_I2C_OR             0x2000  // I2C OR operation
 
 //----------------------------------------------------------------------------
-// Command set for I2C Master Operation Setup Regisetr
+// Command set for I2C Master Operation Setup Register
 //----------------------------------------------------------------------------
 #define WPG_READATADDR_MASK    0x00010000      // read,bytes,I2C shifted,index
 #define WPG_WRITEATADDR_MASK   0x40010000      // write,bytes,I2C shifted,index
@@ -835,7 +835,7 @@ static void poll_hpc (void)
                if (ibmphp_shutdown) 
                        break;
                
-               /* try to get the lock to do some kind of harware access */
+               /* try to get the lock to do some kind of hardware access */
                down (&semOperations);
 
                switch (poll_state) {
@@ -906,7 +906,7 @@ static void poll_hpc (void)
                                poll_state = POLL_LATCH_REGISTER;
                        break;
                }       
-               /* give up the harware semaphore */
+               /* give up the hardware semaphore */
                up (&semOperations);
                /* sleep for a short time just for good measure */
                msleep(100);
index 2335fac65fb4eee0456837e97d9cd99e5adec341..8122fe734aa78d40cd23ea6bd236dcbb040a0bcb 100644 (file)
@@ -1308,10 +1308,10 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
                        /* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
                } else {
                        /* This is Memory */
-                       start_address &= PCI_BASE_ADDRESS_MEM_MASK;
                        if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
                                /* pfmem */
                                debug ("start address of pfmem is %x\n", start_address);
+                               start_address &= PCI_BASE_ADDRESS_MEM_MASK;
 
                                if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
                                        err ("cannot find corresponding PFMEM resource to remove\n");
@@ -1325,6 +1325,8 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
                        } else {
                                /* regular memory */
                                debug ("start address of mem is %x\n", start_address);
+                               start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+
                                if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
                                        err ("cannot find corresponding MEM resource to remove\n");
                                        return -EIO;
@@ -1422,9 +1424,9 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
                        /* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
                } else {
                        /* This is Memory */
-                       start_address &= PCI_BASE_ADDRESS_MEM_MASK;
                        if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
                                /* pfmem */
+                               start_address &= PCI_BASE_ADDRESS_MEM_MASK;
                                if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
                                        err ("cannot find corresponding PFMEM resource to remove\n");
                                        return -EINVAL;
@@ -1436,6 +1438,7 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
                                }
                        } else {
                                /* regular memory */
+                               start_address &= PCI_BASE_ADDRESS_MEM_MASK;
                                if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
                                        err ("cannot find corresponding MEM resource to remove\n");
                                        return -EINVAL;
index 57ace325168dfd5fc569a2a18b7a2b3cc16f3ed4..88d44f7fef2908424ca87d67793d1cf78a9c9d4f 100644 (file)
@@ -150,7 +150,7 @@ struct hotplug_slot_info {
  * @name: the name of the slot being registered.  This string must
  * be unique amoung slots registered on this system.
  * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
- * @info: pointer to the &struct hotplug_slot_info for the inital values for
+ * @info: pointer to the &struct hotplug_slot_info for the initial values for
  * this slot.
  * @release: called during pci_hp_deregister to free memory allocated in a
  * hotplug_slot structure.
index f313121d51414d9a3f12bf26bea28a6bfe0b2bcc..46b294a12418a65eb58055c2535a9e2f23bd39d5 100644 (file)
@@ -130,6 +130,7 @@ struct controller {
        u8 slot_bus;            /* Bus where the slots handled by this controller sit */
        u8 ctrlcap;
        u16 vendor_id;
+       u8 cap_base;
 };
 
 struct irq_mapping {
index 72baf749e65ef812d8e7f6ed69fba0b44cfc7d58..df4915dbc321ca21622dd187b1a8ebc852b5bfae 100644 (file)
@@ -90,6 +90,22 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
        .get_cur_bus_speed =    get_cur_bus_speed,
 };
 
+/**
+ * release_slot - free up the memory used by a slot
+ * @hotplug_slot: slot to free
+ */
+static void release_slot(struct hotplug_slot *hotplug_slot)
+{
+       struct slot *slot = hotplug_slot->private;
+
+       dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+       kfree(slot->hotplug_slot->info);
+       kfree(slot->hotplug_slot->name);
+       kfree(slot->hotplug_slot);
+       kfree(slot);
+}
+
 static int init_slots(struct controller *ctrl)
 {
        struct slot *new_slot;
@@ -139,7 +155,8 @@ static int init_slots(struct controller *ctrl)
 
                /* register this slot with the hotplug pci core */
                new_slot->hotplug_slot->private = new_slot;
-               make_slot_name (new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
+               new_slot->hotplug_slot->release = &release_slot;
+               make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
                new_slot->hotplug_slot->ops = &pciehp_hotplug_slot_ops;
 
                new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status));
@@ -188,10 +205,6 @@ static int cleanup_slots (struct controller * ctrl)
        while (old_slot) {
                next_slot = old_slot->next;
                pci_hp_deregister (old_slot->hotplug_slot);
-               kfree(old_slot->hotplug_slot->info);
-               kfree(old_slot->hotplug_slot->name);
-               kfree(old_slot->hotplug_slot);
-               kfree(old_slot);
                old_slot = next_slot;
        }
 
@@ -594,7 +607,7 @@ static int pciehp_resume (struct pcie_device *dev)
 static struct pcie_port_service_id port_pci_ids[] = { { 
        .vendor = PCI_ANY_ID, 
        .device = PCI_ANY_ID,
-       .port_type = PCIE_RC_PORT, 
+       .port_type = PCIE_ANY_PORT,
        .service_type = PCIE_PORT_SERVICE_HP,
        .driver_data =  0, 
        }, { /* end: all zeroes */ }
index 9e70c4681f77e57d782116ce6d74afb3729c7ceb..1cda30bd6e47c90020fec4290f15aee624f95a4f 100644 (file)
@@ -109,20 +109,20 @@ enum ctrl_offsets {
 };
 static int pcie_cap_base = 0;          /* Base of the PCI Express capability item structure */ 
 
-#define PCIE_CAP_ID    ( pcie_cap_base + PCIECAPID )
-#define NXT_CAP_PTR    ( pcie_cap_base + NXTCAPPTR )
-#define CAP_REG                ( pcie_cap_base + CAPREG )
-#define DEV_CAP                ( pcie_cap_base + DEVCAP )
-#define DEV_CTRL       ( pcie_cap_base + DEVCTRL )
-#define DEV_STATUS     ( pcie_cap_base + DEVSTATUS )
-#define LNK_CAP                ( pcie_cap_base + LNKCAP )
-#define LNK_CTRL       ( pcie_cap_base + LNKCTRL )
-#define LNK_STATUS     ( pcie_cap_base + LNKSTATUS )
-#define SLOT_CAP       ( pcie_cap_base + SLOTCAP )
-#define SLOT_CTRL      ( pcie_cap_base + SLOTCTRL )
-#define SLOT_STATUS    ( pcie_cap_base + SLOTSTATUS )
-#define ROOT_CTRL      ( pcie_cap_base + ROOTCTRL )
-#define ROOT_STATUS    ( pcie_cap_base + ROOTSTATUS )
+#define PCIE_CAP_ID(cb)        ( cb + PCIECAPID )
+#define NXT_CAP_PTR(cb)        ( cb + NXTCAPPTR )
+#define CAP_REG(cb)    ( cb + CAPREG )
+#define DEV_CAP(cb)    ( cb + DEVCAP )
+#define DEV_CTRL(cb)   ( cb + DEVCTRL )
+#define DEV_STATUS(cb) ( cb + DEVSTATUS )
+#define LNK_CAP(cb)    ( cb + LNKCAP )
+#define LNK_CTRL(cb)   ( cb + LNKCTRL )
+#define LNK_STATUS(cb) ( cb + LNKSTATUS )
+#define SLOT_CAP(cb)   ( cb + SLOTCAP )
+#define SLOT_CTRL(cb)  ( cb + SLOTCTRL )
+#define SLOT_STATUS(cb)        ( cb + SLOTSTATUS )
+#define ROOT_CTRL(cb)  ( cb + ROOTCTRL )
+#define ROOT_STATUS(cb)        ( cb + ROOTSTATUS )
 
 #define hp_register_read_word(pdev, reg , value)               \
        pci_read_config_word(pdev, reg, &value)
@@ -303,7 +303,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
        if (retval) {
                        err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                        return retval;
@@ -317,7 +317,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
        }
 
        dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
-       retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE);
+       retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
        if (retval) {
                err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
@@ -342,7 +342,7 @@ static int hpc_check_lnk_status(struct controller *ctrl)
                return -1;
        }
        
-       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status);
 
        if (retval) {
                err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
@@ -376,14 +376,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
        }
 
-       dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL, slot_ctrl);
+       dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
 
@@ -423,13 +423,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
        }
-       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
+       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
 
@@ -463,7 +463,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
@@ -490,7 +490,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
@@ -518,7 +518,7 @@ static int hpc_query_power_fault(struct slot * slot)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
@@ -549,7 +549,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
                err("%s: Invalid HPC slot number!\n", __FUNCTION__);
                return -1;
        }
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
@@ -574,7 +574,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
                slot_cmd = slot_cmd | HP_INTR_ENABLE; 
 
        pcie_write_cmd(slot, slot_cmd);
-       dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
        
        return rc;
 }
@@ -598,7 +598,7 @@ static void hpc_set_green_led_on(struct slot *slot)
                return ;
        }
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
@@ -611,7 +611,7 @@ static void hpc_set_green_led_on(struct slot *slot)
 
        pcie_write_cmd(slot, slot_cmd);
 
-       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
        return;
 }
 
@@ -633,7 +633,7 @@ static void hpc_set_green_led_off(struct slot *slot)
                return ;
        }
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
@@ -646,7 +646,7 @@ static void hpc_set_green_led_off(struct slot *slot)
        if (!pciehp_poll_mode)
                slot_cmd = slot_cmd | HP_INTR_ENABLE; 
        pcie_write_cmd(slot, slot_cmd);
-       dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
 
        return;
 }
@@ -669,7 +669,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
                return ;
        }
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
@@ -683,7 +683,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
                slot_cmd = slot_cmd | HP_INTR_ENABLE; 
        pcie_write_cmd(slot, slot_cmd);
 
-       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
        return;
 }
 
@@ -707,7 +707,7 @@ int pcie_get_ctlr_slot_config(struct controller *ctrl,
        *first_device_num = 0;
        *num_ctlr_slots = 1; 
 
-       rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
+       rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
 
        if (rc) {
                err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);
@@ -793,13 +793,13 @@ static int hpc_power_on_slot(struct slot * slot)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
        }
-       dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL
+       dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
                slot_ctrl);
 
        slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
@@ -813,7 +813,7 @@ static int hpc_power_on_slot(struct slot * slot)
                err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
                return -1;
        }
-       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
 
        DBG_LEAVE_ROUTINE
 
@@ -842,13 +842,13 @@ static int hpc_power_off_slot(struct slot * slot)
                err("%s: Invalid HPC slot number!\n", __FUNCTION__);
                return -1;
        }
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
        }
-       dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL
+       dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
                slot_ctrl);
 
        slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
@@ -862,7 +862,7 @@ static int hpc_power_off_slot(struct slot * slot)
                err("%s: Write command failed!\n", __FUNCTION__);
                return -1;
        }
-       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
 
        DBG_LEAVE_ROUTINE
 
@@ -900,7 +900,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                return IRQ_NONE;
        }
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
        if (rc) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                return IRQ_NONE;
@@ -918,7 +918,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
        dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
        /* Mask Hot-plug Interrupt Enable */
        if (!pciehp_poll_mode) {
-               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
+               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -928,14 +928,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
                temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
 
-               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
+               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                        return IRQ_NONE;
                }
                dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
                
-               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
                if (rc) {
                        err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -944,7 +944,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                
                /* Clear command complete interrupt caused by this write */
                temp_word = 0x1f;
-               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -975,14 +975,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
 
        /* Clear all events after serving them */
        temp_word = 0x1F;
-       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                return IRQ_NONE;
        }
        /* Unmask Hot-plug Interrupt Enable */
        if (!pciehp_poll_mode) {
-               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
+               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -992,14 +992,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
                temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
 
-               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
+               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                        return IRQ_NONE;
                }
                dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);   
        
-               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
                if (rc) {
                        err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -1008,7 +1008,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                
                /* Clear command complete interrupt caused by this write */
                temp_word = 0x1F;
-               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -1038,7 +1038,7 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
                return -1;
        }
 
-       retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
+       retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
 
        if (retval) {
                err("%s : hp_register_read_dword  LNK_CAP failed\n", __FUNCTION__);
@@ -1079,7 +1079,7 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value
                return -1;
        }
 
-       retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
+       retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
 
        if (retval) {
                err("%s : hp_register_read_dword  LNK_CAP failed\n", __FUNCTION__);
@@ -1141,7 +1141,7 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
 
        if (retval) {
                err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
@@ -1182,7 +1182,7 @@ static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
 
        if (retval) {
                err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
@@ -1292,47 +1292,48 @@ int pcie_init(struct controller * ctrl,
                goto abort_free_ctlr;
        }
 
-       pcie_cap_base = cap_base;
+       ctrl->cap_base = cap_base;
 
        dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base);
 
-       rc = hp_register_read_word(pdev, CAP_REG, cap_reg);
+       rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg);
        if (rc) {
                err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG, cap_reg);
+       dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg);
 
-       if (((cap_reg & SLOT_IMPL) == 0) || ((cap_reg & DEV_PORT_TYPE) != 0x0040)){
+       if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040)
+               && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) {
                dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
 
-       rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
+       rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
        if (rc) {
                err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP, slot_cap);
+       dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap);
 
        if (!(slot_cap & HP_CAP)) {
                dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
        /* For debugging purpose */
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
        if (rc) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
+       dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status);
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
+       dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
 
        if (first) {
                spin_lock_init(&hpc_event_lock);
@@ -1372,36 +1373,37 @@ int pcie_init(struct controller * ctrl,
        php_ctlr->num_slots = 1;
 
        /* Mask Hot-plug Interrupt Enable */
-       rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
+       rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
 
-       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
+       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
        temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
 
-       rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
+       rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
        dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
        if (rc) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
+       dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base)
+               , slot_status);
 
        temp_word = 0x1F; /* Clear all events */
-       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
+       dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
 
        if (pciehp_poll_mode)  {/* Install interrupt polling code */
                /* Install and start the interrupt polling timer */
@@ -1417,12 +1419,12 @@ int pcie_init(struct controller * ctrl,
                }
        }
 
-       rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
+       rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
+       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
        dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
 
        intr_enable = intr_enable | PRSN_DETECT_ENABLE;
@@ -1446,27 +1448,27 @@ int pcie_init(struct controller * ctrl,
        dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
 
        /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
-       rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
+       rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
        dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
        if (rc) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
        dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, 
-               SLOT_STATUS, slot_status);
+               SLOT_STATUS(ctrl->cap_base), slot_status);
        
        temp_word =  0x1F; /* Clear all events */
-       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
+       dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
        
        /*  Add this HPC instance into the HPC list */
        spin_lock(&list_lock);
index 6605d6bda5291a525fdf6da450b689e8ea3d8ae5..3194d51c6ec9c6109b20a4eb7c5821d7010f2d3c 100644 (file)
@@ -297,7 +297,7 @@ static int __init init_slots(void)
                hotplug_slot->ops = &skel_hotplug_slot_ops;
                
                /*
-                * Initilize the slot info structure with some known
+                * Initialize the slot info structure with some known
                 * good values.
                 */
                info->power_status = get_power_status(slot);
index f0c53f850aedb12b2c7be0eeaeb5b39146b12eff..a70a5c5705f2dee83f0da960c3a836269735e43d 100644 (file)
@@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
  */
 static void release_slot(struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = (struct slot *)hotplug_slot->private;
+       struct slot *slot = hotplug_slot->private;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
index 9f90eb8e6ecd8302812dd90d5da19c8fffaf17cc..490a9553a0625175d7ba02783988f6915fbc57b7 100644 (file)
@@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot)
        func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
        if (!func) {
                dbg("%s: Error! slot NULL\n", __FUNCTION__);
-               return 1;
+               return -ENODEV;
        }
 
        /* Check to see if (latch closed, card present, power off) */
@@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot)
        if (rc || !getstatus) {
                info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
                up(&p_slot->ctrl->crit_sect);
-               return 1;
+               return -ENODEV;
        }
        rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
        if (rc || getstatus) {
                info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
                up(&p_slot->ctrl->crit_sect);
-               return 1;
+               return -ENODEV;
        }
        rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
        if (rc || getstatus) {
                info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
                up(&p_slot->ctrl->crit_sect);
-               return 1;
+               return -ENODEV;
        }
        up(&p_slot->ctrl->crit_sect);
 
@@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot)
 
        func = shpchp_slot_create(p_slot->bus);
        if (func == NULL)
-               return 1;
+               return -ENOMEM;
 
        func->bus = p_slot->bus;
        func->device = p_slot->device;
@@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot)
                /* Setup slot structure with entry for empty slot */
                func = shpchp_slot_create(p_slot->bus);
                if (func == NULL)
-                       return (1);     /* Out of memory */
+                       return -ENOMEM; /* Out of memory */
 
                func->bus = p_slot->bus;
                func->device = p_slot->device;
@@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot)
        struct pci_func *func;
 
        if (!p_slot->ctrl)
-               return 1;
+               return -ENODEV;
 
        pci_bus = p_slot->ctrl->pci_dev->subordinate;
 
@@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot)
        if (ret || !getstatus) {
                info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
                up(&p_slot->ctrl->crit_sect);
-               return 1;
+               return -ENODEV;
        }
        ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
        if (ret || getstatus) {
                info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
                up(&p_slot->ctrl->crit_sect);
-               return 1;
+               return -ENODEV;
        }
        ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
        if (ret || !getstatus) {
                info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
                up(&p_slot->ctrl->crit_sect);
-               return 1;
+               return -ENODEV;
        }
        up(&p_slot->ctrl->crit_sect);
 
@@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot)
                /* Check the Class Code */
                rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
                if (rc)
-                       return rc;
+                       return -ENODEV;
 
                if (class_code == PCI_BASE_CLASS_DISPLAY) {
                        /* Display/Video adapter (not supported) */
@@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot)
                        /* See if it's a bridge */
                        rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
                        if (rc)
-                               return rc;
+                               return -ENODEV;
 
                        /* If it's a bridge, check the VGA Enable bit */
                        if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
                                rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
                                if (rc)
-                                       return rc;
+                                       return -ENODEV;
 
                                /* If the VGA Enable bit is set, remove isn't supported */
                                if (BCR & PCI_BRIDGE_CTL_VGA) {
@@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot)
        if ((func != NULL) && !rc) {
                rc = remove_board(func, p_slot->ctrl);
        } else if (!rc)
-               rc = 1;
+               rc = -ENODEV;
 
        if (p_slot)
                update_slot_info(p_slot);
 
-       return(rc);
+       return rc;
 }
 
 
index 243a51d88b86844d75a7f2e84c7e3522c837a066..7957cdc72cd0464869096ffe9b59298953fdc539 100644 (file)
@@ -1626,7 +1626,7 @@ int shpchprm_set_hpp(
        pci_bus->number = func->bus;
        devfn = PCI_DEVFN(func->device, func->function);
 
-       ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
+       ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus);
 
        if (ab) {
                if (ab->_hpp) {
@@ -1681,7 +1681,7 @@ void shpchprm_enable_card(
                | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
        bcmd = bcommand  = bcommand | PCI_BRIDGE_CTL_NO_ISA;
 
-       ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
+       ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus);
        if (ab) {
                if (ab->_hpp) {
                        if (ab->_hpp->enable_perr) {
index 22ecd3b058be176a76683a87ae33eb1269ece88a..30206ac43c443c68eb6d89c8fc3146a6f0f307d7 100644 (file)
@@ -522,7 +522,7 @@ void pci_scan_msi_device(struct pci_dev *dev)
  * msi_capability_init - configure device's MSI capability structure
  * @dev: pointer to the pci_dev data structure of MSI device function
  *
- * Setup the MSI capability structure of device funtion with a single
+ * Setup the MSI capability structure of device function with a single
  * MSI vector, regardless of device function is capable of handling
  * multiple messages. A return of zero indicates the successful setup
  * of an entry zero with the new MSI vector or non-zero for otherwise.
@@ -599,7 +599,7 @@ static int msi_capability_init(struct pci_dev *dev)
  * msix_capability_init - configure device's MSI-X capability
  * @dev: pointer to the pci_dev data structure of MSI-X device function
  *
- * Setup the MSI-X capability structure of device funtion with a
+ * Setup the MSI-X capability structure of device function with a
  * single MSI-X vector. A return of zero indicates the successful setup of
  * requested MSI-X entries with allocated vectors or non-zero for otherwise.
  **/
@@ -1074,7 +1074,7 @@ void pci_disable_msix(struct pci_dev* dev)
  * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state
  * @dev: pointer to the pci_dev data structure of MSI(X) device function
  *
- * Being called during hotplug remove, from which the device funciton
+ * Being called during hotplug remove, from which the device function
  * is hot-removed. All previous assigned MSI/MSI-X vectors, if
  * allocated for this device function, are reclaimed to unused state,
  * which may be used later on.
index 968eb32f292d7e075bb982359d9d7332a5f93f15..bc01d34e2634ca12b582e8b42c8dab7aee01da79 100644 (file)
@@ -19,7 +19,7 @@
 
 static u32 ctrlset_buf[3] = {0, 0, 0};
 static u32 global_ctrlsets = 0;
-u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
+static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
 
 static acpi_status  
 acpi_query_osc (
index 37b7961efc44a93fff15ee41c125be1e71c5d9e5..fe98553c978f335dae47646cee5df32c8f69b42e 100644 (file)
@@ -318,6 +318,14 @@ static int pci_device_resume(struct device * dev)
        return 0;
 }
 
+static void pci_device_shutdown(struct device *dev)
+{
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+       struct pci_driver *drv = pci_dev->driver;
+
+       if (drv && drv->shutdown)
+               drv->shutdown(pci_dev);
+}
 
 #define kobj_to_pci_driver(obj) container_of(obj, struct device_driver, kobj)
 #define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
@@ -373,7 +381,7 @@ pci_populate_driver_dir(struct pci_driver *drv)
  * 
  * Adds the driver structure to the list of registered drivers.
  * Returns a negative value on error, otherwise 0. 
- * If no error occured, the driver remains registered even if 
+ * If no error occurred, the driver remains registered even if 
  * no device was claimed during registration.
  */
 int pci_register_driver(struct pci_driver *drv)
@@ -385,6 +393,7 @@ int pci_register_driver(struct pci_driver *drv)
        drv->driver.bus = &pci_bus_type;
        drv->driver.probe = pci_device_probe;
        drv->driver.remove = pci_device_remove;
+       drv->driver.shutdown = pci_device_shutdown,
        drv->driver.owner = drv->owner;
        drv->driver.kobj.ktype = &pci_driver_kobj_type;
        pci_init_dynids(&drv->dynids);
index d57ae71d32b1dd42a77689498e691263d263c3e4..6ca0061137a6937891fb1757699e010abec9d688 100644 (file)
@@ -73,6 +73,17 @@ resource_show(struct device * dev, char * buf)
        return (str - buf);
 }
 
+static ssize_t modalias_show(struct device *dev, char *buf)
+{
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+
+       return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
+                      pci_dev->vendor, pci_dev->device,
+                      pci_dev->subsystem_vendor, pci_dev->subsystem_device,
+                      (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
+                      (u8)(pci_dev->class));
+}
+
 struct device_attribute pci_dev_attrs[] = {
        __ATTR_RO(resource),
        __ATTR_RO(vendor),
@@ -82,6 +93,7 @@ struct device_attribute pci_dev_attrs[] = {
        __ATTR_RO(class),
        __ATTR_RO(irq),
        __ATTR_RO(local_cpus),
+       __ATTR_RO(modalias),
        __ATTR_NULL,
 };
 
@@ -91,6 +103,7 @@ pci_read_config(struct kobject *kobj, 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;
        loff_t init_off = off;
+       u8 *data = (u8*) buf;
 
        /* Several chips lock up trying to read undefined config space */
        if (capable(CAP_SYS_ADMIN)) {
@@ -108,30 +121,47 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
                size = count;
        }
 
-       while (off & 3) {
-               unsigned char val;
+       if ((off & 1) && size) {
+               u8 val;
                pci_read_config_byte(dev, off, &val);
-               buf[off - init_off] = val;
+               data[off - init_off] = val;
                off++;
-               if (--size == 0)
-                       break;
+               size--;
+       }
+
+       if ((off & 3) && size > 2) {
+               u16 val;
+               pci_read_config_word(dev, off, &val);
+               data[off - init_off] = val & 0xff;
+               data[off - init_off + 1] = (val >> 8) & 0xff;
+               off += 2;
+               size -= 2;
        }
 
        while (size > 3) {
-               unsigned int val;
+               u32 val;
                pci_read_config_dword(dev, off, &val);
-               buf[off - init_off] = val & 0xff;
-               buf[off - init_off + 1] = (val >> 8) & 0xff;
-               buf[off - init_off + 2] = (val >> 16) & 0xff;
-               buf[off - init_off + 3] = (val >> 24) & 0xff;
+               data[off - init_off] = val & 0xff;
+               data[off - init_off + 1] = (val >> 8) & 0xff;
+               data[off - init_off + 2] = (val >> 16) & 0xff;
+               data[off - init_off + 3] = (val >> 24) & 0xff;
                off += 4;
                size -= 4;
        }
 
-       while (size > 0) {
-               unsigned char val;
+       if (size >= 2) {
+               u16 val;
+               pci_read_config_word(dev, off, &val);
+               data[off - init_off] = val & 0xff;
+               data[off - init_off + 1] = (val >> 8) & 0xff;
+               off += 2;
+               size -= 2;
+       }
+
+       if (size > 0) {
+               u8 val;
                pci_read_config_byte(dev, off, &val);
-               buf[off - init_off] = val;
+               data[off - init_off] = val;
                off++;
                --size;
        }
@@ -145,6 +175,7 @@ pci_write_config(struct kobject *kobj, 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;
        loff_t init_off = off;
+       u8 *data = (u8*) buf;
 
        if (off > dev->cfg_size)
                return 0;
@@ -152,26 +183,41 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
                size = dev->cfg_size - off;
                count = size;
        }
-
-       while (off & 3) {
-               pci_write_config_byte(dev, off, buf[off - init_off]);
+       
+       if ((off & 1) && size) {
+               pci_write_config_byte(dev, off, data[off - init_off]);
                off++;
-               if (--size == 0)
-                       break;
+               size--;
        }
+       
+       if ((off & 3) && size > 2) {
+               u16 val = data[off - init_off];
+               val |= (u16) data[off - init_off + 1] << 8;
+                pci_write_config_word(dev, off, val);
+                off += 2;
+                size -= 2;
+        }
 
        while (size > 3) {
-               unsigned int val = buf[off - init_off];
-               val |= (unsigned int) buf[off - init_off + 1] << 8;
-               val |= (unsigned int) buf[off - init_off + 2] << 16;
-               val |= (unsigned int) buf[off - init_off + 3] << 24;
+               u32 val = data[off - init_off];
+               val |= (u32) data[off - init_off + 1] << 8;
+               val |= (u32) data[off - init_off + 2] << 16;
+               val |= (u32) data[off - init_off + 3] << 24;
                pci_write_config_dword(dev, off, val);
                off += 4;
                size -= 4;
        }
+       
+       if (size >= 2) {
+               u16 val = data[off - init_off];
+               val |= (u16) data[off - init_off + 1] << 8;
+               pci_write_config_word(dev, off, val);
+               off += 2;
+               size -= 2;
+       }
 
-       while (size > 0) {
-               pci_write_config_byte(dev, off, buf[off - init_off]);
+       if (size) {
+               pci_write_config_byte(dev, off, data[off - init_off]);
                off++;
                --size;
        }
index bfbff83352688dc99776706033e1bb80b8282946..f04b9ffe41539a1a2a1acafa6ea5d16b15fbd64b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <asm/dma.h>   /* isa_dma_bridge_buggy */
+#include "pci.h"
 
 
 /**
@@ -398,10 +399,10 @@ pci_enable_device(struct pci_dev *dev)
 {
        int err;
 
-       dev->is_enabled = 1;
        if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1)))
                return err;
        pci_fixup_device(pci_fixup_enable, dev);
+       dev->is_enabled = 1;
        return 0;
 }
 
@@ -427,16 +428,15 @@ pci_disable_device(struct pci_dev *dev)
 {
        u16 pci_command;
        
-       dev->is_enabled = 0;
-       dev->is_busmaster = 0;
-
        pci_read_config_word(dev, PCI_COMMAND, &pci_command);
        if (pci_command & PCI_COMMAND_MASTER) {
                pci_command &= ~PCI_COMMAND_MASTER;
                pci_write_config_word(dev, PCI_COMMAND, pci_command);
        }
+       dev->is_busmaster = 0;
 
        pcibios_disable_device(dev);
+       dev->is_enabled = 0;
 }
 
 /**
@@ -748,17 +748,6 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask)
        return 0;
 }
     
-int
-pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
-       if (!pci_dac_dma_supported(dev, mask))
-               return -EIO;
-
-       dev->dma_mask = mask;
-
-       return 0;
-}
-
 int
 pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
 {
@@ -821,7 +810,6 @@ EXPORT_SYMBOL(pci_set_master);
 EXPORT_SYMBOL(pci_set_mwi);
 EXPORT_SYMBOL(pci_clear_mwi);
 EXPORT_SYMBOL(pci_set_dma_mask);
-EXPORT_SYMBOL(pci_dac_set_dma_mask);
 EXPORT_SYMBOL(pci_set_consistent_dma_mask);
 EXPORT_SYMBOL(pci_assign_resource);
 EXPORT_SYMBOL(pci_find_parent_resource);
index 79cdc16c52c826b7a1633de4dfb634c6f9f3b8f3..744da0d4ae5f90614a1f719299d23e23854c749e 100644 (file)
@@ -32,33 +32,6 @@ extern unsigned char pci_max_busnr(void);
 extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);
 extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
 
-struct pci_dev_wrapped {
-       struct pci_dev  *dev;
-       void            *data;
-};
-
-struct pci_bus_wrapped {
-       struct pci_bus  *bus;
-       void            *data;
-};
-
-struct pci_visit {
-       int (* pre_visit_pci_bus)       (struct pci_bus_wrapped *,
-                                        struct pci_dev_wrapped *);
-       int (* post_visit_pci_bus)      (struct pci_bus_wrapped *,
-                                        struct pci_dev_wrapped *);
-
-       int (* pre_visit_pci_dev)       (struct pci_dev_wrapped *,
-                                        struct pci_bus_wrapped *);
-       int (* visit_pci_dev)           (struct pci_dev_wrapped *,
-                                        struct pci_bus_wrapped *);
-       int (* post_visit_pci_dev)      (struct pci_dev_wrapped *,
-                                        struct pci_bus_wrapped *);
-};
-
-extern int pci_visit_dev(struct pci_visit *fn,
-                        struct pci_dev_wrapped *wrapped_dev,
-                        struct pci_bus_wrapped *wrapped_parent);
 extern void pci_remove_legacy_files(struct pci_bus *bus);
 
 /* Lock for read/write access to pci device and bus lists */
index 93481b41b613e33b75f1b494074372c80fe299cd..1d2ef1e2ffc6178398c2347b3b4295fee763dda1 100644 (file)
        080f  Sentry5 DDR/SDR RAM Controller
        0811  Sentry5 External Interface Core
        0816  BCM3302 Sentry5 MIPS32 CPU
+       1600  NetXtreme BCM5752 Gigabit Ethernet PCI Express
        1644  NetXtreme BCM5700 Gigabit Ethernet
                1014 0277  Broadcom Vigil B5700 1000Base-T
                1028 00d1  Broadcom BCM5700
index 4037a3e568de9d97043a946e6eb936f914de27cb..3e84b501e6a419ea2b7e28452983c36a8a127bff 100644 (file)
@@ -39,7 +39,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
                driver->id_table->vendor != pciedev->id.vendor) ||
               (driver->id_table->device != PCI_ANY_ID &&
                driver->id_table->device != pciedev->id.device) ||      
-               driver->id_table->port_type != pciedev->id.port_type ||
+              (driver->id_table->port_type != PCIE_ANY_PORT &&
+               driver->id_table->port_type != pciedev->id.port_type) ||
                driver->id_table->service_type != pciedev->id.service_type )
                return 0;
 
index 6f0edadd132cfeee9f8327a4af8d178b7ad16353..fd48b201eb53ac18e443519c17046ba7b68bb94c 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/cpumask.h>
+#include "pci.h"
 
 #define CARDBUS_LATENCY_TIMER  176     /* secondary latency timer */
 #define CARDBUS_RESERVE_BUSNR  3
@@ -124,7 +125,7 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags)
 /*
  * Find the extent of a PCI decode..
  */
-static u32 pci_size(u32 base, u32 maxbase, unsigned long mask)
+static u32 pci_size(u32 base, u32 maxbase, u32 mask)
 {
        u32 size = mask & maxbase;      /* Find the significant bits */
        if (!size)
index 84cc4f620d8d4807db5830d4aa37f376bfa74463..e68bbfb1e7c318d0c34c11e3c76774ae17f3c60a 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
+#include "pci.h"
 
 static int proc_initialized;   /* = 0 */
 
index 15a398051682ae19334a358600ecee9b85f1a434..968033fd29f0bfc287a23399e5d6f9e2d8776f82 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/acpi.h>
+#include "pci.h"
 
 /* Deal with broken BIOS'es that neglect to enable passive release,
    which can cause problems in combination with the 82441FX/PPro MTRRs */
@@ -328,6 +330,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801CA_12,
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801DB_0,                quirk_ich4_lpc_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801DB_12,       quirk_ich4_lpc_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801EB_0,                quirk_ich4_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_ESB_1,            quirk_ich4_lpc_acpi );
 
 /*
  * VIA ACPI: One IO region pointed to by longword at
@@ -453,23 +456,15 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
 } 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC,         quirk_amd_8131_ioapic ); 
 
+static void __init quirk_svw_msi(struct pci_dev *dev)
+{
+       pci_msi_quirk = 1;
+       printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n");
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi );
 #endif /* CONFIG_X86_IO_APIC */
 
 
-/*
- * Via 686A/B:  The PCI_INTERRUPT_LINE register for the on-chip
- * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
- * when written, it makes an internal connection to the PIC.
- * For these devices, this register is defined to be 4 bits wide.
- * Normally this is fine.  However for IO-APIC motherboards, or
- * non-x86 architectures (yes Via exists on PPC among other places),
- * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
- * interrupts delivered properly.
- *
- * TODO: When we have device-specific interrupt routers,
- * quirk_via_irqpic will go away from quirks.
- */
-
 /*
  * FIXME: it is questionable that quirk_via_acpi
  * is needed.  It shows up as an ISA bridge, and does not
@@ -492,6 +487,31 @@ static void __devinit quirk_via_acpi(struct pci_dev *d)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C586_3,     quirk_via_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C686_4,     quirk_via_acpi );
 
+/*
+ * Via 686A/B:  The PCI_INTERRUPT_LINE register for the on-chip
+ * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
+ * when written, it makes an internal connection to the PIC.
+ * For these devices, this register is defined to be 4 bits wide.
+ * Normally this is fine.  However for IO-APIC motherboards, or
+ * non-x86 architectures (yes Via exists on PPC among other places),
+ * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
+ * interrupts delivered properly.
+ */
+static void quirk_via_irq(struct pci_dev *dev)
+{
+       u8 irq, new_irq;
+
+       new_irq = dev->irq & 0xf;
+       pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+       if (new_irq != irq) {
+               printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n",
+                       pci_name(dev), irq, new_irq);
+               udelay(15);     /* unknown if delay really needed */
+               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
+       }
+}
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
+
 /*
  * PIIX3 USB: We have to disable USB interrupts that are
  * hardwired to PIRQD# and may be shared with an
@@ -681,19 +701,6 @@ static void __init quirk_disable_pxb(struct pci_dev *pdev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82454NX,    quirk_disable_pxb );
 
-/*
- *     VIA northbridges care about PCI_INTERRUPT_LINE
- */
-int via_interrupt_line_quirk;
-
-static void __devinit quirk_via_bridge(struct pci_dev *pdev)
-{
-       if(pdev->devfn == 0) {
-               printk(KERN_INFO "PCI: Via IRQ fixup\n");
-               via_interrupt_line_quirk = 1;
-       }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_ANY_ID,                     quirk_via_bridge );
 
 /*
  *     Serverworks CSB5 IDE does not fully support native mode
index 66150d08b5c7c6d470c83a723559504b9b40dc70..c4ade288c5da6dcdcb497882f1dd1f8b659c29f4 100644 (file)
@@ -1592,9 +1592,9 @@ static int __init init_pcmcia_bus(void)
 
        /* Set up character device for user mode clients */
        i = register_chrdev(0, "pcmcia", &ds_fops);
-       if (i == -EBUSY)
+       if (i < 0)
                printk(KERN_NOTICE "unable to find a free device # for "
-                      "Driver Services\n");
+                      "Driver Services (error=%d)\n", i);
        else
                major_dev = i;
 
index 3f4364341d8d0a0be3289d01a57a1a7c24c73242..20642f0e7bfe85f1b252099e18420d48a0b7c1b4 100644 (file)
@@ -744,7 +744,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
 
        for (i = 0; i < MAX_SOCKETS; i++) {
                socket[i].io_base = pci_resource_start(dev, 0);
-               socket[i].socket.features |= SS_CAP_PCCARD;
+               socket[i].socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
                socket[i].socket.map_size = 0x1000;
                socket[i].socket.irq_mask = mask;
                socket[i].socket.pci_irq  = dev->irq;
index 52c073a9d7e4463ceee2db044ed85d2faf09e62b..a8a1d104524a5c261decbaed8c896a18a52461e6 100644 (file)
@@ -442,6 +442,25 @@ out:
 }
 
 
+/* changes the irq of func1 to match that of func0 */
+static int ti12xx_align_irqs(struct yenta_socket *socket, int *old_irq)
+{
+       struct pci_dev *func0;
+
+       /* find func0 device */
+       func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
+       if (!func0)
+               return 0;
+
+       if (old_irq)
+               *old_irq = socket->cb_irq;
+       socket->cb_irq = socket->dev->irq = func0->irq;
+
+       pci_dev_put(func0);
+
+       return 1;
+}
+
 /*
  * ties INTA and INTB together. also changes the devices irq to that of
  * the function 0 device. call from func1 only.
@@ -449,26 +468,22 @@ out:
  */
 static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq)
 {
-       struct pci_dev *func0;
        u32 sysctl;
+       int ret;
 
        sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
        if (sysctl & TI122X_SCR_INTRTIE)
                return 0;
 
-       /* find func0 device */
-       func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
-       if (!func0)
+       /* align */
+       ret = ti12xx_align_irqs(socket, old_irq);
+       if (!ret)
                return 0;
 
-       /* change the interrupt to match func0, tie 'em up */
-       *old_irq = socket->cb_irq;
-       socket->cb_irq = socket->dev->irq = func0->irq;
+       /* tie */
        sysctl |= TI122X_SCR_INTRTIE;
        config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl);
 
-       pci_dev_put(func0);
-
        return 1;
 }
 
@@ -489,7 +504,7 @@ static void ti12xx_untie_interrupts(struct yenta_socket *socket, int old_irq)
  */
 static void ti12xx_irqroute_func1(struct yenta_socket *socket)
 {
-       u32 mfunc, mfunc_old, devctl;
+       u32 mfunc, mfunc_old, devctl, sysctl;
        int pci_irq_status;
 
        mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
@@ -497,6 +512,11 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
        printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
               pci_name(socket->dev), mfunc, devctl);
 
+       /* if IRQs are configured as tied, align irq of func1 with func0 */
+       sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+       if (sysctl & TI122X_SCR_INTRTIE)
+               ti12xx_align_irqs(socket, NULL);
+
        /* make sure PCI interrupts are enabled before probing */
        ti_init(socket);
 
index 02cfe244e069777219e3ef4450e05634badafcc9..ceeb3cf64a16ccc10aa521c550889fc0cad5edcd 100644 (file)
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.161 $
+ * $Revision: 1.164 $
  */
 
 #include <linux/config.h>
@@ -1766,10 +1766,10 @@ dasd_generic_probe (struct ccw_device *cdev,
                printk(KERN_WARNING
                       "dasd_generic_probe: could not add sysfs entries "
                       "for %s\n", cdev->dev.bus_id);
+       } else {
+               cdev->handler = &dasd_int_handler;
        }
 
-       cdev->handler = &dasd_int_handler;
-
        return ret;
 }
 
@@ -1780,6 +1780,8 @@ dasd_generic_remove (struct ccw_device *cdev)
 {
        struct dasd_device *device;
 
+       cdev->handler = NULL;
+
        dasd_remove_sysfs_files(cdev);
        device = dasd_device_from_cdev(cdev);
        if (IS_ERR(device))
@@ -1810,14 +1812,14 @@ dasd_generic_set_online (struct ccw_device *cdev,
        struct dasd_device *device;
        int feature_diag, rc;
 
-       feature_diag = dasd_get_feature(cdev, DASD_FEATURE_USEDIAG);
-       if (feature_diag < 0)
-               return feature_diag;
-
        device = dasd_create_device(cdev);
        if (IS_ERR(device))
                return PTR_ERR(device);
 
+       feature_diag = dasd_get_feature(cdev, DASD_FEATURE_USEDIAG);
+       if (feature_diag < 0)
+               return feature_diag;
+
        if (feature_diag) {
                if (!dasd_diag_discipline_pointer) {
                        printk (KERN_WARNING
index 7cabb80a2e4144ef77210e5576124009baa747f3..90d4d0ef3dd4d54f5b6563e24c68118c654aa74f 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
 obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
 obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o
 obj-$(CONFIG_LCS) += lcs.o cu3088.o
-qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o qeth_tso.o
+obj-$(CONFIG_CLAW) += claw.o cu3088.o
+qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o 
 qeth-$(CONFIG_PROC_FS) += qeth_proc.o
 obj-$(CONFIG_QETH) += qeth.o
index ef8883951720c27ea3aa3b1c0abacda934105c0c..7fe2ebd1792dc6de5cbe1ee4a30af420fd76d8fb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.4 $)
+ * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $)
  *
  * CTC / ESCON network driver - s390 dbf exploit.
  *
@@ -9,7 +9,7 @@
  *    Author(s): Original Code written by
  *                       Peter Tiedemann (ptiedem@de.ibm.com)
  *
- *    $Revision: 1.4 $  $Date: 2004/10/15 09:26:58 $
+ *    $Revision: 1.5 $  $Date: 2005/02/27 19:46:44 $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
+#ifndef _CTCDBUG_H_
+#define _CTCDBUG_H_
 
 #include <asm/debug.h>
+#include "ctcmain.h"
 /**
  * Debug Facility stuff
  */
@@ -41,7 +43,7 @@
 #define CTC_DBF_DATA_LEN 128
 #define CTC_DBF_DATA_INDEX 3
 #define CTC_DBF_DATA_NR_AREAS 1
-#define CTC_DBF_DATA_LEVEL 2
+#define CTC_DBF_DATA_LEVEL 3
 
 #define CTC_DBF_TRACE_NAME "ctc_trace"
 #define CTC_DBF_TRACE_LEN 16
@@ -121,3 +123,5 @@ hex_dump(unsigned char *buf, size_t len)
        printk("\n");
 }
 
+
+#endif
index 7266bf5ea6599f9734866b01383032636e4de96f..ff3e95e07e895dc73768f91fe01f93a1b87964c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.72 2005/03/17 10:51:52 ptiedem Exp $
+ * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $
  *
  * CTC / ESCON network driver
  *
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.72 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $
  *
  */
 \f
 #undef DEBUG
-
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include "ctctty.h"
 #include "fsm.h"
 #include "cu3088.h"
+
 #include "ctcdbug.h"
+#include "ctcmain.h"
 
 MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
 MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver");
 MODULE_LICENSE("GPL");
-
-/**
- * CCW commands, used in this driver.
- */
-#define CCW_CMD_WRITE          0x01
-#define CCW_CMD_READ           0x02
-#define CCW_CMD_SET_EXTENDED   0xc3
-#define CCW_CMD_PREPARE                0xe3
-
-#define CTC_PROTO_S390          0
-#define CTC_PROTO_LINUX         1
-#define CTC_PROTO_LINUX_TTY     2
-#define CTC_PROTO_OS390         3
-#define CTC_PROTO_MAX           3
-
-#define CTC_BUFSIZE_LIMIT       65535
-#define CTC_BUFSIZE_DEFAULT     32768
-
-#define CTC_TIMEOUT_5SEC        5000
-
-#define CTC_INITIAL_BLOCKLEN    2
-
-#define READ                   0
-#define WRITE                  1
-
-#define CTC_ID_SIZE             BUS_ID_SIZE+3
-\f
-
-struct ctc_profile {
-       unsigned long maxmulti;
-       unsigned long maxcqueue;
-       unsigned long doios_single;
-       unsigned long doios_multi;
-       unsigned long txlen;
-       unsigned long tx_time;
-       struct timespec send_stamp;
-};
-
-/**
- * Definition of one channel
- */
-struct channel {
-
-       /**
-        * Pointer to next channel in list.
-        */
-       struct channel *next;
-       char id[CTC_ID_SIZE];
-       struct ccw_device *cdev;
-
-       /**
-        * Type of this channel.
-        * CTC/A or Escon for valid channels.
-        */
-       enum channel_types type;
-
-       /**
-        * Misc. flags. See CHANNEL_FLAGS_... below
-        */
-       __u32 flags;
-
-       /**
-        * The protocol of this channel
-        */
-       __u16 protocol;
-
-       /**
-        * I/O and irq related stuff
-        */
-       struct ccw1 *ccw;
-       struct irb *irb;
-
-       /**
-        * RX/TX buffer size
-        */
-       int max_bufsize;
-
-       /**
-        * Transmit/Receive buffer.
-        */
-       struct sk_buff *trans_skb;
-
-       /**
-        * Universal I/O queue.
-        */
-       struct sk_buff_head io_queue;
-
-       /**
-        * TX queue for collecting skb's during busy.
-        */
-       struct sk_buff_head collect_queue;
-
-       /**
-        * Amount of data in collect_queue.
-        */
-       int collect_len;
-
-       /**
-        * spinlock for collect_queue and collect_len
-        */
-       spinlock_t collect_lock;
-
-       /**
-        * Timer for detecting unresposive
-        * I/O operations.
-        */
-       fsm_timer timer;
-
-       /**
-        * Retry counter for misc. operations.
-        */
-       int retry;
-
-       /**
-        * The finite state machine of this channel
-        */
-       fsm_instance *fsm;
-
-       /**
-        * The corresponding net_device this channel
-        * belongs to.
-        */
-       struct net_device *netdev;
-
-       struct ctc_profile prof;
-
-       unsigned char *trans_skb_data;
-
-       __u16 logflags;
-};
-
-#define CHANNEL_FLAGS_READ            0
-#define CHANNEL_FLAGS_WRITE           1
-#define CHANNEL_FLAGS_INUSE           2
-#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4
-#define CHANNEL_FLAGS_FAILED          8
-#define CHANNEL_FLAGS_WAITIRQ        16
-#define CHANNEL_FLAGS_RWMASK 1
-#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)
-
-#define LOG_FLAG_ILLEGALPKT  1
-#define LOG_FLAG_ILLEGALSIZE 2
-#define LOG_FLAG_OVERRUN     4
-#define LOG_FLAG_NOMEM       8
-
-#define CTC_LOGLEVEL_INFO     1
-#define CTC_LOGLEVEL_NOTICE   2
-#define CTC_LOGLEVEL_WARN     4
-#define CTC_LOGLEVEL_EMERG    8
-#define CTC_LOGLEVEL_ERR     16
-#define CTC_LOGLEVEL_DEBUG   32
-#define CTC_LOGLEVEL_CRIT    64
-
-#define CTC_LOGLEVEL_DEFAULT \
-(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT)
-
-#define CTC_LOGLEVEL_MAX     ((CTC_LOGLEVEL_CRIT<<1)-1)
-
-static int loglevel = CTC_LOGLEVEL_DEFAULT;
-
-#define ctc_pr_debug(fmt, arg...) \
-do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0)
-
-#define ctc_pr_info(fmt, arg...) \
-do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0)
-
-#define ctc_pr_notice(fmt, arg...) \
-do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0)
-
-#define ctc_pr_warn(fmt, arg...) \
-do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0)
-
-#define ctc_pr_emerg(fmt, arg...) \
-do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0)
-
-#define ctc_pr_err(fmt, arg...) \
-do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0)
-
-#define ctc_pr_crit(fmt, arg...) \
-do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0)
-
-/**
- * Linked list of all detected channels.
- */
-static struct channel *channels = NULL;
-
-struct ctc_priv {
-       struct net_device_stats stats;
-       unsigned long tbusy;
-       /**
-        * The finite state machine of this interface.
-        */
-       fsm_instance *fsm;
-       /**
-        * The protocol of this device
-        */
-       __u16 protocol;
-       /**
-        * Timer for restarting after I/O Errors
-        */
-       fsm_timer               restart_timer;
-
-       int buffer_size;
-
-       struct channel *channel[2];
-};
-
-/**
- * Definition of our link level header.
- */
-struct ll_header {
-       __u16 length;
-       __u16 type;
-       __u16 unused;
-};
-#define LL_HEADER_LENGTH (sizeof(struct ll_header))
-
-/**
- * Compatibility macros for busy handling
- * of network devices.
- */
-static __inline__ void
-ctc_clear_busy(struct net_device * dev)
-{
-       clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));
-       if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
-               netif_wake_queue(dev);
-}
-
-static __inline__ int
-ctc_test_and_set_busy(struct net_device * dev)
-{
-       if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
-               netif_stop_queue(dev);
-       return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);
-}
-
-/**
- * Print Banner.
- */
-static void
-print_banner(void)
-{
-       static int printed = 0;
-       char vbuf[] = "$Revision: 1.72 $";
-       char *version = vbuf;
-
-       if (printed)
-               return;
-       if ((version = strchr(version, ':'))) {
-               char *p = strchr(version + 1, '$');
-               if (p)
-                       *p = '\0';
-       } else
-               version = " ??? ";
-       printk(KERN_INFO "CTC driver Version%s"
-#ifdef DEBUG
-                   " (DEBUG-VERSION, " __DATE__ __TIME__ ")"
-#endif
-                   " initialized\n", version);
-       printed = 1;
-}
-\f
-/**
- * Return type of a detected device.
- */
-static enum channel_types
-get_channel_type(struct ccw_device_id *id)
-{
-       enum channel_types type = (enum channel_types) id->driver_info;
-
-       if (type == channel_type_ficon)
-               type = channel_type_escon;
-
-       return type;
-}
-\f
 /**
  * States of the interface statemachine.
  */
@@ -371,7 +95,7 @@ enum dev_states {
        /**
         * MUST be always the last element!!
         */
-       NR_DEV_STATES
+       CTC_NR_DEV_STATES
 };
 
 static const char *dev_state_names[] = {
@@ -399,7 +123,7 @@ enum dev_events {
        /**
         * MUST be always the last element!!
         */
-       NR_DEV_EVENTS
+       CTC_NR_DEV_EVENTS
 };
 
 static const char *dev_event_names[] = {
@@ -476,40 +200,6 @@ enum ch_events {
        NR_CH_EVENTS,
 };
 
-static const char *ch_event_names[] = {
-       "ccw_device success",
-       "ccw_device busy",
-       "ccw_device enodev",
-       "ccw_device ioerr",
-       "ccw_device unknown",
-
-       "Status ATTN & BUSY",
-       "Status ATTN",
-       "Status BUSY",
-
-       "Unit check remote reset",
-       "Unit check remote system reset",
-       "Unit check TX timeout",
-       "Unit check TX parity",
-       "Unit check Hardware failure",
-       "Unit check RX parity",
-       "Unit check ZERO",
-       "Unit check Unknown",
-
-       "SubChannel check Unknown",
-
-       "Machine check failure",
-       "Machine check operational",
-
-       "IRQ normal",
-       "IRQ final",
-
-       "Timer",
-
-       "Start",
-       "Stop",
-};
-
 /**
  * States of the channel statemachine.
  */
@@ -545,6 +235,87 @@ enum ch_states {
        NR_CH_STATES,
 };
 
+static int loglevel = CTC_LOGLEVEL_DEFAULT;
+
+/**
+ * Linked list of all detected channels.
+ */
+static struct channel *channels = NULL;
+
+/**
+ * Print Banner.
+ */
+static void
+print_banner(void)
+{
+       static int printed = 0;
+       char vbuf[] = "$Revision: 1.74 $";
+       char *version = vbuf;
+
+       if (printed)
+               return;
+       if ((version = strchr(version, ':'))) {
+               char *p = strchr(version + 1, '$');
+               if (p)
+                       *p = '\0';
+       } else
+               version = " ??? ";
+       printk(KERN_INFO "CTC driver Version%s"
+#ifdef DEBUG
+                   " (DEBUG-VERSION, " __DATE__ __TIME__ ")"
+#endif
+                   " initialized\n", version);
+       printed = 1;
+}
+
+/**
+ * Return type of a detected device.
+ */
+static enum channel_types
+get_channel_type(struct ccw_device_id *id)
+{
+       enum channel_types type = (enum channel_types) id->driver_info;
+
+       if (type == channel_type_ficon)
+               type = channel_type_escon;
+
+       return type;
+}
+
+static const char *ch_event_names[] = {
+       "ccw_device success",
+       "ccw_device busy",
+       "ccw_device enodev",
+       "ccw_device ioerr",
+       "ccw_device unknown",
+
+       "Status ATTN & BUSY",
+       "Status ATTN",
+       "Status BUSY",
+
+       "Unit check remote reset",
+       "Unit check remote system reset",
+       "Unit check TX timeout",
+       "Unit check TX parity",
+       "Unit check Hardware failure",
+       "Unit check RX parity",
+       "Unit check ZERO",
+       "Unit check Unknown",
+
+       "SubChannel check Unknown",
+
+       "Machine check failure",
+       "Machine check operational",
+
+       "IRQ normal",
+       "IRQ final",
+
+       "Timer",
+
+       "Start",
+       "Stop",
+};
+
 static const char *ch_state_names[] = {
        "Idle",
        "Stopped",
@@ -1934,7 +1705,6 @@ add_channel(struct ccw_device *cdev, enum channel_types type)
        ch->cdev = cdev;
        snprintf(ch->id, CTC_ID_SIZE, "ch-%s", cdev->dev.bus_id);
        ch->type = type;
-       loglevel = CTC_LOGLEVEL_DEFAULT;
        ch->fsm = init_fsm(ch->id, ch_state_names,
                           ch_event_names, NR_CH_STATES, NR_CH_EVENTS,
                           ch_fsm, CH_FSM_LEN, GFP_KERNEL);
@@ -2697,6 +2467,7 @@ ctc_stats(struct net_device * dev)
 /*
  * sysfs attributes
  */
+
 static ssize_t
 buffer_show(struct device *dev, char *buf)
 {
@@ -2715,57 +2486,61 @@ buffer_write(struct device *dev, const char *buf, size_t count)
        struct ctc_priv *priv;
        struct net_device *ndev;
        int bs1;
+       char buffer[16];
 
        DBF_TEXT(trace, 3, __FUNCTION__);
+       DBF_TEXT(trace, 3, buf);
        priv = dev->driver_data;
-       if (!priv)
+       if (!priv) {
+               DBF_TEXT(trace, 3, "bfnopriv");
                return -ENODEV;
+       }
+
+       sscanf(buf, "%u", &bs1);
+       if (bs1 > CTC_BUFSIZE_LIMIT)
+               goto einval;
+       if (bs1 < (576 + LL_HEADER_LENGTH + 2))
+               goto einval;
+       priv->buffer_size = bs1;        // just to overwrite the default
+
        ndev = priv->channel[READ]->netdev;
-       if (!ndev)
+       if (!ndev) {
+               DBF_TEXT(trace, 3, "bfnondev");
                return -ENODEV;
-       sscanf(buf, "%u", &bs1);
+       }
 
-       if (bs1 > CTC_BUFSIZE_LIMIT)
-               return -EINVAL;
        if ((ndev->flags & IFF_RUNNING) &&
            (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2)))
-               return -EINVAL;
-       if (bs1 < (576 + LL_HEADER_LENGTH + 2))
-               return -EINVAL;
+               goto einval;
 
-       priv->buffer_size = bs1;
-       priv->channel[READ]->max_bufsize =
-           priv->channel[WRITE]->max_bufsize = bs1;
+       priv->channel[READ]->max_bufsize = bs1;
+       priv->channel[WRITE]->max_bufsize = bs1;
        if (!(ndev->flags & IFF_RUNNING))
                ndev->mtu = bs1 - LL_HEADER_LENGTH - 2;
        priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
        priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
 
+       sprintf(buffer, "%d",priv->buffer_size);
+       DBF_TEXT(trace, 3, buffer);
        return count;
 
+einval:
+       DBF_TEXT(trace, 3, "buff_err");
+       return -EINVAL;
 }
 
 static ssize_t
 loglevel_show(struct device *dev, char *buf)
 {
-       struct ctc_priv *priv;
-
-       priv = dev->driver_data;
-       if (!priv)
-               return -ENODEV;
        return sprintf(buf, "%d\n", loglevel);
 }
 
 static ssize_t
 loglevel_write(struct device *dev, const char *buf, size_t count)
 {
-       struct ctc_priv *priv;
        int ll1;
 
        DBF_TEXT(trace, 5, __FUNCTION__);
-       priv = dev->driver_data;
-       if (!priv)
-               return -ENODEV;
        sscanf(buf, "%i", &ll1);
 
        if ((ll1 > CTC_LOGLEVEL_MAX) || (ll1 < 0))
@@ -2835,27 +2610,6 @@ stats_write(struct device *dev, const char *buf, size_t count)
        return count;
 }
 
-static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
-static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write);
-static DEVICE_ATTR(stats, 0644, stats_show, stats_write);
-
-static int
-ctc_add_attributes(struct device *dev)
-{
-//     device_create_file(dev, &dev_attr_buffer);
-       device_create_file(dev, &dev_attr_loglevel);
-       device_create_file(dev, &dev_attr_stats);
-       return 0;
-}
-
-static void
-ctc_remove_attributes(struct device *dev)
-{
-       device_remove_file(dev, &dev_attr_stats);
-       device_remove_file(dev, &dev_attr_loglevel);
-//     device_remove_file(dev, &dev_attr_buffer);
-}
-
 \f
 static void
 ctc_netdev_unregister(struct net_device * dev)
@@ -2899,52 +2653,6 @@ ctc_free_netdevice(struct net_device * dev, int free_dev)
 #endif
 }
 
-/**
- * Initialize everything of the net device except the name and the
- * channel structs.
- */
-static struct net_device *
-ctc_init_netdevice(struct net_device * dev, int alloc_device, 
-                  struct ctc_priv *privptr)
-{
-       if (!privptr)
-               return NULL;
-
-       DBF_TEXT(setup, 3, __FUNCTION__);
-       if (alloc_device) {
-               dev = kmalloc(sizeof (struct net_device), GFP_KERNEL);
-               if (!dev)
-                       return NULL;
-               memset(dev, 0, sizeof (struct net_device));
-       }
-
-       dev->priv = privptr;
-       privptr->fsm = init_fsm("ctcdev", dev_state_names,
-                               dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
-                               dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
-       if (privptr->fsm == NULL) {
-               if (alloc_device)
-                       kfree(dev);
-               return NULL;
-       }
-       fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
-       fsm_settimer(privptr->fsm, &privptr->restart_timer);
-       if (dev->mtu == 0)
-               dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
-       dev->hard_start_xmit = ctc_tx;
-       dev->open = ctc_open;
-       dev->stop = ctc_close;
-       dev->get_stats = ctc_stats;
-       dev->change_mtu = ctc_change_mtu;
-       dev->hard_header_len = LL_HEADER_LENGTH + 2;
-       dev->addr_len = 0;
-       dev->type = ARPHRD_SLIP;
-       dev->tx_queue_len = 100;
-       dev->flags = IFF_POINTOPOINT | IFF_NOARP;
-       SET_MODULE_OWNER(dev);
-       return dev;
-}
-
 static ssize_t
 ctc_proto_show(struct device *dev, char *buf)
 {
@@ -2977,7 +2685,6 @@ ctc_proto_store(struct device *dev, const char *buf, size_t count)
        return count;
 }
 
-static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store);
 
 static ssize_t
 ctc_type_show(struct device *dev, char *buf)
@@ -2991,8 +2698,13 @@ ctc_type_show(struct device *dev, char *buf)
        return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]);
 }
 
+static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
+static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store);
 static DEVICE_ATTR(type, 0444, ctc_type_show, NULL);
 
+static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write);
+static DEVICE_ATTR(stats, 0644, stats_show, stats_write);
+
 static struct attribute *ctc_attr[] = {
        &dev_attr_protocol.attr,
        &dev_attr_type.attr,
@@ -3004,6 +2716,21 @@ static struct attribute_group ctc_attr_group = {
        .attrs = ctc_attr,
 };
 
+static int
+ctc_add_attributes(struct device *dev)
+{
+       device_create_file(dev, &dev_attr_loglevel);
+       device_create_file(dev, &dev_attr_stats);
+       return 0;
+}
+
+static void
+ctc_remove_attributes(struct device *dev)
+{
+       device_remove_file(dev, &dev_attr_stats);
+       device_remove_file(dev, &dev_attr_loglevel);
+}
+
 static int
 ctc_add_files(struct device *dev)
 {
@@ -3028,15 +2755,15 @@ ctc_remove_files(struct device *dev)
  *
  * @returns 0 on success, !0 on failure.
  */
-
 static int
 ctc_probe_device(struct ccwgroup_device *cgdev)
 {
        struct ctc_priv *priv;
        int rc;
+       char buffer[16];
 
        pr_debug("%s() called\n", __FUNCTION__);
-       DBF_TEXT(trace, 3, __FUNCTION__);
+       DBF_TEXT(setup, 3, __FUNCTION__);
 
        if (!get_device(&cgdev->dev))
                return -ENODEV;
@@ -3060,9 +2787,69 @@ ctc_probe_device(struct ccwgroup_device *cgdev)
        cgdev->cdev[1]->handler = ctc_irq_handler;
        cgdev->dev.driver_data = priv;
 
+       sprintf(buffer, "%p", priv);
+       DBF_TEXT(data, 3, buffer);
+
+       sprintf(buffer, "%u", (unsigned int)sizeof(struct ctc_priv));
+       DBF_TEXT(data, 3, buffer);
+
+       sprintf(buffer, "%p", &channels);
+       DBF_TEXT(data, 3, buffer);
+
+       sprintf(buffer, "%u", (unsigned int)sizeof(struct channel));
+       DBF_TEXT(data, 3, buffer);
+
        return 0;
 }
 
+/**
+ * Initialize everything of the net device except the name and the
+ * channel structs.
+ */
+static struct net_device *
+ctc_init_netdevice(struct net_device * dev, int alloc_device,
+                  struct ctc_priv *privptr)
+{
+       if (!privptr)
+               return NULL;
+
+       DBF_TEXT(setup, 3, __FUNCTION__);
+
+       if (alloc_device) {
+               dev = kmalloc(sizeof (struct net_device), GFP_KERNEL);
+               if (!dev)
+                       return NULL;
+               memset(dev, 0, sizeof (struct net_device));
+       }
+
+       dev->priv = privptr;
+       privptr->fsm = init_fsm("ctcdev", dev_state_names,
+                               dev_event_names, CTC_NR_DEV_STATES, CTC_NR_DEV_EVENTS,
+                               dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
+       if (privptr->fsm == NULL) {
+               if (alloc_device)
+                       kfree(dev);
+               return NULL;
+       }
+       fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
+       fsm_settimer(privptr->fsm, &privptr->restart_timer);
+       if (dev->mtu == 0)
+               dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
+       dev->hard_start_xmit = ctc_tx;
+       dev->open = ctc_open;
+       dev->stop = ctc_close;
+       dev->get_stats = ctc_stats;
+       dev->change_mtu = ctc_change_mtu;
+       dev->hard_header_len = LL_HEADER_LENGTH + 2;
+       dev->addr_len = 0;
+       dev->type = ARPHRD_SLIP;
+       dev->tx_queue_len = 100;
+       dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+       SET_MODULE_OWNER(dev);
+       return dev;
+}
+
+
 /**
  *
  * Setup an interface.
@@ -3081,6 +2868,7 @@ ctc_new_device(struct ccwgroup_device *cgdev)
        struct ctc_priv *privptr;
        struct net_device *dev;
        int ret;
+       char buffer[16];
 
        pr_debug("%s() called\n", __FUNCTION__);
        DBF_TEXT(setup, 3, __FUNCTION__);
@@ -3089,6 +2877,9 @@ ctc_new_device(struct ccwgroup_device *cgdev)
        if (!privptr)
                return -ENODEV;
 
+       sprintf(buffer, "%d", privptr->buffer_size);
+       DBF_TEXT(setup, 3, buffer);
+
        type = get_channel_type(&cgdev->cdev[0]->id);
        
        snprintf(read_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id);
@@ -3177,9 +2968,10 @@ ctc_shutdown_device(struct ccwgroup_device *cgdev)
        struct ctc_priv *priv;
        struct net_device *ndev;
                
-       DBF_TEXT(trace, 3, __FUNCTION__);
+       DBF_TEXT(setup, 3, __FUNCTION__);
        pr_debug("%s() called\n", __FUNCTION__);
 
+
        priv = cgdev->dev.driver_data;
        ndev = NULL;
        if (!priv)
@@ -3215,7 +3007,6 @@ ctc_shutdown_device(struct ccwgroup_device *cgdev)
                channel_remove(priv->channel[READ]);
        if (priv->channel[WRITE])
                channel_remove(priv->channel[WRITE]);
-       
        priv->channel[READ] = priv->channel[WRITE] = NULL;
 
        return 0;
@@ -3228,7 +3019,7 @@ ctc_remove_device(struct ccwgroup_device *cgdev)
        struct ctc_priv *priv;
 
        pr_debug("%s() called\n", __FUNCTION__);
-       DBF_TEXT(trace, 3, __FUNCTION__);
+       DBF_TEXT(setup, 3, __FUNCTION__);
 
        priv = cgdev->dev.driver_data;
        if (!priv)
@@ -3265,6 +3056,7 @@ static struct ccwgroup_driver ctc_group_driver = {
 static void __exit
 ctc_exit(void)
 {
+       DBF_TEXT(setup, 3, __FUNCTION__);
        unregister_cu3088_discipline(&ctc_group_driver);
        ctc_tty_cleanup();
        ctc_unregister_dbf_views();
@@ -3282,6 +3074,10 @@ ctc_init(void)
 {
        int ret = 0;
 
+       loglevel = CTC_LOGLEVEL_DEFAULT;
+
+       DBF_TEXT(setup, 3, __FUNCTION__);
+
        print_banner();
 
        ret = ctc_register_dbf_views();
diff --git a/drivers/s390/net/ctcmain.h b/drivers/s390/net/ctcmain.h
new file mode 100644 (file)
index 0000000..ba3605f
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * $Id: ctcmain.h,v 1.4 2005/03/24 09:04:17 mschwide Exp $
+ *
+ * CTC / ESCON network driver
+ *
+ * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
+             Peter Tiedemann (ptiedem@de.ibm.com)
+ *
+ *
+ * Documentation used:
+ *  - Principles of Operation (IBM doc#: SA22-7201-06)
+ *  - Common IO/-Device Commands and Self Description (IBM doc#: SA22-7204-02)
+ *  - Common IO/-Device Commands and Self Description (IBM doc#: SN22-5535)
+ *  - ESCON Channel-to-Channel Adapter (IBM doc#: SA22-7203-00)
+ *  - ESCON I/O Interface (IBM doc#: SA22-7202-029
+ *
+ * This program is free software; you can redistribute 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.
+ *
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.4 $
+ *
+ */
+
+#ifndef _CTCMAIN_H_
+#define _CTCMAIN_H_
+
+#include <asm/ccwdev.h>
+#include <asm/ccwgroup.h>
+
+#include "ctctty.h"
+#include "fsm.h"
+#include "cu3088.h"
+
+
+/**
+ * CCW commands, used in this driver.
+ */
+#define CCW_CMD_WRITE          0x01
+#define CCW_CMD_READ           0x02
+#define CCW_CMD_SET_EXTENDED   0xc3
+#define CCW_CMD_PREPARE                0xe3
+
+#define CTC_PROTO_S390          0
+#define CTC_PROTO_LINUX         1
+#define CTC_PROTO_LINUX_TTY     2
+#define CTC_PROTO_OS390         3
+#define CTC_PROTO_MAX           3
+
+#define CTC_BUFSIZE_LIMIT       65535
+#define CTC_BUFSIZE_DEFAULT     32768
+
+#define CTC_TIMEOUT_5SEC        5000
+
+#define CTC_INITIAL_BLOCKLEN    2
+
+#define READ                   0
+#define WRITE                  1
+
+#define CTC_ID_SIZE             BUS_ID_SIZE+3
+
+
+struct ctc_profile {
+       unsigned long maxmulti;
+       unsigned long maxcqueue;
+       unsigned long doios_single;
+       unsigned long doios_multi;
+       unsigned long txlen;
+       unsigned long tx_time;
+       struct timespec send_stamp;
+};
+
+/**
+ * Definition of one channel
+ */
+struct channel {
+
+       /**
+        * Pointer to next channel in list.
+        */
+       struct channel *next;
+       char id[CTC_ID_SIZE];
+       struct ccw_device *cdev;
+
+       /**
+        * Type of this channel.
+        * CTC/A or Escon for valid channels.
+        */
+       enum channel_types type;
+
+       /**
+        * Misc. flags. See CHANNEL_FLAGS_... below
+        */
+       __u32 flags;
+
+       /**
+        * The protocol of this channel
+        */
+       __u16 protocol;
+
+       /**
+        * I/O and irq related stuff
+        */
+       struct ccw1 *ccw;
+       struct irb *irb;
+
+       /**
+        * RX/TX buffer size
+        */
+       int max_bufsize;
+
+       /**
+        * Transmit/Receive buffer.
+        */
+       struct sk_buff *trans_skb;
+
+       /**
+        * Universal I/O queue.
+        */
+       struct sk_buff_head io_queue;
+
+       /**
+        * TX queue for collecting skb's during busy.
+        */
+       struct sk_buff_head collect_queue;
+
+       /**
+        * Amount of data in collect_queue.
+        */
+       int collect_len;
+
+       /**
+        * spinlock for collect_queue and collect_len
+        */
+       spinlock_t collect_lock;
+
+       /**
+        * Timer for detecting unresposive
+        * I/O operations.
+        */
+       fsm_timer timer;
+
+       /**
+        * Retry counter for misc. operations.
+        */
+       int retry;
+
+       /**
+        * The finite state machine of this channel
+        */
+       fsm_instance *fsm;
+
+       /**
+        * The corresponding net_device this channel
+        * belongs to.
+        */
+       struct net_device *netdev;
+
+       struct ctc_profile prof;
+
+       unsigned char *trans_skb_data;
+
+       __u16 logflags;
+};
+
+#define CHANNEL_FLAGS_READ            0
+#define CHANNEL_FLAGS_WRITE           1
+#define CHANNEL_FLAGS_INUSE           2
+#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4
+#define CHANNEL_FLAGS_FAILED          8
+#define CHANNEL_FLAGS_WAITIRQ        16
+#define CHANNEL_FLAGS_RWMASK 1
+#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)
+
+#define LOG_FLAG_ILLEGALPKT  1
+#define LOG_FLAG_ILLEGALSIZE 2
+#define LOG_FLAG_OVERRUN     4
+#define LOG_FLAG_NOMEM       8
+
+#define CTC_LOGLEVEL_INFO     1
+#define CTC_LOGLEVEL_NOTICE   2
+#define CTC_LOGLEVEL_WARN     4
+#define CTC_LOGLEVEL_EMERG    8
+#define CTC_LOGLEVEL_ERR     16
+#define CTC_LOGLEVEL_DEBUG   32
+#define CTC_LOGLEVEL_CRIT    64
+
+#define CTC_LOGLEVEL_DEFAULT \
+(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT)
+
+#define CTC_LOGLEVEL_MAX     ((CTC_LOGLEVEL_CRIT<<1)-1)
+
+#define ctc_pr_debug(fmt, arg...) \
+do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0)
+
+#define ctc_pr_info(fmt, arg...) \
+do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0)
+
+#define ctc_pr_notice(fmt, arg...) \
+do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0)
+
+#define ctc_pr_warn(fmt, arg...) \
+do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0)
+
+#define ctc_pr_emerg(fmt, arg...) \
+do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0)
+
+#define ctc_pr_err(fmt, arg...) \
+do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0)
+
+#define ctc_pr_crit(fmt, arg...) \
+do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0)
+
+struct ctc_priv {
+       struct net_device_stats stats;
+       unsigned long tbusy;
+       /**
+        * The finite state machine of this interface.
+        */
+       fsm_instance *fsm;
+       /**
+        * The protocol of this device
+        */
+       __u16 protocol;
+       /**
+        * Timer for restarting after I/O Errors
+        */
+       fsm_timer               restart_timer;
+
+       int buffer_size;
+
+       struct channel *channel[2];
+};
+
+/**
+ * Definition of our link level header.
+ */
+struct ll_header {
+       __u16 length;
+       __u16 type;
+       __u16 unused;
+};
+#define LL_HEADER_LENGTH (sizeof(struct ll_header))
+
+/**
+ * Compatibility macros for busy handling
+ * of network devices.
+ */
+static __inline__ void
+ctc_clear_busy(struct net_device * dev)
+{
+       clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));
+       if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
+               netif_wake_queue(dev);
+}
+
+static __inline__ int
+ctc_test_and_set_busy(struct net_device * dev)
+{
+       if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
+               netif_stop_queue(dev);
+       return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);
+}
+
+#endif
index 9257d60c78330478bca8a05280fda54054ceb9c4..3080393e823db43117d22a6bd73adf7cfdcc6013 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ctctty.c,v 1.26 2004/08/04 11:06:55 mschwide Exp $
+ * $Id: ctctty.c,v 1.29 2005/04/05 08:50:44 mschwide Exp $
  *
  * CTC / ESCON network driver, tty interface.
  *
@@ -1056,8 +1056,7 @@ ctc_tty_close(struct tty_struct *tty, struct file *filp)
        info->tty = 0;
        tty->closing = 0;
        if (info->blocked_open) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(HZ/2);
+               msleep_interruptible(500);
                wake_up_interruptible(&info->open_wait);
        }
        info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
index 1b0a9f16024c5929f0062972d431fd33088bb1d7..0075894c71db0e09086efd97b55111f0a374bbe0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cu3088.c,v 1.34 2004/06/15 13:16:27 pavlic Exp $
+ * $Id: cu3088.c,v 1.35 2005/03/30 19:28:52 richtera Exp $
  *
  * CTC / LCS ccw_device driver
  *
@@ -39,6 +39,7 @@ const char *cu3088_type[] = {
        "FICON channel",
        "P390 LCS card",
        "OSA LCS card",
+       "CLAW channel device",
        "unknown channel type",
        "unsupported channel type",
 };
@@ -51,6 +52,7 @@ static struct ccw_device_id cu3088_ids[] = {
        { CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon },
        { CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 },
        { CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 },
+       { CCW_DEVICE(0x3088, 0x61), .driver_info = channel_type_claw },
        { /* end of list */ }
 };
 
index 0ec49a8b3adcc5a2e697d01313120e18ad43fc4a..1753661f702a196325968df22cffec4485743f5e 100644 (file)
@@ -23,6 +23,9 @@ enum channel_types {
        /* Device is a OSA2 card */
        channel_type_osa2,
 
+       /* Device is a CLAW channel device */
+       channel_type_claw,
+
        /* Device is a channel, but we don't know
         * anything about it */
        channel_type_unknown,
index 1ac6563ee3e0fd0574f8e79e275130606defed3d..e08e74e16124704b1f7b8bede6092a2d1cab376e 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * $Id: iucv.c,v 1.43 2005/02/09 14:47:43 braunu Exp $
+ * $Id: iucv.c,v 1.45 2005/04/26 22:59:06 braunu Exp $
  *
  * IUCV network driver
  *
@@ -29,7 +29,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.43 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.45 $
  *
  */
 \f
@@ -355,7 +355,7 @@ do { \
 static void
 iucv_banner(void)
 {
-       char vbuf[] = "$Revision: 1.43 $";
+       char vbuf[] = "$Revision: 1.45 $";
        char *version = vbuf;
 
        if ((version = strchr(version, ':'))) {
@@ -2553,12 +2553,12 @@ EXPORT_SYMBOL (iucv_resume);
 #endif
 EXPORT_SYMBOL (iucv_reply_prmmsg);
 EXPORT_SYMBOL (iucv_send);
-#if 0
 EXPORT_SYMBOL (iucv_send2way);
 EXPORT_SYMBOL (iucv_send2way_array);
-EXPORT_SYMBOL (iucv_send_array);
 EXPORT_SYMBOL (iucv_send2way_prmmsg);
 EXPORT_SYMBOL (iucv_send2way_prmmsg_array);
+#if 0
+EXPORT_SYMBOL (iucv_send_array);
 EXPORT_SYMBOL (iucv_send_prmmsg);
 EXPORT_SYMBOL (iucv_setmask);
 #endif
index 0f76e945b9841dadd2ac93b4c627fca18d0e9c84..cccfed248e701ef939bb022c975558f5097c54ca 100644 (file)
@@ -11,7 +11,7 @@
  *                       Frank Pavlic (pavlic@de.ibm.com) and
  *                       Martin Schwidefsky <schwidefsky@de.ibm.com>
  *
- *    $Revision: 1.96 $         $Date: 2004/11/11 13:42:33 $
+ *    $Revision: 1.98 $         $Date: 2005/04/18 13:41:29 $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@
 /**
  * initialization string for output
  */
-#define VERSION_LCS_C  "$Revision: 1.96 $"
+#define VERSION_LCS_C  "$Revision: 1.98 $"
 
 static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
 static char debug_buffer[255];
@@ -1098,14 +1098,6 @@ lcs_check_multicast_support(struct lcs_card *card)
                PRINT_ERR("Query IPAssist failed. Assuming unsupported!\n");
                return -EOPNOTSUPP;
        }
-       /* Print out supported assists: IPv6 */
-       PRINT_INFO("LCS device %s %s IPv6 support\n", card->dev->name,
-                  (card->ip_assists_supported & LCS_IPASS_IPV6_SUPPORT) ?
-                  "with" : "without");
-       /* Print out supported assist: Multicast */
-       PRINT_INFO("LCS device %s %s Multicast support\n", card->dev->name,
-                  (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) ?
-                  "with" : "without");
        if (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT)
                return 0;
        return -EOPNOTSUPP;
@@ -1160,7 +1152,7 @@ list_modified:
                }
        }
        /* re-insert all entries from the failed_list into ipm_list */
-       list_for_each_entry(ipm, &failed_list, list) {
+       list_for_each_entry_safe(ipm, tmp, &failed_list, list) {
                list_del_init(&ipm->list);
                list_add_tail(&ipm->list, &card->ipm_list);
        }
@@ -2198,30 +2190,39 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
        if (!dev)
                goto out;
        card->dev = dev;
-netdev_out:
        card->dev->priv = card;
        card->dev->open = lcs_open_device;
        card->dev->stop = lcs_stop_device;
        card->dev->hard_start_xmit = lcs_start_xmit;
        card->dev->get_stats = lcs_getstats;
        SET_MODULE_OWNER(dev);
-       if (lcs_register_netdev(ccwgdev) != 0)
-               goto out;
        memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH);
 #ifdef CONFIG_IP_MULTICAST
        if (!lcs_check_multicast_support(card))
                card->dev->set_multicast_list = lcs_set_multicast_list;
 #endif
-       netif_stop_queue(card->dev);
+netdev_out:
        lcs_set_allowed_threads(card,0xffffffff);
        if (recover_state == DEV_STATE_RECOVER) {
                lcs_set_multicast_list(card->dev);
                card->dev->flags |= IFF_UP;
                netif_wake_queue(card->dev);
                card->state = DEV_STATE_UP;
-       } else
+       } else {
                lcs_stopcard(card);
+       }
 
+       if (lcs_register_netdev(ccwgdev) != 0)
+               goto out;
+
+       /* Print out supported assists: IPv6 */
+       PRINT_INFO("LCS device %s %s IPv6 support\n", card->dev->name,
+                  (card->ip_assists_supported & LCS_IPASS_IPV6_SUPPORT) ?
+                  "with" : "without");
+       /* Print out supported assist: Multicast */
+       PRINT_INFO("LCS device %s %s Multicast support\n", card->dev->name,
+                  (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) ?
+                  "with" : "without");
        return 0;
 out:
 
index a341041a6cf77358955232fae17fa61ef09b4107..a755b57db46b359c9cb632919fc71ef7fd9c52fd 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "qeth_mpc.h"
 
-#define VERSION_QETH_H                 "$Revision: 1.135 $"
+#define VERSION_QETH_H                 "$Revision: 1.139 $"
 
 #ifdef CONFIG_QETH_IPV6
 #define QETH_VERSION_IPV6      ":IPv6"
@@ -288,7 +288,8 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
 #define QETH_TX_TIMEOUT                100 * HZ
 #define QETH_HEADER_SIZE       32
 #define MAX_PORTNO             15
-#define QETH_FAKE_LL_LEN       ETH_HLEN
+#define QETH_FAKE_LL_LEN_ETH   ETH_HLEN
+#define QETH_FAKE_LL_LEN_TR    (sizeof(struct trh_hdr)-TR_MAXRIFLEN+sizeof(struct trllc))
 #define QETH_FAKE_LL_V6_ADDR_POS 24
 
 /*IPv6 address autoconfiguration stuff*/
@@ -369,6 +370,25 @@ struct qeth_hdr {
        } hdr;
 } __attribute__ ((packed));
 
+/*TCP Segmentation Offload header*/
+struct qeth_hdr_ext_tso {
+        __u16 hdr_tot_len;
+        __u8  imb_hdr_no;
+        __u8  reserved;
+        __u8  hdr_type;
+        __u8  hdr_version;
+        __u16 hdr_len;
+        __u32 payload_len;
+        __u16 mss;
+        __u16 dg_hdr_len;
+        __u8  padding[16];
+} __attribute__ ((packed));
+
+struct qeth_hdr_tso {
+        struct qeth_hdr hdr;   /*hdr->hdr.l3.xxx*/
+       struct qeth_hdr_ext_tso ext;
+} __attribute__ ((packed));
+
 
 /* flags for qeth_hdr.flags */
 #define QETH_HDR_PASSTHRU 0x10
@@ -866,6 +886,7 @@ qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size)
         return hdr;
 }
 
+
 inline static int
 qeth_get_hlen(__u8 link_type)
 {
@@ -873,19 +894,19 @@ qeth_get_hlen(__u8 link_type)
        switch (link_type) {
        case QETH_LINK_TYPE_HSTR:
        case QETH_LINK_TYPE_LANE_TR:
-               return sizeof(struct qeth_hdr) + TR_HLEN;
+               return sizeof(struct qeth_hdr_tso) + TR_HLEN;
        default:
 #ifdef CONFIG_QETH_VLAN
-               return sizeof(struct qeth_hdr) + VLAN_ETH_HLEN;
+               return sizeof(struct qeth_hdr_tso) + VLAN_ETH_HLEN;
 #else
-               return sizeof(struct qeth_hdr) + ETH_HLEN;
+               return sizeof(struct qeth_hdr_tso) + ETH_HLEN;
 #endif
        }
 #else  /* CONFIG_QETH_IPV6 */
 #ifdef CONFIG_QETH_VLAN
-       return sizeof(struct qeth_hdr) + VLAN_HLEN;
+       return sizeof(struct qeth_hdr_tso) + VLAN_HLEN;
 #else
-       return sizeof(struct qeth_hdr);
+       return sizeof(struct qeth_hdr_tso);
 #endif
 #endif /* CONFIG_QETH_IPV6 */
 }
index 7ee1c06ed68a841af7ac49eeaa1d616681845b67..f94f1f25eec60a8e57ba9d311a90c47b2df58594 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.11 $)
+ * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.13 $)
  *
  * Enhanced Device Driver Packing (EDDP) support for the qeth driver.
  *
@@ -8,7 +8,7 @@
  *
  *    Author(s): Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.11 $         $Date: 2005/03/24 09:04:18 $
+ *    $Revision: 1.13 $         $Date: 2005/05/04 20:19:18 $
  *
  */
 #include <linux/config.h>
@@ -85,7 +85,7 @@ void
 qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
 {
        struct qeth_eddp_context_reference *ref;
-
+       
        QETH_DBF_TEXT(trace, 6, "eddprctx");
        while (!list_empty(&buf->ctx_list)){
                ref = list_entry(buf->ctx_list.next,
@@ -139,7 +139,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
                                           "buffer!\n");
                                goto out;
                        }
-               }
+               }               
                /* check if the whole next skb fits into current buffer */
                if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) -
                                        buf->next_element_to_fill)
@@ -152,7 +152,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
                         * and increment ctx's refcnt */
                        must_refcnt = 1;
                        continue;
-               }
+               }       
                if (must_refcnt){
                        must_refcnt = 0;
                        if (qeth_eddp_buf_ref_context(buf, ctx)){
@@ -202,40 +202,29 @@ out:
        return flush_cnt;
 }
 
-static inline int
-qeth_get_skb_data_len(struct sk_buff *skb)
-{
-       int len = skb->len;
-       int i;
-
-       for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i)
-               len -= skb_shinfo(skb)->frags[i].size;
-       return len;
-}
-
 static inline void
 qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
-                             struct qeth_eddp_data *eddp)
+                             struct qeth_eddp_data *eddp, int data_len)
 {
        u8 *page;
        int page_remainder;
        int page_offset;
-       int hdr_len;
+       int pkt_len;
        struct qeth_eddp_element *element;
 
        QETH_DBF_TEXT(trace, 5, "eddpcrsh");
        page = ctx->pages[ctx->offset >> PAGE_SHIFT];
        page_offset = ctx->offset % PAGE_SIZE;
        element = &ctx->elements[ctx->num_elements];
-       hdr_len = eddp->nhl + eddp->thl;
+       pkt_len = eddp->nhl + eddp->thl + data_len;
        /* FIXME: layer2 and VLAN !!! */
        if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
-               hdr_len += ETH_HLEN;
+               pkt_len += ETH_HLEN;
        if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
-               hdr_len += VLAN_HLEN;
-       /* does complete header fit in current page ? */
+               pkt_len += VLAN_HLEN;
+       /* does complete packet fit in current page ? */
        page_remainder = PAGE_SIZE - page_offset;
-       if (page_remainder < (sizeof(struct qeth_hdr) + hdr_len)){
+       if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)){
                /* no -> go to start of next page */
                ctx->offset += page_remainder;
                page = ctx->pages[ctx->offset >> PAGE_SHIFT];
@@ -281,7 +270,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
        int left_in_frag;
        int copy_len;
        u8 *src;
-
+       
        QETH_DBF_TEXT(trace, 5, "eddpcdtc");
        if (skb_shinfo(eddp->skb)->nr_frags == 0) {
                memcpy(dst, eddp->skb->data + eddp->skb_offset, len);
@@ -292,7 +281,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
                while (len > 0) {
                        if (eddp->frag < 0) {
                                /* we're in skb->data */
-                               left_in_frag = qeth_get_skb_data_len(eddp->skb)
+                               left_in_frag = (eddp->skb->len - eddp->skb->data_len)
                                                - eddp->skb_offset;
                                src = eddp->skb->data + eddp->skb_offset;
                        } else {
@@ -424,7 +413,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
        struct tcphdr *tcph;
        int data_len;
        u32 hcsum;
-
+       
        QETH_DBF_TEXT(trace, 5, "eddpftcp");
        eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
        tcph = eddp->skb->h.th;
@@ -464,7 +453,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
                else
                        hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len);
                /* fill the next segment into the context */
-               qeth_eddp_create_segment_hdrs(ctx, eddp);
+               qeth_eddp_create_segment_hdrs(ctx, eddp, data_len);
                qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum);
                if (eddp->skb_offset >= eddp->skb->len)
                        break;
@@ -474,13 +463,13 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
                eddp->th.tcp.h.seq += data_len;
        }
 }
-
+                          
 static inline int
 qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
                           struct sk_buff *skb, struct qeth_hdr *qhdr)
 {
        struct qeth_eddp_data *eddp = NULL;
-
+       
        QETH_DBF_TEXT(trace, 5, "eddpficx");
        /* create our segmentation headers and copy original headers */
        if (skb->protocol == ETH_P_IP)
@@ -520,7 +509,7 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
                         int hdr_len)
 {
        int skbs_per_page;
-
+       
        QETH_DBF_TEXT(trace, 5, "eddpcanp");
        /* can we put multiple skbs in one page? */
        skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
@@ -600,7 +589,7 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
                             struct qeth_hdr *qhdr)
 {
        struct qeth_eddp_context *ctx = NULL;
-
+       
        QETH_DBF_TEXT(trace, 5, "creddpct");
        if (skb->protocol == ETH_P_IP)
                ctx = qeth_eddp_create_context_generic(card, skb,
index 607b92542df6c3924cc5d7f8740928776661eb34..208127a5033ae707ffdb1168d2c0f7da979cab4d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.206 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.214 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  *
@@ -12,7 +12,7 @@
  *                       Frank Pavlic (pavlic@de.ibm.com) and
  *                       Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.206 $        $Date: 2005/03/24 09:04:18 $
+ *    $Revision: 1.214 $        $Date: 2005/05/04 20:19:18 $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -80,7 +80,7 @@ qeth_eyecatcher(void)
 #include "qeth_eddp.h"
 #include "qeth_tso.h"
 
-#define VERSION_QETH_C "$Revision: 1.206 $"
+#define VERSION_QETH_C "$Revision: 1.214 $"
 static const char *version = "qeth S/390 OSA-Express driver";
 
 /**
@@ -158,6 +158,9 @@ qeth_irq_tasklet(unsigned long);
 static int
 qeth_set_online(struct ccwgroup_device *);
 
+static int
+__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode);
+
 static struct qeth_ipaddr *
 qeth_get_addr_buffer(enum qeth_prot_versions);
 
@@ -510,10 +513,10 @@ qeth_irq_tasklet(unsigned long data)
        wake_up(&card->wait_q);
 }
 
-static int qeth_stop_card(struct qeth_card *);
+static int qeth_stop_card(struct qeth_card *, int);
 
 static int
-qeth_set_offline(struct ccwgroup_device *cgdev)
+__qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
 {
        struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
        int rc = 0;
@@ -523,7 +526,7 @@ qeth_set_offline(struct ccwgroup_device *cgdev)
        QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
 
        recover_flag = card->state;
-       if (qeth_stop_card(card) == -ERESTARTSYS){
+       if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){
                PRINT_WARN("Stopping card %s interrupted by user!\n",
                           CARD_BUS_ID(card));
                return -ERESTARTSYS;
@@ -539,6 +542,12 @@ qeth_set_offline(struct ccwgroup_device *cgdev)
        return 0;
 }
 
+static int
+qeth_set_offline(struct ccwgroup_device *cgdev)
+{
+       return  __qeth_set_offline(cgdev, 0);
+}
+
 static int
 qeth_wait_for_threads(struct qeth_card *card, unsigned long threads);
 
@@ -953,8 +962,8 @@ qeth_recover(void *ptr)
        PRINT_WARN("Recovery of device %s started ...\n",
                   CARD_BUS_ID(card));
        card->use_hard_stop = 1;
-       qeth_set_offline(card->gdev);
-       rc = qeth_set_online(card->gdev);
+       __qeth_set_offline(card->gdev,1);
+       rc = __qeth_set_online(card->gdev,1);
        if (!rc)
                PRINT_INFO("Device %s successfully recovered!\n",
                           CARD_BUS_ID(card));
@@ -2152,9 +2161,15 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
        if (!skb_len)
                return NULL;
        if (card->options.fake_ll){
-               if (!(skb = qeth_get_skb(skb_len + QETH_FAKE_LL_LEN)))
-                       goto no_mem;
-               skb_pull(skb, QETH_FAKE_LL_LEN);
+               if(card->dev->type == ARPHRD_IEEE802_TR){
+                       if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR)))
+                               goto no_mem;
+                       skb_reserve(skb,QETH_FAKE_LL_LEN_TR);
+               } else {
+                       if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH)))
+                               goto no_mem;
+                       skb_reserve(skb,QETH_FAKE_LL_LEN_ETH);
+               }
        } else if (!(skb = qeth_get_skb(skb_len)))
                goto no_mem;
        data_ptr = element->addr + offset;
@@ -2229,14 +2244,68 @@ qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
 }
 
 static inline void
-qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
+qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
+                        struct qeth_hdr *hdr)
+{
+       struct trh_hdr *fake_hdr;
+       struct trllc *fake_llc;
+       struct iphdr *ip_hdr;
+
+       QETH_DBF_TEXT(trace,5,"skbfktr");
+       skb->mac.raw = skb->data - QETH_FAKE_LL_LEN_TR;
+       /* this is a fake ethernet header */
+       fake_hdr = (struct trh_hdr *) skb->mac.raw;
+
+       /* the destination MAC address */
+       switch (skb->pkt_type){
+       case PACKET_MULTICAST:
+               switch (skb->protocol){
+#ifdef CONFIG_QETH_IPV6
+               case __constant_htons(ETH_P_IPV6):
+                       ndisc_mc_map((struct in6_addr *)
+                                    skb->data + QETH_FAKE_LL_V6_ADDR_POS,
+                                    fake_hdr->daddr, card->dev, 0);
+                       break;
+#endif /* CONFIG_QETH_IPV6 */
+               case __constant_htons(ETH_P_IP):
+                       ip_hdr = (struct iphdr *)skb->data;
+                       ip_tr_mc_map(ip_hdr->daddr, fake_hdr->daddr);
+                       break;
+               default:
+                       memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN);
+               }
+               break;
+       case PACKET_BROADCAST:
+               memset(fake_hdr->daddr, 0xff, TR_ALEN);
+               break;
+       default:
+               memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN);
+       }
+       /* the source MAC address */
+       if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR)
+               memcpy(fake_hdr->saddr, &hdr->hdr.l3.dest_addr[2], TR_ALEN);
+       else
+               memset(fake_hdr->saddr, 0, TR_ALEN);
+       fake_hdr->rcf=0;
+       fake_llc = (struct trllc*)&(fake_hdr->rcf);
+       fake_llc->dsap = EXTENDED_SAP;
+       fake_llc->ssap = EXTENDED_SAP;
+       fake_llc->llc  = UI_CMD;
+       fake_llc->protid[0] = 0;
+       fake_llc->protid[1] = 0;
+       fake_llc->protid[2] = 0;
+       fake_llc->ethertype = ETH_P_IP;
+}
+
+static inline void
+qeth_rebuild_skb_fake_ll_eth(struct qeth_card *card, struct sk_buff *skb,
                         struct qeth_hdr *hdr)
 {
        struct ethhdr *fake_hdr;
        struct iphdr *ip_hdr;
 
-       QETH_DBF_TEXT(trace,5,"skbfake");
-       skb->mac.raw = skb->data - QETH_FAKE_LL_LEN;
+       QETH_DBF_TEXT(trace,5,"skbfketh");
+       skb->mac.raw = skb->data - QETH_FAKE_LL_LEN_ETH;
        /* this is a fake ethernet header */
        fake_hdr = (struct ethhdr *) skb->mac.raw;
 
@@ -2253,10 +2322,7 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
 #endif /* CONFIG_QETH_IPV6 */
                case __constant_htons(ETH_P_IP):
                        ip_hdr = (struct iphdr *)skb->data;
-                       if (card->dev->type == ARPHRD_IEEE802_TR)
-                               ip_tr_mc_map(ip_hdr->daddr, fake_hdr->h_dest);
-                       else
-                               ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest);
+                       ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest);
                        break;
                default:
                        memcpy(fake_hdr->h_dest, card->dev->dev_addr, ETH_ALEN);
@@ -2277,6 +2343,16 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
        fake_hdr->h_proto = skb->protocol;
 }
 
+static inline void
+qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
+                       struct qeth_hdr *hdr)
+{
+       if (card->dev->type == ARPHRD_IEEE802_TR)
+               qeth_rebuild_skb_fake_ll_tr(card, skb, hdr);
+       else
+               qeth_rebuild_skb_fake_ll_eth(card, skb, hdr);
+}
+
 static inline void
 qeth_rebuild_skb_vlan(struct qeth_card *card, struct sk_buff *skb,
                      struct qeth_hdr *hdr)
@@ -3440,16 +3516,25 @@ qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
                     unsigned short type, void *daddr, void *saddr,
                     unsigned len)
 {
-       struct ethhdr *hdr;
+       if(dev->type == ARPHRD_IEEE802_TR){
+               struct trh_hdr *hdr;
+               hdr = (struct trh_hdr *)skb_push(skb, QETH_FAKE_LL_LEN_TR);
+               memcpy(hdr->saddr, dev->dev_addr, TR_ALEN);
+               memcpy(hdr->daddr, "FAKELL", TR_ALEN);
+               return QETH_FAKE_LL_LEN_TR;
+
+       } else {
+               struct ethhdr *hdr;
+               hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN_ETH);
+               memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN);
+               memcpy(hdr->h_dest, "FAKELL", ETH_ALEN);
+               if (type != ETH_P_802_3)
+                       hdr->h_proto = htons(type);
+               else
+                       hdr->h_proto = htons(len);
+               return QETH_FAKE_LL_LEN_ETH;
 
-        hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN);
-       memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN);
-        memcpy(hdr->h_dest, "FAKELL", ETH_ALEN);
-        if (type != ETH_P_802_3)
-                hdr->h_proto = htons(type);
-        else
-                hdr->h_proto = htons(len);
-       return QETH_FAKE_LL_LEN;
+       }
 }
 
 static inline int
@@ -3710,16 +3795,12 @@ static inline int
 qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
                 struct qeth_hdr **hdr, int ipv)
 {
-       int rc = 0;
 #ifdef CONFIG_QETH_VLAN
        u16 *tag;
 #endif
 
        QETH_DBF_TEXT(trace, 6, "prepskb");
 
-       rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
-       if (rc)
-               return rc;
 #ifdef CONFIG_QETH_VLAN
        if (card->vlangrp && vlan_tx_tag_present(*skb) &&
            ((ipv == 6) || card->options.layer2) ) {
@@ -3882,9 +3963,15 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
                        memcpy(hdr->hdr.l3.dest_addr, &skb->nh.ipv6h->daddr, 16);
                }
        } else { /* passthrough */
-               if (!memcmp(skb->data + sizeof(struct qeth_hdr),
+                if((skb->dev->type == ARPHRD_IEEE802_TR) &&
+                   !memcmp(skb->data + sizeof(struct qeth_hdr) + 
+                   sizeof(__u16), skb->dev->broadcast, 6)) {
+                       hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
+                                               QETH_HDR_PASSTHRU;
+               } else if (!memcmp(skb->data + sizeof(struct qeth_hdr),
                            skb->dev->broadcast, 6)) {   /* broadcast? */
-                       hdr->hdr.l3.flags = QETH_CAST_BROADCAST | QETH_HDR_PASSTHRU;
+                       hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
+                                               QETH_HDR_PASSTHRU;
                } else {
                        hdr->hdr.l3.flags = (cast_type == RTN_MULTICAST) ?
                                QETH_CAST_MULTICAST | QETH_HDR_PASSTHRU :
@@ -3893,68 +3980,30 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
        }
 }
 
-static inline void
-__qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer,
-                       int *next_element_to_fill)
-{
-       int length = skb->len;
-       struct skb_frag_struct *frag;
-       int fragno;
-       unsigned long addr;
-       int element;
-       int first_lap = 1;
-
-       fragno = skb_shinfo(skb)->nr_frags; /* start with last frag */
-       element = *next_element_to_fill + fragno;
-       while (length > 0) {
-               if (fragno > 0) {
-                       frag = &skb_shinfo(skb)->frags[fragno - 1];
-                       addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
-                               frag->page_offset;
-                       buffer->element[element].addr = (char *)addr;
-                       buffer->element[element].length = frag->size;
-                       length -= frag->size;
-                       if (first_lap)
-                               buffer->element[element].flags =
-                                   SBAL_FLAGS_LAST_FRAG;
-                       else
-                               buffer->element[element].flags =
-                                   SBAL_FLAGS_MIDDLE_FRAG;
-               } else {
-                       buffer->element[element].addr = skb->data;
-                       buffer->element[element].length = length;
-                       length = 0;
-                       buffer->element[element].flags =
-                               SBAL_FLAGS_FIRST_FRAG;
-               }
-               element--;
-               fragno--;
-               first_lap = 0;
-       }
-       *next_element_to_fill += skb_shinfo(skb)->nr_frags + 1;
-}
-
 static inline void
 __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer,
-                  int *next_element_to_fill)
+                  int is_tso, int *next_element_to_fill)
 {
        int length = skb->len;
        int length_here;
        int element;
        char *data;
-       int first_lap = 1;
+       int first_lap ;
 
        element = *next_element_to_fill;
        data = skb->data;
+       first_lap = (is_tso == 0 ? 1 : 0);
+
        while (length > 0) {
                /* length_here is the remaining amount of data in this page */
                length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE);
                if (length < length_here)
                        length_here = length;
+
                buffer->element[element].addr = data;
                buffer->element[element].length = length_here;
                length -= length_here;
-               if (!length){
+               if (!length) {
                        if (first_lap)
                                buffer->element[element].flags = 0;
                        else
@@ -3981,17 +4030,35 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue,
                 struct sk_buff *skb)
 {
        struct qdio_buffer *buffer;
-       int flush_cnt = 0;
+       struct qeth_hdr_tso *hdr;
+       int flush_cnt = 0, hdr_len, large_send = 0;
 
        QETH_DBF_TEXT(trace, 6, "qdfillbf");
+
        buffer = buf->buffer;
        atomic_inc(&skb->users);
        skb_queue_tail(&buf->skb_list, skb);
+
+       hdr  = (struct qeth_hdr_tso *) skb->data;
+       /*check first on TSO ....*/
+       if (hdr->hdr.hdr.l3.id == QETH_HEADER_TYPE_TSO) {
+               int element = buf->next_element_to_fill;
+
+               hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len;
+               /*fill first buffer entry only with header information */
+               buffer->element[element].addr = skb->data;
+               buffer->element[element].length = hdr_len;
+               buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
+               buf->next_element_to_fill++;
+               skb->data += hdr_len;
+               skb->len  -= hdr_len;
+               large_send = 1;
+       }
        if (skb_shinfo(skb)->nr_frags == 0)
-               __qeth_fill_buffer(skb, buffer,
+               __qeth_fill_buffer(skb, buffer, large_send,
                                   (int *)&buf->next_element_to_fill);
        else
-               __qeth_fill_buffer_frag(skb, buffer,
+               __qeth_fill_buffer_frag(skb, buffer, large_send,
                                        (int *)&buf->next_element_to_fill);
 
        if (!queue->do_pack) {
@@ -4183,6 +4250,25 @@ out:
        return rc;
 }
 
+static inline int
+qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb)
+{
+       int elements_needed = 0;
+
+        if (skb_shinfo(skb)->nr_frags > 0) {
+                elements_needed = (skb_shinfo(skb)->nr_frags + 1);
+       }
+        if (elements_needed == 0 )
+                elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
+                                        + skb->len) >> PAGE_SHIFT);
+        if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){
+                PRINT_ERR("qeth_do_send_packet: invalid size of "
+                          "IP packet. Discarded.");
+                return 0;
+        }
+        return elements_needed;
+}
+
 static inline int
 qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
 {
@@ -4205,7 +4291,11 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
                                dev_kfree_skb_irq(skb);
                                return 0;
                        }
-                       skb_pull(skb, QETH_FAKE_LL_LEN);
+                       if(card->dev->type == ARPHRD_IEEE802_TR){
+                               skb_pull(skb, QETH_FAKE_LL_LEN_TR);
+                       } else {
+                               skb_pull(skb, QETH_FAKE_LL_LEN_ETH);
+                       }
                }
        }
        cast_type = qeth_get_cast_type(card, skb);
@@ -4221,19 +4311,25 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
        if (skb_shinfo(skb)->tso_size)
                large_send = card->options.large_send;
 
-       if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))){
-               QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc);
-               return rc;
-       }
        /*are we able to do TSO ? If so ,prepare and send it from here */
        if ((large_send == QETH_LARGE_SEND_TSO) &&
            (cast_type == RTN_UNSPEC)) {
-               rc = qeth_tso_send_packet(card, skb, queue,
-                                         ipv, cast_type);
-               goto do_statistics;
+               rc = qeth_tso_prepare_packet(card, skb, ipv, cast_type);
+               if (rc) {
+                       card->stats.tx_dropped++;
+                       card->stats.tx_errors++;
+                       dev_kfree_skb_any(skb);
+                       return NETDEV_TX_OK;
+               } 
+               elements_needed++;
+       } else {
+               if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) {
+                       QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc);
+                       return rc;
+               }
+               qeth_fill_header(card, hdr, skb, ipv, cast_type);
        }
 
-       qeth_fill_header(card, hdr, skb, ipv, cast_type);
        if (large_send == QETH_LARGE_SEND_EDDP) {
                ctx = qeth_eddp_create_context(card, skb, hdr);
                if (ctx == NULL) {
@@ -4241,7 +4337,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
                        return -EINVAL;
                }
        } else {
-               elements_needed = qeth_get_elements_no(card,(void*) hdr, skb);
+               elements_needed += qeth_get_elements_no(card,(void*) hdr, skb);
                if (!elements_needed)
                        return -EINVAL;
        }
@@ -4252,12 +4348,12 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
        else
                rc = qeth_do_send_packet_fast(card, queue, skb, hdr,
                                              elements_needed, ctx);
-do_statistics:
        if (!rc){
                card->stats.tx_packets++;
                card->stats.tx_bytes += skb->len;
 #ifdef CONFIG_QETH_PERF_STATS
-               if (skb_shinfo(skb)->tso_size) {
+               if (skb_shinfo(skb)->tso_size &&
+                  !(large_send == QETH_LARGE_SEND_NO)) {
                        card->perf_stats.large_send_bytes += skb->len;
                        card->perf_stats.large_send_cnt++;
                }
@@ -7154,7 +7250,7 @@ qeth_wait_for_threads(struct qeth_card *card, unsigned long threads)
 }
 
 static int
-qeth_stop_card(struct qeth_card *card)
+qeth_stop_card(struct qeth_card *card, int recovery_mode)
 {
        int rc = 0;
 
@@ -7167,9 +7263,13 @@ qeth_stop_card(struct qeth_card *card)
        if (card->read.state == CH_STATE_UP &&
            card->write.state == CH_STATE_UP &&
            (card->state == CARD_STATE_UP)) {
-               rtnl_lock();
-               dev_close(card->dev);
-               rtnl_unlock();
+               if(recovery_mode) {
+                       qeth_stop(card->dev);
+               } else {
+                       rtnl_lock();
+                       dev_close(card->dev);
+                       rtnl_unlock();
+               }
                if (!card->use_hard_stop) {
                        __u8 *mac = &card->dev->dev_addr[0];
                        rc = qeth_layer2_send_delmac(card, mac);
@@ -7341,13 +7441,17 @@ qeth_register_netdev(struct qeth_card *card)
 }
 
 static void
-qeth_start_again(struct qeth_card *card)
+qeth_start_again(struct qeth_card *card, int recovery_mode)
 {
        QETH_DBF_TEXT(setup ,2, "startag");
 
-       rtnl_lock();
-       dev_open(card->dev);
-       rtnl_unlock();
+       if(recovery_mode) {
+               qeth_open(card->dev);
+       } else {
+               rtnl_lock();
+               dev_open(card->dev);
+               rtnl_unlock();
+       }
        /* this also sets saved unicast addresses */
        qeth_set_multicast_list(card->dev);
 }
@@ -7404,7 +7508,7 @@ static void qeth_make_parameters_consistent(struct qeth_card *card)
 
 
 static int
-qeth_set_online(struct ccwgroup_device *gdev)
+__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
 {
        struct qeth_card *card = gdev->dev.driver_data;
        int rc = 0;
@@ -7464,12 +7568,12 @@ qeth_set_online(struct ccwgroup_device *gdev)
  * we can also use this state for recovery purposes*/
        qeth_set_allowed_threads(card, 0xffffffff, 0);
        if (recover_flag == CARD_STATE_RECOVER)
-               qeth_start_again(card);
+               qeth_start_again(card, recovery_mode);
        qeth_notify_processes();
        return 0;
 out_remove:
        card->use_hard_stop = 1;
-       qeth_stop_card(card);
+       qeth_stop_card(card, 0);
        ccw_device_set_offline(CARD_DDEV(card));
        ccw_device_set_offline(CARD_WDEV(card));
        ccw_device_set_offline(CARD_RDEV(card));
@@ -7480,6 +7584,12 @@ out_remove:
        return -ENODEV;
 }
 
+static int
+qeth_set_online(struct ccwgroup_device *gdev)
+{
+       return __qeth_set_online(gdev, 0);
+}
+
 static struct ccw_device_id qeth_ids[] = {
        {CCW_DEVICE(0x1731, 0x01), driver_info:QETH_CARD_TYPE_OSAE},
        {CCW_DEVICE(0x1731, 0x05), driver_info:QETH_CARD_TYPE_IQD},
diff --git a/drivers/s390/net/qeth_tso.c b/drivers/s390/net/qeth_tso.c
deleted file mode 100644 (file)
index c919762..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * linux/drivers/s390/net/qeth_tso.c ($Revision: 1.6 $)
- *
- * Header file for qeth TCP Segmentation Offload support.
- *
- * Copyright 2004 IBM Corporation
- *
- *    Author(s): Frank Pavlic <pavlic@de.ibm.com>
- *
- *    $Revision: 1.6 $  $Date: 2005/03/24 09:04:18 $
- *
- */
-
-#include <linux/skbuff.h>
-#include <linux/tcp.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <net/ip6_checksum.h>
-#include "qeth.h"
-#include "qeth_mpc.h"
-#include "qeth_tso.h"
-
-/**
- * skb already partially prepared
- * classic qdio header in skb->data
- * */
-static inline struct qeth_hdr_tso *
-qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
-{
-       int rc = 0;
-
-       QETH_DBF_TEXT(trace, 5, "tsoprsk");
-       rc = qeth_realloc_headroom(card, skb,sizeof(struct qeth_hdr_ext_tso));
-       if (rc)
-               return NULL;
-
-       return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_ext_tso));
-}
-
-/**
- * fill header for a TSO packet
- */
-static inline void
-qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb)
-{
-       struct qeth_hdr_tso *hdr;
-       struct tcphdr *tcph;
-       struct iphdr *iph;
-
-       QETH_DBF_TEXT(trace, 5, "tsofhdr");
-
-       hdr  = (struct qeth_hdr_tso *) skb->data;
-       iph  = skb->nh.iph;
-       tcph = skb->h.th;
-       /*fix header to TSO values ...*/
-       hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
-       /*set values which are fix for the first approach ...*/
-       hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
-       hdr->ext.imb_hdr_no  = 1;
-       hdr->ext.hdr_type    = 1;
-       hdr->ext.hdr_version = 1;
-       hdr->ext.hdr_len     = 28;
-       /*insert non-fix values */
-       hdr->ext.mss = skb_shinfo(skb)->tso_size;
-       hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
-       hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
-                                      sizeof(struct qeth_hdr_tso));
-}
-
-/**
- * change some header values as requested by hardware
- */
-static inline void
-qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb)
-{
-       struct iphdr *iph;
-       struct ipv6hdr *ip6h;
-       struct tcphdr *tcph;
-
-       iph  = skb->nh.iph;
-       ip6h = skb->nh.ipv6h;
-       tcph = skb->h.th;
-
-       tcph->check = 0;
-       if (skb->protocol == ETH_P_IPV6) {
-               ip6h->payload_len = 0;
-               tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
-                                              0, IPPROTO_TCP, 0);
-               return;
-       }
-       /*OSA want us to set these values ...*/
-       tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
-                                        0, IPPROTO_TCP, 0);
-       iph->tot_len = 0;
-       iph->check = 0;
-}
-
-static inline struct qeth_hdr_tso *
-qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb,
-                       int ipv, int cast_type)
-{
-       struct qeth_hdr_tso *hdr;
-       int rc = 0;
-
-       QETH_DBF_TEXT(trace, 5, "tsoprep");
-
-       /*get headroom for tso qdio header */
-       hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb);
-       if (hdr == NULL) {
-               QETH_DBF_TEXT_(trace, 4, "2err%d", rc);
-               return NULL;
-       }
-       memset(hdr, 0, sizeof(struct qeth_hdr_tso));
-       /*fill first 32 bytes of  qdio header as used
-        *FIXME: TSO has two struct members
-        * with different names but same size
-        * */
-       qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type);
-       qeth_tso_fill_header(card, skb);
-       qeth_tso_set_tcpip_header(card, skb);
-       return hdr;
-}
-
-static inline int
-qeth_tso_get_queue_buffer(struct qeth_qdio_out_q *queue)
-{
-       struct qeth_qdio_out_buffer *buffer;
-       int flush_cnt = 0;
-
-       QETH_DBF_TEXT(trace, 5, "tsobuf");
-
-       /* force to non-packing*/
-       if (queue->do_pack)
-               queue->do_pack = 0;
-       buffer = &queue->bufs[queue->next_buf_to_fill];
-       /* get a new buffer if current is already in use*/
-       if ((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) &&
-           (buffer->next_element_to_fill > 0)) {
-               atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
-               queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
-                                         QDIO_MAX_BUFFERS_PER_Q;
-               flush_cnt++;
-       }
-       return flush_cnt;
-}
-
-static inline void
-__qeth_tso_fill_buffer_frag(struct qeth_qdio_out_buffer *buf,
-                         struct sk_buff *skb)
-{
-       struct skb_frag_struct *frag;
-       struct qdio_buffer *buffer;
-       int fragno, cnt, element;
-       unsigned long addr;
-
-        QETH_DBF_TEXT(trace, 6, "tsfilfrg");
-
-       /*initialize variables ...*/
-       fragno = skb_shinfo(skb)->nr_frags;
-       buffer = buf->buffer;
-       element = buf->next_element_to_fill;
-       /*fill buffer elements .....*/
-       for (cnt = 0; cnt < fragno; cnt++) {
-               frag = &skb_shinfo(skb)->frags[cnt];
-               addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
-                       frag->page_offset;
-               buffer->element[element].addr = (char *)addr;
-               buffer->element[element].length = frag->size;
-               if (cnt < (fragno - 1))
-                       buffer->element[element].flags =
-                               SBAL_FLAGS_MIDDLE_FRAG;
-               else
-                       buffer->element[element].flags =
-                               SBAL_FLAGS_LAST_FRAG;
-               element++;
-       }
-       buf->next_element_to_fill = element;
-}
-
-static inline int
-qeth_tso_fill_buffer(struct qeth_qdio_out_buffer *buf,
-                    struct sk_buff *skb)
-{
-        int length, length_here, element;
-        int hdr_len;
-       struct qdio_buffer *buffer;
-       struct qeth_hdr_tso *hdr;
-       char *data;
-
-        QETH_DBF_TEXT(trace, 3, "tsfilbuf");
-
-       /*increment user count and queue skb ...*/
-        atomic_inc(&skb->users);
-        skb_queue_tail(&buf->skb_list, skb);
-
-       /*initialize all variables...*/
-        buffer = buf->buffer;
-       hdr = (struct qeth_hdr_tso *)skb->data;
-       hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len;
-       data = skb->data + hdr_len;
-       length = skb->len - hdr_len;
-        element = buf->next_element_to_fill;
-       /*fill first buffer entry only with header information */
-       buffer->element[element].addr = skb->data;
-       buffer->element[element].length = hdr_len;
-       buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
-       buf->next_element_to_fill++;
-
-       if (skb_shinfo(skb)->nr_frags > 0) {
-                 __qeth_tso_fill_buffer_frag(buf, skb);
-                 goto out;
-        }
-
-       /*start filling buffer entries ...*/
-        element++;
-        while (length > 0) {
-                /* length_here is the remaining amount of data in this page */
-               length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE);
-               if (length < length_here)
-                        length_here = length;
-                buffer->element[element].addr = data;
-                buffer->element[element].length = length_here;
-                length -= length_here;
-                if (!length)
-                        buffer->element[element].flags =
-                                SBAL_FLAGS_LAST_FRAG;
-                 else
-                         buffer->element[element].flags =
-                                 SBAL_FLAGS_MIDDLE_FRAG;
-                data += length_here;
-                element++;
-        }
-        /*set the buffer to primed  ...*/
-        buf->next_element_to_fill = element;
-out:
-       atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
-        return 1;
-}
-
-int
-qeth_tso_send_packet(struct qeth_card *card, struct sk_buff *skb,
-                    struct qeth_qdio_out_q *queue, int ipv, int cast_type)
-{
-       int flush_cnt = 0;
-       struct qeth_hdr_tso *hdr;
-       struct qeth_qdio_out_buffer *buffer;
-        int start_index;
-
-       QETH_DBF_TEXT(trace, 3, "tsosend");
-
-       if (!(hdr = qeth_tso_prepare_packet(card, skb, ipv, cast_type)))
-               return -ENOMEM;
-       /*check if skb fits in one SBAL ...*/
-       if (!(qeth_get_elements_no(card, (void*)hdr, skb)))
-               return -EINVAL;
-       /*lock queue, force switching to non-packing and send it ...*/
-       while (atomic_compare_and_swap(QETH_OUT_Q_UNLOCKED,
-                                       QETH_OUT_Q_LOCKED,
-                                       &queue->state));
-        start_index = queue->next_buf_to_fill;
-        buffer = &queue->bufs[queue->next_buf_to_fill];
-       /*check if card is too busy ...*/
-       if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){
-               card->stats.tx_dropped++;
-               goto out;
-       }
-       /*let's force to non-packing and get a new SBAL*/
-       flush_cnt += qeth_tso_get_queue_buffer(queue);
-       buffer = &queue->bufs[queue->next_buf_to_fill];
-       if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
-               card->stats.tx_dropped++;
-               goto out;
-       }
-       flush_cnt += qeth_tso_fill_buffer(buffer, skb);
-       queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
-                                  QDIO_MAX_BUFFERS_PER_Q;
-out:
-       atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
-       if (flush_cnt)
-               qeth_flush_buffers(queue, 0, start_index, flush_cnt);
-       /*do some statistics */
-       card->stats.tx_packets++;
-       card->stats.tx_bytes += skb->len;
-       return 0;
-}
index 83504dee3f57d9d72ee963772a3d63429bd729c7..ad33e6f466f1bd819547f687e5b9e719a6c19f5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.4 $)
+ * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.7 $)
  *
  * Header file for qeth TCP Segmentation Offload support.
  *
  *
  *    Author(s): Frank Pavlic <pavlic@de.ibm.com>
  *
- *    $Revision: 1.4 $  $Date: 2005/03/24 09:04:18 $
+ *    $Revision: 1.7 $  $Date: 2005/05/04 20:19:18 $
  *
  */
 #ifndef __QETH_TSO_H__
 #define __QETH_TSO_H__
 
+#include <linux/skbuff.h>
+#include <linux/tcp.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <net/ip6_checksum.h>
+#include "qeth.h"
+#include "qeth_mpc.h"
 
-extern int
-qeth_tso_send_packet(struct qeth_card *, struct sk_buff *,
-                    struct qeth_qdio_out_q *, int , int);
 
-struct qeth_hdr_ext_tso {
-        __u16 hdr_tot_len;
-        __u8  imb_hdr_no;
-        __u8  reserved;
-        __u8  hdr_type;
-        __u8  hdr_version;
-        __u16 hdr_len;
-        __u32 payload_len;
-        __u16 mss;
-        __u16 dg_hdr_len;
-        __u8  padding[16];
-} __attribute__ ((packed));
+static inline struct qeth_hdr_tso *
+qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
+{
+       QETH_DBF_TEXT(trace, 5, "tsoprsk");
+       return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_tso));
+}
+
+/**
+ * fill header for a TSO packet
+ */
+static inline void
+qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb)
+{
+       struct qeth_hdr_tso *hdr;
+       struct tcphdr *tcph;
+       struct iphdr *iph;
+
+       QETH_DBF_TEXT(trace, 5, "tsofhdr");
+
+       hdr  = (struct qeth_hdr_tso *) skb->data;
+       iph  = skb->nh.iph;
+       tcph = skb->h.th;
+       /*fix header to TSO values ...*/
+       hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
+       /*set values which are fix for the first approach ...*/
+       hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
+       hdr->ext.imb_hdr_no  = 1;
+       hdr->ext.hdr_type    = 1;
+       hdr->ext.hdr_version = 1;
+       hdr->ext.hdr_len     = 28;
+       /*insert non-fix values */
+       hdr->ext.mss = skb_shinfo(skb)->tso_size;
+       hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
+       hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
+                                      sizeof(struct qeth_hdr_tso));
+}
+
+/**
+ * change some header values as requested by hardware
+ */
+static inline void
+qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb)
+{
+       struct iphdr *iph;
+       struct ipv6hdr *ip6h;
+       struct tcphdr *tcph;
 
-struct qeth_hdr_tso {
-        struct qeth_hdr hdr;   /*hdr->hdr.l3.xxx*/
-       struct qeth_hdr_ext_tso ext;
-} __attribute__ ((packed));
+       iph  = skb->nh.iph;
+       ip6h = skb->nh.ipv6h;
+       tcph = skb->h.th;
 
-/*some helper functions*/
+       tcph->check = 0;
+       if (skb->protocol == ETH_P_IPV6) {
+               ip6h->payload_len = 0;
+               tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
+                                              0, IPPROTO_TCP, 0);
+               return;
+       }
+       /*OSA want us to set these values ...*/
+       tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
+                                        0, IPPROTO_TCP, 0);
+       iph->tot_len = 0;
+       iph->check = 0;
+}
 
 static inline int
-qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb)
+qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb,
+                       int ipv, int cast_type)
+{
+       struct qeth_hdr_tso *hdr;
+
+       QETH_DBF_TEXT(trace, 5, "tsoprep");
+
+       hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb);
+       if (hdr == NULL) {
+               QETH_DBF_TEXT(trace, 4, "tsoperr");
+               return -ENOMEM;
+       }
+       memset(hdr, 0, sizeof(struct qeth_hdr_tso));
+       /*fill first 32 bytes of  qdio header as used
+        *FIXME: TSO has two struct members
+        * with different names but same size
+        * */
+       qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type);
+       qeth_tso_fill_header(card, skb);
+       qeth_tso_set_tcpip_header(card, skb);
+       return 0;
+}
+
+static inline void
+__qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer,
+                       int is_tso, int *next_element_to_fill)
 {
-       int elements_needed = 0;
-
-       if (skb_shinfo(skb)->nr_frags > 0)
-               elements_needed = (skb_shinfo(skb)->nr_frags + 1);
-       if (elements_needed == 0 )
-               elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
-                                       + skb->len) >> PAGE_SHIFT);
-       if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){
-               PRINT_ERR("qeth_do_send_packet: invalid size of "
-                         "IP packet. Discarded.");
-               return 0;
+       struct skb_frag_struct *frag;
+       int fragno;
+       unsigned long addr;
+       int element, cnt, dlen;
+       
+       fragno = skb_shinfo(skb)->nr_frags;
+       element = *next_element_to_fill;
+       dlen = 0;
+       
+       if (is_tso)
+               buffer->element[element].flags =
+                       SBAL_FLAGS_MIDDLE_FRAG;
+       else
+               buffer->element[element].flags =
+                       SBAL_FLAGS_FIRST_FRAG;
+       if ( (dlen = (skb->len - skb->data_len)) ) {
+               buffer->element[element].addr = skb->data;
+               buffer->element[element].length = dlen;
+               element++;
+       }
+       for (cnt = 0; cnt < fragno; cnt++) {
+               frag = &skb_shinfo(skb)->frags[cnt];
+               addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
+                       frag->page_offset;
+               buffer->element[element].addr = (char *)addr;
+               buffer->element[element].length = frag->size;
+               if (cnt < (fragno - 1))
+                       buffer->element[element].flags =
+                               SBAL_FLAGS_MIDDLE_FRAG;
+               else
+                       buffer->element[element].flags =
+                               SBAL_FLAGS_LAST_FRAG;
+               element++;
        }
-       return elements_needed;
+       *next_element_to_fill = element;
 }
 #endif /* __QETH_TSO_H__ */
index 1f9aeb4accc60cc80f810125083e860dbf74dc3f..68d151aaa4749f893294d4a04150f57c59b6f509 100644 (file)
@@ -52,7 +52,7 @@ static inline int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *,
 static inline int zfcp_sg_list_copy_to_user(void __user *,
                                            struct zfcp_sg_list *, size_t);
 
-static int zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long);
+static long zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long);
 
 #define ZFCP_CFDC_IOC_MAGIC                     0xDD
 #define ZFCP_CFDC_IOC \
index 0afa1c4696ca6b5f7ae4c1356ad7b640f8c8b8cc..c5daf372f853d556c83abcf2ad475d65fda581b5 100644 (file)
@@ -61,7 +61,6 @@
 #include <linux/mempool.h>
 #include <linux/syscalls.h>
 #include <linux/ioctl.h>
-#include <linux/ioctl32.h>
 
 /************************ DEBUG FLAGS *****************************************/
 
index e5fa1703856bf94858f327377fec588d71779788..650d5e924f4714c1d0c00f4777c1fad58559c645 100644 (file)
@@ -81,10 +81,6 @@ unsigned char irqs[4] = {
 int irqhit=0;
 #endif
 
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
 static struct tty_driver *aurora_driver;
 static struct Aurora_board aurora_board[AURORA_NBOARD] = {
        {0,},
@@ -594,7 +590,7 @@ static void aurora_transmit(struct Aurora_board const * bp, int chip)
                                            &bp->r[chip]->r[CD180_TDR]);
                                port->COR2 &= ~COR2_ETC;
                        }
-                       count = MIN(port->break_length, 0xff);
+                       count = min(port->break_length, 0xff);
                        sbus_writeb(CD180_C_ESC,
                                    &bp->r[chip]->r[CD180_TDR]);
                        sbus_writeb(CD180_C_DELAY,
@@ -1575,7 +1571,7 @@ static int aurora_write(struct tty_struct * tty,
        save_flags(flags);
        while (1) {
                cli();
-               c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+               c = min(count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
                                   SERIAL_XMIT_SIZE - port->xmit_head));
                if (c <= 0) {
                        restore_flags(flags);
index 750b11cefd934349480d6237f6df564edf6d297b..27fec8a5eb5bff4642c28160fb4d0ad6941dcd15 100644 (file)
@@ -260,7 +260,7 @@ config SCSI_3W_9XXX
 
 config SCSI_7000FASST
        tristate "7000FASST SCSI support"
-       depends on ISA && SCSI
+       depends on ISA && SCSI && ISA_DMA_API
        help
          This driver supports the Western Digital 7000 SCSI host adapter
          family.  Some information is in the source:
@@ -295,7 +295,7 @@ config SCSI_AHA152X
 
 config SCSI_AHA1542
        tristate "Adaptec AHA1542 support"
-       depends on ISA && SCSI
+       depends on ISA && SCSI && ISA_DMA_API
        ---help---
          This is support for a SCSI host adapter.  It is explained in section
          3.4 of the SCSI-HOWTO, available from
@@ -515,7 +515,7 @@ config SCSI_SATA_VITESSE
 
 config SCSI_BUSLOGIC
        tristate "BusLogic SCSI support"
-       depends on (PCI || ISA || MCA) && SCSI && (BROKEN || !SPARC64)
+       depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API
        ---help---
          This is support for BusLogic MultiMaster and FlashPoint SCSI Host
          Adapters. Consult the SCSI-HOWTO, available from
@@ -571,7 +571,7 @@ config SCSI_DTC3280
 
 config SCSI_EATA
        tristate "EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support"
-       depends on (ISA || EISA || PCI) && SCSI && (BROKEN || !SPARC64)
+       depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API
        ---help---
          This driver supports all EATA/DMA-compliant SCSI host adapters.  DPT
          ISA and all EISA I/O addresses are probed looking for the "EATA"
@@ -665,7 +665,7 @@ config SCSI_FD_MCS
 
 config SCSI_GDTH
        tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support"
-       depends on (ISA || EISA || PCI) && SCSI && (BROKEN || !SPARC64)
+       depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API
        ---help---
          Formerly called GDT SCSI Disk Array Controller Support.
 
@@ -1416,7 +1416,7 @@ config SCSI_T128
 
 config SCSI_U14_34F
        tristate "UltraStor 14F/34F support"
-       depends on ISA && SCSI
+       depends on ISA && SCSI && ISA_DMA_API
        ---help---
          This is support for the UltraStor 14F and 34F SCSI-2 host adapters.
          The source at <file:drivers/scsi/u14-34f.c> contains some
@@ -1752,7 +1752,7 @@ config SCSI_NCR53C7xx_FAST
 
 config SUN3_SCSI
        tristate "Sun3 NCR5380 SCSI"
-       depends on SUN3 && SCSI
+       depends on SUN3 && SCSI && BROKEN
        help
          This option will enable support for the OBIO (onboard io) NCR5380
          SCSI controller found in the Sun 3/50 and 3/60, as well as for
index 3c86655a5f337676f458fd64e2f4cded73c52c44..74b93564a258fdc44ee45e73c833a157b31ec0f5 100644 (file)
@@ -1824,7 +1824,10 @@ static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs)
                /* loop */
                while (hmuch) {
                        int j, fifo_stuck = 0, newphase;
-                       unsigned long flags, timeout;
+                       unsigned long timeout;
+#if 0
+                       unsigned long flags;
+#endif
 #if 0
                        if ( i % 10 )
                                ESPDATA(("\r"));
index c9b82687ba1aa5c59bd3bfd2d5fda40d7d3ea762..242fa77513f5a6e3502d2ae12cf3be65ff82853c 100644 (file)
@@ -450,7 +450,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
                }
        }
 
-       return 0;
+       return err;
 }
 
 /**
index da5bd33d982d7e521b6b0603adcb0911395b184d..fc5263c6b10267b2869cf8b3a1967b97490b392b 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/dma-mapping.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -289,6 +290,8 @@ static void ahci_host_stop(struct ata_host_set *host_set)
 {
        struct ahci_host_priv *hpriv = host_set->private_data;
        kfree(hpriv);
+
+       ata_host_stop(host_set);
 }
 
 static int ahci_port_start(struct ata_port *ap)
index c2b47f2bdffdf489233c3d6c106ac75c893c7844..682ca0b32b44b33b0cedbb8a469ee0ec78dccc6f 100644 (file)
@@ -41,7 +41,6 @@
 
 #include "aic7xxx_osm.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #include <linux/device.h>
 #include <linux/eisa.h>
 
@@ -62,13 +61,6 @@ static struct eisa_driver aic7770_driver = {
 };
 
 typedef  struct device *aic7770_dev_t;
-#else
-#define MINSLOT                        1
-#define NUMSLOTS               16
-#define IDOFFSET               0x80
-
-typedef void *aic7770_dev_t;
-#endif
 
 static int aic7770_linux_config(struct aic7770_identity *entry,
                                aic7770_dev_t dev, u_int eisaBase);
@@ -76,7 +68,6 @@ static int aic7770_linux_config(struct aic7770_identity *entry,
 int
 ahc_linux_eisa_init(void)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        struct eisa_device_id *eid;
        struct aic7770_identity *id;
        int i;
@@ -110,44 +101,6 @@ ahc_linux_eisa_init(void)
        eid->sig[0] = 0;
 
        return eisa_driver_register(&aic7770_driver);
-#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */
-       struct aic7770_identity *entry;
-       u_int  slot;
-       u_int  eisaBase;
-       u_int  i;
-       int ret = -ENODEV;
-
-       if (aic7xxx_probe_eisa_vl == 0)
-               return ret;
-
-       eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
-       for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
-               uint32_t eisa_id;
-               size_t   id_size;
-
-               if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0)
-                       continue;
-
-               eisa_id = 0;
-               id_size = sizeof(eisa_id);
-               for (i = 0; i < 4; i++) {
-                       /* VLcards require priming*/
-                       outb(0x80 + i, eisaBase + IDOFFSET);
-                       eisa_id |= inb(eisaBase + IDOFFSET + i)
-                                  << ((id_size-i-1) * 8);
-               }
-               release_region(eisaBase, AHC_EISA_IOSIZE);
-               if (eisa_id & 0x80000000)
-                       continue;  /* no EISA card in slot */
-
-               entry = aic7770_find_device(eisa_id);
-               if (entry != NULL) {
-                       aic7770_linux_config(entry, NULL, eisaBase);
-                       ret = 0;
-               }
-       }
-       return ret;
-#endif
 }
 
 void
@@ -187,11 +140,10 @@ aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev,
                ahc_free(ahc);
                return (error);
        }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+
        dev->driver_data = (void *)ahc;
        if (aic7xxx_detect_complete)
                error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
-#endif
        return (error);
 }
 
@@ -225,7 +177,6 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq)
        return (-error);
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static int
 aic7770_eisa_dev_probe(struct device *dev)
 {
@@ -261,4 +212,3 @@ aic7770_eisa_dev_remove(struct device *dev)
 
        return (0);
 }
-#endif
index 550c9921691ad8df96602bf833d2c28ba7eba411..7c02b7dc7098869d0eba696477c1c35fef3f0693 100644 (file)
@@ -2488,7 +2488,7 @@ ahd_linux_dv_thread(void *data)
        sprintf(current->comm, "ahd_dv_%d", ahd->unit);
 #else
        daemonize("ahd_dv_%d", ahd->unit);
-       current->flags |= PF_FREEZE;
+       current->flags |= PF_NOFREEZE;
 #endif
        unlock_kernel();
 
index e60f9338e44ad4a2eb938adcc70a491c9a09815d..c13e56320010cc641f09db992e9cbb5599967ca7 100644 (file)
@@ -134,11 +134,6 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL;
 #include "aiclib.c"
 
 #include <linux/init.h>                /* __setup */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include "sd.h"                        /* For geometry detection */
-#endif
-
 #include <linux/mm.h>          /* For fetching system memory size */
 #include <linux/blkdev.h>              /* For block_size() */
 #include <linux/delay.h>       /* For ssleep/msleep */
@@ -148,11 +143,6 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL;
  */
 spinlock_t ahc_list_spinlock;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-/* For dynamic sglist size calculation. */
-u_int ahc_linux_nseg;
-#endif
-
 /*
  * Set this to the delay in seconds after SCSI bus reset.
  * Note, we honor this only for the initial bus reset.
@@ -436,15 +426,12 @@ static void ahc_linux_handle_scsi_status(struct ahc_softc *,
                                         struct ahc_linux_device *,
                                         struct scb *);
 static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
-                                        Scsi_Cmnd *cmd);
+                                        struct scsi_cmnd *cmd);
 static void ahc_linux_sem_timeout(u_long arg);
 static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
 static void ahc_linux_release_simq(u_long arg);
-static void ahc_linux_dev_timed_unfreeze(u_long arg);
-static int  ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag);
+static int  ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
 static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
-static void ahc_linux_size_nseg(void);
-static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc);
 static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
                                     struct ahc_devinfo *devinfo);
 static void ahc_linux_device_queue_depth(struct ahc_softc *ahc,
@@ -458,54 +445,27 @@ static struct ahc_linux_device*   ahc_linux_alloc_device(struct ahc_softc*,
                                                       u_int);
 static void                    ahc_linux_free_device(struct ahc_softc*,
                                                      struct ahc_linux_device*);
-static void ahc_linux_run_device_queue(struct ahc_softc*,
-                                      struct ahc_linux_device*);
+static int ahc_linux_run_command(struct ahc_softc*,
+                                struct ahc_linux_device *,
+                                struct scsi_cmnd *);
 static void ahc_linux_setup_tag_info_global(char *p);
 static aic_option_callback_t ahc_linux_setup_tag_info;
 static int  aic7xxx_setup(char *s);
 static int  ahc_linux_next_unit(void);
-static void ahc_runq_tasklet(unsigned long data);
-static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc);
 
 /********************************* Inlines ************************************/
-static __inline void ahc_schedule_runq(struct ahc_softc *ahc);
 static __inline struct ahc_linux_device*
                     ahc_linux_get_device(struct ahc_softc *ahc, u_int channel,
-                                         u_int target, u_int lun, int alloc);
-static __inline void ahc_schedule_completeq(struct ahc_softc *ahc);
-static __inline void ahc_linux_check_device_queue(struct ahc_softc *ahc,
-                                                 struct ahc_linux_device *dev);
-static __inline struct ahc_linux_device *
-                    ahc_linux_next_device_to_run(struct ahc_softc *ahc);
-static __inline void ahc_linux_run_device_queues(struct ahc_softc *ahc);
+                                         u_int target, u_int lun);
 static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
 
 static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
                                      struct ahc_dma_seg *sg,
                                      dma_addr_t addr, bus_size_t len);
 
-static __inline void
-ahc_schedule_completeq(struct ahc_softc *ahc)
-{
-       if ((ahc->platform_data->flags & AHC_RUN_CMPLT_Q_TIMER) == 0) {
-               ahc->platform_data->flags |= AHC_RUN_CMPLT_Q_TIMER;
-               ahc->platform_data->completeq_timer.expires = jiffies;
-               add_timer(&ahc->platform_data->completeq_timer);
-       }
-}
-
-/*
- * Must be called with our lock held.
- */
-static __inline void
-ahc_schedule_runq(struct ahc_softc *ahc)
-{
-       tasklet_schedule(&ahc->platform_data->runq_tasklet);
-}
-
 static __inline struct ahc_linux_device*
 ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
-                    u_int lun, int alloc)
+                    u_int lun)
 {
        struct ahc_linux_target *targ;
        struct ahc_linux_device *dev;
@@ -515,102 +475,15 @@ ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
        if (channel != 0)
                target_offset += 8;
        targ = ahc->platform_data->targets[target_offset];
-       if (targ == NULL) {
-               if (alloc != 0) {
-                       targ = ahc_linux_alloc_target(ahc, channel, target);
-                       if (targ == NULL)
-                               return (NULL);
-               } else
-                       return (NULL);
-       }
+       BUG_ON(targ == NULL);
        dev = targ->devices[lun];
-       if (dev == NULL && alloc != 0)
-               dev = ahc_linux_alloc_device(ahc, targ, lun);
-       return (dev);
-}
-
-#define AHC_LINUX_MAX_RETURNED_ERRORS 4
-static struct ahc_cmd *
-ahc_linux_run_complete_queue(struct ahc_softc *ahc)
-{
-       struct  ahc_cmd *acmd;
-       u_long  done_flags;
-       int     with_errors;
-
-       with_errors = 0;
-       ahc_done_lock(ahc, &done_flags);
-       while ((acmd = TAILQ_FIRST(&ahc->platform_data->completeq)) != NULL) {
-               Scsi_Cmnd *cmd;
-
-               if (with_errors > AHC_LINUX_MAX_RETURNED_ERRORS) {
-                       /*
-                        * Linux uses stack recursion to requeue
-                        * commands that need to be retried.  Avoid
-                        * blowing out the stack by "spoon feeding"
-                        * commands that completed with error back
-                        * the operating system in case they are going
-                        * to be retried. "ick"
-                        */
-                       ahc_schedule_completeq(ahc);
-                       break;
-               }
-               TAILQ_REMOVE(&ahc->platform_data->completeq,
-                            acmd, acmd_links.tqe);
-               cmd = &acmd_scsi_cmd(acmd);
-               cmd->host_scribble = NULL;
-               if (ahc_cmd_get_transaction_status(cmd) != DID_OK
-                || (cmd->result & 0xFF) != SCSI_STATUS_OK)
-                       with_errors++;
-
-               cmd->scsi_done(cmd);
-       }
-       ahc_done_unlock(ahc, &done_flags);
-       return (acmd);
-}
-
-static __inline void
-ahc_linux_check_device_queue(struct ahc_softc *ahc,
-                            struct ahc_linux_device *dev)
-{
-       if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) != 0
-        && dev->active == 0) {
-               dev->flags &= ~AHC_DEV_FREEZE_TIL_EMPTY;
-               dev->qfrozen--;
-       }
-
-       if (TAILQ_FIRST(&dev->busyq) == NULL
-        || dev->openings == 0 || dev->qfrozen != 0)
-               return;
-
-       ahc_linux_run_device_queue(ahc, dev);
-}
-
-static __inline struct ahc_linux_device *
-ahc_linux_next_device_to_run(struct ahc_softc *ahc)
-{
-       
-       if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0
-           || (ahc->platform_data->qfrozen != 0))
-               return (NULL);
-       return (TAILQ_FIRST(&ahc->platform_data->device_runq));
-}
-
-static __inline void
-ahc_linux_run_device_queues(struct ahc_softc *ahc)
-{
-       struct ahc_linux_device *dev;
-
-       while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) {
-               TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links);
-               dev->flags &= ~AHC_DEV_ON_RUN_LIST;
-               ahc_linux_check_device_queue(ahc, dev);
-       }
+       return dev;
 }
 
 static __inline void
 ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
 {
-       Scsi_Cmnd *cmd;
+       struct scsi_cmnd *cmd;
 
        cmd = scb->io_ctx;
        ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE);
@@ -650,109 +523,15 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
        return (consumed);
 }
 
-/************************  Host template entry points *************************/
-static int        ahc_linux_detect(Scsi_Host_Template *);
-static int        ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
-static const char *ahc_linux_info(struct Scsi_Host *);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static int        ahc_linux_slave_alloc(Scsi_Device *);
-static int        ahc_linux_slave_configure(Scsi_Device *);
-static void       ahc_linux_slave_destroy(Scsi_Device *);
-#if defined(__i386__)
-static int        ahc_linux_biosparam(struct scsi_device*,
-                                      struct block_device*,
-                                      sector_t, int[]);
-#endif
-#else
-static int        ahc_linux_release(struct Scsi_Host *);
-static void       ahc_linux_select_queue_depth(struct Scsi_Host *host,
-                                               Scsi_Device *scsi_devs);
-#if defined(__i386__)
-static int        ahc_linux_biosparam(Disk *, kdev_t, int[]);
-#endif
-#endif
-static int        ahc_linux_bus_reset(Scsi_Cmnd *);
-static int        ahc_linux_dev_reset(Scsi_Cmnd *);
-static int        ahc_linux_abort(Scsi_Cmnd *);
-
-/*
- * Calculate a safe value for AHC_NSEG (as expressed through ahc_linux_nseg).
- *
- * In pre-2.5.X...
- * The midlayer allocates an S/G array dynamically when a command is issued
- * using SCSI malloc.  This array, which is in an OS dependent format that
- * must later be copied to our private S/G list, is sized to house just the
- * number of segments needed for the current transfer.  Since the code that
- * sizes the SCSI malloc pool does not take into consideration fragmentation
- * of the pool, executing transactions numbering just a fraction of our
- * concurrent transaction limit with list lengths aproaching AHC_NSEG will
- * quickly depleat the SCSI malloc pool of usable space.  Unfortunately, the
- * mid-layer does not properly handle this scsi malloc failures for the S/G
- * array and the result can be a lockup of the I/O subsystem.  We try to size
- * our S/G list so that it satisfies our drivers allocation requirements in
- * addition to avoiding fragmentation of the SCSI malloc pool.
- */
-static void
-ahc_linux_size_nseg(void)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       u_int cur_size;
-       u_int best_size;
-
-       /*
-        * The SCSI allocator rounds to the nearest 512 bytes
-        * an cannot allocate across a page boundary.  Our algorithm
-        * is to start at 1K of scsi malloc space per-command and
-        * loop through all factors of the PAGE_SIZE and pick the best.
-        */
-       best_size = 0;
-       for (cur_size = 1024; cur_size <= PAGE_SIZE; cur_size *= 2) {
-               u_int nseg;
-
-               nseg = cur_size / sizeof(struct scatterlist);
-               if (nseg < AHC_LINUX_MIN_NSEG)
-                       continue;
-
-               if (best_size == 0) {
-                       best_size = cur_size;
-                       ahc_linux_nseg = nseg;
-               } else {
-                       u_int best_rem;
-                       u_int cur_rem;
-
-                       /*
-                        * Compare the traits of the current "best_size"
-                        * with the current size to determine if the
-                        * current size is a better size.
-                        */
-                       best_rem = best_size % sizeof(struct scatterlist);
-                       cur_rem = cur_size % sizeof(struct scatterlist);
-                       if (cur_rem < best_rem) {
-                               best_size = cur_size;
-                               ahc_linux_nseg = nseg;
-                       }
-               }
-       }
-#endif
-}
-
 /*
  * Try to detect an Adaptec 7XXX controller.
  */
 static int
-ahc_linux_detect(Scsi_Host_Template *template)
+ahc_linux_detect(struct scsi_host_template *template)
 {
        struct  ahc_softc *ahc;
        int     found = 0;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       /*
-        * It is a bug that the upper layer takes
-        * this lock just prior to calling us.
-        */
-       spin_unlock_irq(&io_request_lock);
-#endif
-
        /*
         * Sanity checking of Linux SCSI data structures so
         * that some of our hacks^H^H^H^H^Hassumptions aren't
@@ -764,7 +543,6 @@ ahc_linux_detect(Scsi_Host_Template *template)
                printf("ahc_linux_detect: Unable to attach\n");
                return (0);
        }
-       ahc_linux_size_nseg();
        /*
         * If we've been passed any parameters, process them now.
         */
@@ -793,48 +571,11 @@ ahc_linux_detect(Scsi_Host_Template *template)
                        found++;
        }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       spin_lock_irq(&io_request_lock);
-#endif
        aic7xxx_detect_complete++;
 
        return (found);
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-/*
- * Free the passed in Scsi_Host memory structures prior to unloading the
- * module.
- */
-int
-ahc_linux_release(struct Scsi_Host * host)
-{
-       struct ahc_softc *ahc;
-       u_long l;
-
-       ahc_list_lock(&l);
-       if (host != NULL) {
-
-               /*
-                * We should be able to just perform
-                * the free directly, but check our
-                * list for extra sanity.
-                */
-               ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata);
-               if (ahc != NULL) {
-                       u_long s;
-
-                       ahc_lock(ahc, &s);
-                       ahc_intr_enable(ahc, FALSE);
-                       ahc_unlock(ahc, &s);
-                       ahc_free(ahc);
-               }
-       }
-       ahc_list_unlock(&l);
-       return (0);
-}
-#endif
-
 /*
  * Return a string describing the driver.
  */
@@ -867,11 +608,10 @@ ahc_linux_info(struct Scsi_Host *host)
  * Queue an SCB to the controller.
  */
 static int
-ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
+ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
 {
        struct   ahc_softc *ahc;
        struct   ahc_linux_device *dev;
-       u_long   flags;
 
        ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
 
@@ -880,205 +620,152 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
         */
        cmd->scsi_done = scsi_done;
 
-       ahc_midlayer_entrypoint_lock(ahc, &flags);
-
        /*
         * Close the race of a command that was in the process of
         * being queued to us just as our simq was frozen.  Let
         * DV commands through so long as we are only frozen to
         * perform DV.
         */
-       if (ahc->platform_data->qfrozen != 0) {
+       if (ahc->platform_data->qfrozen != 0)
+               return SCSI_MLQUEUE_HOST_BUSY;
 
-               ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
-               ahc_linux_queue_cmd_complete(ahc, cmd);
-               ahc_schedule_completeq(ahc);
-               ahc_midlayer_entrypoint_unlock(ahc, &flags);
-               return (0);
-       }
        dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
-                                  cmd->device->lun, /*alloc*/TRUE);
-       if (dev == NULL) {
-               ahc_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
-               ahc_linux_queue_cmd_complete(ahc, cmd);
-               ahc_schedule_completeq(ahc);
-               ahc_midlayer_entrypoint_unlock(ahc, &flags);
-               printf("%s: aic7xxx_linux_queue - Unable to allocate device!\n",
-                      ahc_name(ahc));
-               return (0);
-       }
+                                  cmd->device->lun);
+       BUG_ON(dev == NULL);
+
        cmd->result = CAM_REQ_INPROG << 16;
-       TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe);
-       if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
-               TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
-               dev->flags |= AHC_DEV_ON_RUN_LIST;
-               ahc_linux_run_device_queues(ahc);
-       }
-       ahc_midlayer_entrypoint_unlock(ahc, &flags);
-       return (0);
+
+       return ahc_linux_run_command(ahc, dev, cmd);
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static int
-ahc_linux_slave_alloc(Scsi_Device *device)
+ahc_linux_slave_alloc(struct scsi_device *device)
 {
        struct  ahc_softc *ahc;
+       struct ahc_linux_target *targ;
+       struct scsi_target *starget = device->sdev_target;
+       struct ahc_linux_device *dev;
+       unsigned int target_offset;
+       unsigned long flags;
+       int retval = -ENOMEM;
+
+       target_offset = starget->id;
+       if (starget->channel != 0)
+               target_offset += 8;
 
        ahc = *((struct ahc_softc **)device->host->hostdata);
        if (bootverbose)
                printf("%s: Slave Alloc %d\n", ahc_name(ahc), device->id);
-       return (0);
+       ahc_lock(ahc, &flags);
+       targ = ahc->platform_data->targets[target_offset];
+       if (targ == NULL) {
+               struct seeprom_config *sc;
+
+               targ = ahc_linux_alloc_target(ahc, starget->channel,
+                                               starget->id);
+               sc = ahc->seep_config;
+               if (targ == NULL)
+                       goto out;
+
+               if (sc) {
+                       unsigned short scsirate;
+                       struct ahc_devinfo devinfo;
+                       struct ahc_initiator_tinfo *tinfo;
+                       struct ahc_tmode_tstate *tstate;
+                       char channel = starget->channel + 'A';
+                       unsigned int our_id = ahc->our_id;
+
+                       if (starget->channel)
+                               our_id = ahc->our_id_b;
+
+                       if ((ahc->features & AHC_ULTRA2) != 0) {
+                               scsirate = sc->device_flags[target_offset] & CFXFER;
+                       } else {
+                               scsirate = (sc->device_flags[target_offset] & CFXFER) << 4;
+                               if (sc->device_flags[target_offset] & CFSYNCH)
+                                       scsirate |= SOFS;
+                       }
+                       if (sc->device_flags[target_offset] & CFWIDEB) {
+                               scsirate |= WIDEXFER;
+                               spi_max_width(starget) = 1;
+                       } else
+                               spi_max_width(starget) = 0;
+                       spi_min_period(starget) = 
+                               ahc_find_period(ahc, scsirate, AHC_SYNCRATE_DT);
+                       tinfo = ahc_fetch_transinfo(ahc, channel, ahc->our_id,
+                                                   targ->target, &tstate);
+                       ahc_compile_devinfo(&devinfo, our_id, targ->target,
+                                           CAM_LUN_WILDCARD, channel,
+                                           ROLE_INITIATOR);
+                       ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
+                                        AHC_TRANS_GOAL, /*paused*/FALSE);
+                       ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
+                                     AHC_TRANS_GOAL, /*paused*/FALSE);
+               }
+                       
+       }
+       dev = targ->devices[device->lun];
+       if (dev == NULL) {
+               dev = ahc_linux_alloc_device(ahc, targ, device->lun);
+               if (dev == NULL)
+                       goto out;
+       }
+       retval = 0;
+
+ out:
+       ahc_unlock(ahc, &flags);
+       return retval;
 }
 
 static int
-ahc_linux_slave_configure(Scsi_Device *device)
+ahc_linux_slave_configure(struct scsi_device *device)
 {
        struct  ahc_softc *ahc;
        struct  ahc_linux_device *dev;
-       u_long  flags;
 
        ahc = *((struct ahc_softc **)device->host->hostdata);
+
        if (bootverbose)
                printf("%s: Slave Configure %d\n", ahc_name(ahc), device->id);
-       ahc_midlayer_entrypoint_lock(ahc, &flags);
-       /*
-        * Since Linux has attached to the device, configure
-        * it so we don't free and allocate the device
-        * structure on every command.
-        */
-       dev = ahc_linux_get_device(ahc, device->channel,
-                                  device->id, device->lun,
-                                  /*alloc*/TRUE);
-       if (dev != NULL) {
-               dev->flags &= ~AHC_DEV_UNCONFIGURED;
-               dev->scsi_device = device;
-               ahc_linux_device_queue_depth(ahc, dev);
-       }
-       ahc_midlayer_entrypoint_unlock(ahc, &flags);
+
+       dev = ahc_linux_get_device(ahc, device->channel, device->id,
+                                  device->lun);
+       dev->scsi_device = device;
+       ahc_linux_device_queue_depth(ahc, dev);
 
        /* Initial Domain Validation */
        if (!spi_initial_dv(device->sdev_target))
                spi_dv_device(device);
 
-       return (0);
+       return 0;
 }
 
 static void
-ahc_linux_slave_destroy(Scsi_Device *device)
+ahc_linux_slave_destroy(struct scsi_device *device)
 {
        struct  ahc_softc *ahc;
        struct  ahc_linux_device *dev;
-       u_long  flags;
 
        ahc = *((struct ahc_softc **)device->host->hostdata);
        if (bootverbose)
                printf("%s: Slave Destroy %d\n", ahc_name(ahc), device->id);
-       ahc_midlayer_entrypoint_lock(ahc, &flags);
        dev = ahc_linux_get_device(ahc, device->channel,
-                                  device->id, device->lun,
-                                          /*alloc*/FALSE);
-       /*
-        * Filter out "silly" deletions of real devices by only
-        * deleting devices that have had slave_configure()
-        * called on them.  All other devices that have not
-        * been configured will automatically be deleted by
-        * the refcounting process.
-        */
-       if (dev != NULL
-        && (dev->flags & AHC_DEV_SLAVE_CONFIGURED) != 0) {
-               dev->flags |= AHC_DEV_UNCONFIGURED;
-               if (TAILQ_EMPTY(&dev->busyq)
-                && dev->active == 0
-                && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0)
-                       ahc_linux_free_device(ahc, dev);
-       }
-       ahc_midlayer_entrypoint_unlock(ahc, &flags);
-}
-#else
-/*
- * Sets the queue depth for each SCSI device hanging
- * off the input host adapter.
- */
-static void
-ahc_linux_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs)
-{
-       Scsi_Device *device;
-       Scsi_Device *ldev;
-       struct  ahc_softc *ahc;
-       u_long  flags;
+                                  device->id, device->lun);
 
-       ahc = *((struct ahc_softc **)host->hostdata);
-       ahc_lock(ahc, &flags);
-       for (device = scsi_devs; device != NULL; device = device->next) {
+       BUG_ON(dev->active);
 
-               /*
-                * Watch out for duplicate devices.  This works around
-                * some quirks in how the SCSI scanning code does its
-                * device management.
-                */
-               for (ldev = scsi_devs; ldev != device; ldev = ldev->next) {
-                       if (ldev->host == device->host
-                        && ldev->channel == device->channel
-                        && ldev->id == device->id
-                        && ldev->lun == device->lun)
-                               break;
-               }
-               /* Skip duplicate. */
-               if (ldev != device)
-                       continue;
-
-               if (device->host == host) {
-                       struct   ahc_linux_device *dev;
-
-                       /*
-                        * Since Linux has attached to the device, configure
-                        * it so we don't free and allocate the device
-                        * structure on every command.
-                        */
-                       dev = ahc_linux_get_device(ahc, device->channel,
-                                                  device->id, device->lun,
-                                                  /*alloc*/TRUE);
-                       if (dev != NULL) {
-                               dev->flags &= ~AHC_DEV_UNCONFIGURED;
-                               dev->scsi_device = device;
-                               ahc_linux_device_queue_depth(ahc, dev);
-                               device->queue_depth = dev->openings
-                                                   + dev->active;
-                               if ((dev->flags & (AHC_DEV_Q_BASIC
-                                               | AHC_DEV_Q_TAGGED)) == 0) {
-                                       /*
-                                        * We allow the OS to queue 2 untagged
-                                        * transactions to us at any time even
-                                        * though we can only execute them
-                                        * serially on the controller/device.
-                                        * This should remove some latency.
-                                        */
-                                       device->queue_depth = 2;
-                               }
-                       }
-               }
-       }
-       ahc_unlock(ahc, &flags);
+       ahc_linux_free_device(ahc, dev);
 }
-#endif
 
 #if defined(__i386__)
 /*
  * Return the disk geometry for the given SCSI device.
  */
 static int
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
                    sector_t capacity, int geom[])
 {
        uint8_t *bh;
-#else
-ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[])
-{
-       struct  scsi_device *sdev = disk->device;
-       u_long  capacity = disk->capacity;
-       struct  buffer_head *bh;
-#endif
        int      heads;
        int      sectors;
        int      cylinders;
@@ -1090,22 +777,11 @@ ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[])
        ahc = *((struct ahc_softc **)sdev->host->hostdata);
        channel = sdev->channel;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        bh = scsi_bios_ptable(bdev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17)
-       bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev));
-#else
-       bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024);
-#endif
-
        if (bh) {
                ret = scsi_partsize(bh, capacity,
                                    &geom[2], &geom[0], &geom[1]);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
                kfree(bh);
-#else
-               brelse(bh);
-#endif
                if (ret != -1)
                        return (ret);
        }
@@ -1135,7 +811,7 @@ ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[])
  * Abort the current SCSI command(s).
  */
 static int
-ahc_linux_abort(Scsi_Cmnd *cmd)
+ahc_linux_abort(struct scsi_cmnd *cmd)
 {
        int error;
 
@@ -1149,7 +825,7 @@ ahc_linux_abort(Scsi_Cmnd *cmd)
  * Attempt to send a target reset message to the device that timed out.
  */
 static int
-ahc_linux_dev_reset(Scsi_Cmnd *cmd)
+ahc_linux_dev_reset(struct scsi_cmnd *cmd)
 {
        int error;
 
@@ -1163,18 +839,14 @@ ahc_linux_dev_reset(Scsi_Cmnd *cmd)
  * Reset the SCSI bus.
  */
 static int
-ahc_linux_bus_reset(Scsi_Cmnd *cmd)
+ahc_linux_bus_reset(struct scsi_cmnd *cmd)
 {
        struct ahc_softc *ahc;
-       u_long s;
        int    found;
 
        ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
-       ahc_midlayer_entrypoint_lock(ahc, &s);
        found = ahc_reset_channel(ahc, cmd->device->channel + 'A',
                                  /*initiate reset*/TRUE);
-       ahc_linux_run_complete_queue(ahc);
-       ahc_midlayer_entrypoint_unlock(ahc, &s);
 
        if (bootverbose)
                printf("%s: SCSI bus reset delivered. "
@@ -1183,7 +855,7 @@ ahc_linux_bus_reset(Scsi_Cmnd *cmd)
        return SUCCESS;
 }
 
-Scsi_Host_Template aic7xxx_driver_template = {
+struct scsi_host_template aic7xxx_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "aic7xxx",
        .proc_info              = ahc_linux_proc_info,
@@ -1206,33 +878,6 @@ Scsi_Host_Template aic7xxx_driver_template = {
 
 /**************************** Tasklet Handler *********************************/
 
-/*
- * In 2.4.X and above, this routine is called from a tasklet,
- * so we must re-acquire our lock prior to executing this code.
- * In all prior kernels, ahc_schedule_runq() calls this routine
- * directly and ahc_schedule_runq() is called with our lock held.
- */
-static void
-ahc_runq_tasklet(unsigned long data)
-{
-       struct ahc_softc* ahc;
-       struct ahc_linux_device *dev;
-       u_long flags;
-
-       ahc = (struct ahc_softc *)data;
-       ahc_lock(ahc, &flags);
-       while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) {
-       
-               TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links);
-               dev->flags &= ~AHC_DEV_ON_RUN_LIST;
-               ahc_linux_check_device_queue(ahc, dev);
-               /* Yeild to our interrupt handler */
-               ahc_unlock(ahc, &flags);
-               ahc_lock(ahc, &flags);
-       }
-       ahc_unlock(ahc, &flags);
-}
-
 /******************************** Macros **************************************/
 #define BUILD_SCSIID(ahc, cmd)                                             \
        ((((cmd)->device->id << TID_SHIFT) & TID)                           \
@@ -1278,37 +923,11 @@ int
 ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr,
                 int flags, bus_dmamap_t *mapp)
 {
-       bus_dmamap_t map;
-
-       map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT);
-       if (map == NULL)
-               return (ENOMEM);
-       /*
-        * Although we can dma data above 4GB, our
-        * "consistent" memory is below 4GB for
-        * space efficiency reasons (only need a 4byte
-        * address).  For this reason, we have to reset
-        * our dma mask when doing allocations.
-        */
-       if (ahc->dev_softc != NULL)
-               if (pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF)) {
-                       printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
-                       kfree(map);
-                       return (ENODEV);
-               }
        *vaddr = pci_alloc_consistent(ahc->dev_softc,
-                                     dmat->maxsize, &map->bus_addr);
-       if (ahc->dev_softc != NULL)
-               if (pci_set_dma_mask(ahc->dev_softc,
-                                    ahc->platform_data->hw_dma_mask)) {
-                       printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
-                       kfree(map);
-                       return (ENODEV);
-               }
+                                     dmat->maxsize, mapp);
        if (*vaddr == NULL)
-               return (ENOMEM);
-       *mapp = map;
-       return(0);
+               return ENOMEM;
+       return 0;
 }
 
 void
@@ -1316,7 +935,7 @@ ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat,
                void* vaddr, bus_dmamap_t map)
 {
        pci_free_consistent(ahc->dev_softc, dmat->maxsize,
-                           vaddr, map->bus_addr);
+                           vaddr, map);
 }
 
 int
@@ -1330,7 +949,7 @@ ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map,
         */
        bus_dma_segment_t stack_sg;
 
-       stack_sg.ds_addr = map->bus_addr;
+       stack_sg.ds_addr = map;
        stack_sg.ds_len = dmat->maxsize;
        cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0);
        return (0);
@@ -1339,12 +958,6 @@ ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map,
 void
 ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
 {
-       /*
-        * The map may is NULL in our < 2.3.X implementation.
-        * Now it's 2.6.5, but just in case...
-        */
-       BUG_ON(map == NULL);
-       free(map, M_DEVBUF);
 }
 
 int
@@ -1550,7 +1163,7 @@ __setup("aic7xxx=", aic7xxx_setup);
 uint32_t aic7xxx_verbose;
 
 int
-ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
+ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template)
 {
        char     buf[80];
        struct   Scsi_Host *host;
@@ -1564,11 +1177,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
 
        *((struct ahc_softc **)host->hostdata) = ahc;
        ahc_lock(ahc, &s);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        scsi_assign_lock(host, &ahc->platform_data->spin_lock);
-#elif AHC_SCSI_HAS_HOST_LOCK != 0
-       host->lock = &ahc->platform_data->spin_lock;
-#endif
        ahc->platform_data->host = host;
        host->can_queue = AHC_MAX_QUEUE;
        host->cmd_per_lun = 2;
@@ -1587,19 +1196,14 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
                ahc_set_name(ahc, new_name);
        }
        host->unique_id = ahc->unit;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       scsi_set_pci_device(host, ahc->dev_softc);
-#endif
        ahc_linux_initialize_scsi_bus(ahc);
        ahc_intr_enable(ahc, TRUE);
        ahc_unlock(ahc, &s);
 
        host->transportt = ahc_linux_transport_template;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */
        scsi_scan_host(host);
-#endif
        return (0);
 }
 
@@ -1717,19 +1321,9 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
        if (ahc->platform_data == NULL)
                return (ENOMEM);
        memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
-       TAILQ_INIT(&ahc->platform_data->completeq);
-       TAILQ_INIT(&ahc->platform_data->device_runq);
        ahc->platform_data->irq = AHC_LINUX_NOIRQ;
-       ahc->platform_data->hw_dma_mask = 0xFFFFFFFF;
        ahc_lockinit(ahc);
-       ahc_done_lockinit(ahc);
-       init_timer(&ahc->platform_data->completeq_timer);
-       ahc->platform_data->completeq_timer.data = (u_long)ahc;
-       ahc->platform_data->completeq_timer.function =
-           (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue;
        init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
-       tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet,
-                    (unsigned long)ahc);
        ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
        ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
        if (aic7xxx_pci_parity == 0)
@@ -1746,12 +1340,8 @@ ahc_platform_free(struct ahc_softc *ahc)
        int i, j;
 
        if (ahc->platform_data != NULL) {
-               del_timer_sync(&ahc->platform_data->completeq_timer);
-               tasklet_kill(&ahc->platform_data->runq_tasklet);
                if (ahc->platform_data->host != NULL) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
                        scsi_remove_host(ahc->platform_data->host);
-#endif
                        scsi_host_put(ahc->platform_data->host);
                }
 
@@ -1787,16 +1377,7 @@ ahc_platform_free(struct ahc_softc *ahc)
                        release_mem_region(ahc->platform_data->mem_busaddr,
                                           0x1000);
                }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               /*
-                * In 2.4 we detach from the scsi midlayer before the PCI
-                * layer invokes our remove callback.  No per-instance
-                * detach is provided, so we must reach inside the PCI
-                * subsystem's internals and detach our driver manually.
-                */
-               if (ahc->dev_softc != NULL)
-                       ahc->dev_softc->driver = NULL;
-#endif
+
                free(ahc->platform_data, M_DEVBUF);
        }
 }
@@ -1820,7 +1401,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
 
        dev = ahc_linux_get_device(ahc, devinfo->channel - 'A',
                                   devinfo->target,
-                                  devinfo->lun, /*alloc*/FALSE);
+                                  devinfo->lun);
        if (dev == NULL)
                return;
        was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED);
@@ -1873,7 +1454,6 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
                dev->maxtags = 0;
                dev->openings =  1 - dev->active;
        }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        if (dev->scsi_device != NULL) {
                switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
                case AHC_DEV_Q_BASIC:
@@ -1899,90 +1479,13 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
                        break;
                }
        }
-#endif
 }
 
 int
 ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel,
                        int lun, u_int tag, role_t role, uint32_t status)
 {
-       int chan;
-       int maxchan;
-       int targ;
-       int maxtarg;
-       int clun;
-       int maxlun;
-       int count;
-
-       if (tag != SCB_LIST_NULL)
-               return (0);
-
-       chan = 0;
-       if (channel != ALL_CHANNELS) {
-               chan = channel - 'A';
-               maxchan = chan + 1;
-       } else {
-               maxchan = (ahc->features & AHC_TWIN) ? 2 : 1;
-       }
-       targ = 0;
-       if (target != CAM_TARGET_WILDCARD) {
-               targ = target;
-               maxtarg = targ + 1;
-       } else {
-               maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
-       }
-       clun = 0;
-       if (lun != CAM_LUN_WILDCARD) {
-               clun = lun;
-               maxlun = clun + 1;
-       } else {
-               maxlun = AHC_NUM_LUNS;
-       }
-
-       count = 0;
-       for (; chan < maxchan; chan++) {
-
-               for (; targ < maxtarg; targ++) {
-
-                       for (; clun < maxlun; clun++) {
-                               struct ahc_linux_device *dev;
-                               struct ahc_busyq *busyq;
-                               struct ahc_cmd *acmd;
-
-                               dev = ahc_linux_get_device(ahc, chan,
-                                                          targ, clun,
-                                                          /*alloc*/FALSE);
-                               if (dev == NULL)
-                                       continue;
-
-                               busyq = &dev->busyq;
-                               while ((acmd = TAILQ_FIRST(busyq)) != NULL) {
-                                       Scsi_Cmnd *cmd;
-
-                                       cmd = &acmd_scsi_cmd(acmd);
-                                       TAILQ_REMOVE(busyq, acmd,
-                                                    acmd_links.tqe);
-                                       count++;
-                                       cmd->result = status << 16;
-                                       ahc_linux_queue_cmd_complete(ahc, cmd);
-                               }
-                       }
-               }
-       }
-
-       return (count);
-}
-
-static void
-ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc)
-{
-       u_long flags;
-
-       ahc_lock(ahc, &flags);
-       del_timer(&ahc->platform_data->completeq_timer);
-       ahc->platform_data->flags &= ~AHC_RUN_CMPLT_Q_TIMER;
-       ahc_linux_run_complete_queue(ahc);
-       ahc_unlock(ahc, &flags);
+       return 0;
 }
 
 static u_int
@@ -2045,213 +1548,200 @@ ahc_linux_device_queue_depth(struct ahc_softc *ahc,
        }
 }
 
-static void
-ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
+static int
+ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
+                     struct scsi_cmnd *cmd)
 {
-       struct   ahc_cmd *acmd;
-       struct   scsi_cmnd *cmd;
        struct   scb *scb;
        struct   hardware_scb *hscb;
        struct   ahc_initiator_tinfo *tinfo;
        struct   ahc_tmode_tstate *tstate;
        uint16_t mask;
+       struct scb_tailq *untagged_q = NULL;
 
-       if ((dev->flags & AHC_DEV_ON_RUN_LIST) != 0)
-               panic("running device on run list");
+       /*
+        * Schedule us to run later.  The only reason we are not
+        * running is because the whole controller Q is frozen.
+        */
+       if (ahc->platform_data->qfrozen != 0)
+               return SCSI_MLQUEUE_HOST_BUSY;
 
-       while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL
-           && dev->openings > 0 && dev->qfrozen == 0) {
+       /*
+        * We only allow one untagged transaction
+        * per target in the initiator role unless
+        * we are storing a full busy target *lun*
+        * table in SCB space.
+        */
+       if (!blk_rq_tagged(cmd->request)
+           && (ahc->features & AHC_SCB_BTT) == 0) {
+               int target_offset;
 
-               /*
-                * Schedule us to run later.  The only reason we are not
-                * running is because the whole controller Q is frozen.
-                */
-               if (ahc->platform_data->qfrozen != 0) {
-                       TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
-                                         dev, links);
-                       dev->flags |= AHC_DEV_ON_RUN_LIST;
-                       return;
-               }
-               /*
-                * Get an scb to use.
-                */
-               if ((scb = ahc_get_scb(ahc)) == NULL) {
-                       TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
-                                        dev, links);
-                       dev->flags |= AHC_DEV_ON_RUN_LIST;
-                       ahc->flags |= AHC_RESOURCE_SHORTAGE;
-                       return;
-               }
-               TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe);
-               cmd = &acmd_scsi_cmd(acmd);
-               scb->io_ctx = cmd;
-               scb->platform_data->dev = dev;
-               hscb = scb->hscb;
-               cmd->host_scribble = (char *)scb;
+               target_offset = cmd->device->id + cmd->device->channel * 8;
+               untagged_q = &(ahc->untagged_queues[target_offset]);
+               if (!TAILQ_EMPTY(untagged_q))
+                       /* if we're already executing an untagged command
+                        * we're busy to another */
+                       return SCSI_MLQUEUE_DEVICE_BUSY;
+       }
 
-               /*
-                * Fill out basics of the HSCB.
-                */
-               hscb->control = 0;
-               hscb->scsiid = BUILD_SCSIID(ahc, cmd);
-               hscb->lun = cmd->device->lun;
-               mask = SCB_GET_TARGET_MASK(ahc, scb);
-               tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
-                                           SCB_GET_OUR_ID(scb),
-                                           SCB_GET_TARGET(ahc, scb), &tstate);
-               hscb->scsirate = tinfo->scsirate;
-               hscb->scsioffset = tinfo->curr.offset;
-               if ((tstate->ultraenb & mask) != 0)
-                       hscb->control |= ULTRAENB;
-
-               if ((ahc->user_discenable & mask) != 0)
-                       hscb->control |= DISCENB;
-
-               if ((tstate->auto_negotiate & mask) != 0) {
-                       scb->flags |= SCB_AUTO_NEGOTIATE;
-                       scb->hscb->control |= MK_MESSAGE;
-               }
+       /*
+        * Get an scb to use.
+        */
+       if ((scb = ahc_get_scb(ahc)) == NULL) {
+                       ahc->flags |= AHC_RESOURCE_SHORTAGE;
+                       return SCSI_MLQUEUE_HOST_BUSY;
+       }
 
-               if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-                       int     msg_bytes;
-                       uint8_t tag_msgs[2];
+       scb->io_ctx = cmd;
+       scb->platform_data->dev = dev;
+       hscb = scb->hscb;
+       cmd->host_scribble = (char *)scb;
 
-                       msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs);
-                       if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) {
-                               hscb->control |= tag_msgs[0];
-                               if (tag_msgs[0] == MSG_ORDERED_TASK)
-                                       dev->commands_since_idle_or_otag = 0;
-                       } else
-#endif
-                       if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
-                        && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
-                               hscb->control |= MSG_ORDERED_TASK;
+       /*
+        * Fill out basics of the HSCB.
+        */
+       hscb->control = 0;
+       hscb->scsiid = BUILD_SCSIID(ahc, cmd);
+       hscb->lun = cmd->device->lun;
+       mask = SCB_GET_TARGET_MASK(ahc, scb);
+       tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
+                                   SCB_GET_OUR_ID(scb),
+                                   SCB_GET_TARGET(ahc, scb), &tstate);
+       hscb->scsirate = tinfo->scsirate;
+       hscb->scsioffset = tinfo->curr.offset;
+       if ((tstate->ultraenb & mask) != 0)
+               hscb->control |= ULTRAENB;
+       
+       if ((ahc->user_discenable & mask) != 0)
+               hscb->control |= DISCENB;
+       
+       if ((tstate->auto_negotiate & mask) != 0) {
+               scb->flags |= SCB_AUTO_NEGOTIATE;
+               scb->hscb->control |= MK_MESSAGE;
+       }
+
+       if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
+               int     msg_bytes;
+               uint8_t tag_msgs[2];
+               
+               msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs);
+               if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) {
+                       hscb->control |= tag_msgs[0];
+                       if (tag_msgs[0] == MSG_ORDERED_TASK)
                                dev->commands_since_idle_or_otag = 0;
-                       } else {
-                               hscb->control |= MSG_SIMPLE_TASK;
-                       }
-               }
-
-               hscb->cdb_len = cmd->cmd_len;
-               if (hscb->cdb_len <= 12) {
-                       memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
+               } else if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
+                               && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
+                       hscb->control |= MSG_ORDERED_TASK;
+                       dev->commands_since_idle_or_otag = 0;
                } else {
-                       memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
-                       scb->flags |= SCB_CDB32_PTR;
+                       hscb->control |= MSG_SIMPLE_TASK;
                }
+       }
 
-               scb->platform_data->xfer_len = 0;
-               ahc_set_residual(scb, 0);
-               ahc_set_sense_residual(scb, 0);
-               scb->sg_count = 0;
-               if (cmd->use_sg != 0) {
-                       struct  ahc_dma_seg *sg;
-                       struct  scatterlist *cur_seg;
-                       struct  scatterlist *end_seg;
-                       int     nseg;
-
-                       cur_seg = (struct scatterlist *)cmd->request_buffer;
-                       nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
-                           cmd->sc_data_direction);
-                       end_seg = cur_seg + nseg;
-                       /* Copy the segments into the SG list. */
-                       sg = scb->sg_list;
-                       /*
-                        * The sg_count may be larger than nseg if
-                        * a transfer crosses a 32bit page.
-                        */ 
-                       while (cur_seg < end_seg) {
-                               dma_addr_t addr;
-                               bus_size_t len;
-                               int consumed;
-
-                               addr = sg_dma_address(cur_seg);
-                               len = sg_dma_len(cur_seg);
-                               consumed = ahc_linux_map_seg(ahc, scb,
-                                                            sg, addr, len);
-                               sg += consumed;
-                               scb->sg_count += consumed;
-                               cur_seg++;
-                       }
-                       sg--;
-                       sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
-
-                       /*
-                        * Reset the sg list pointer.
-                        */
-                       scb->hscb->sgptr =
-                           ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
+       hscb->cdb_len = cmd->cmd_len;
+       if (hscb->cdb_len <= 12) {
+               memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
+       } else {
+               memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
+               scb->flags |= SCB_CDB32_PTR;
+       }
 
-                       /*
-                        * Copy the first SG into the "current"
-                        * data pointer area.
-                        */
-                       scb->hscb->dataptr = scb->sg_list->addr;
-                       scb->hscb->datacnt = scb->sg_list->len;
-               } else if (cmd->request_bufflen != 0) {
-                       struct   ahc_dma_seg *sg;
+       scb->platform_data->xfer_len = 0;
+       ahc_set_residual(scb, 0);
+       ahc_set_sense_residual(scb, 0);
+       scb->sg_count = 0;
+       if (cmd->use_sg != 0) {
+               struct  ahc_dma_seg *sg;
+               struct  scatterlist *cur_seg;
+               struct  scatterlist *end_seg;
+               int     nseg;
+
+               cur_seg = (struct scatterlist *)cmd->request_buffer;
+               nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
+                                 cmd->sc_data_direction);
+               end_seg = cur_seg + nseg;
+               /* Copy the segments into the SG list. */
+               sg = scb->sg_list;
+               /*
+                * The sg_count may be larger than nseg if
+                * a transfer crosses a 32bit page.
+                */ 
+               while (cur_seg < end_seg) {
                        dma_addr_t addr;
-
-                       sg = scb->sg_list;
-                       addr = pci_map_single(ahc->dev_softc,
-                              cmd->request_buffer,
-                              cmd->request_bufflen,
-                              cmd->sc_data_direction);
-                       scb->platform_data->buf_busaddr = addr;
-                       scb->sg_count = ahc_linux_map_seg(ahc, scb,
-                                                         sg, addr,
-                                                         cmd->request_bufflen);
-                       sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
-
-                       /*
-                        * Reset the sg list pointer.
-                        */
-                       scb->hscb->sgptr =
-                           ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
-
-                       /*
-                        * Copy the first SG into the "current"
-                        * data pointer area.
-                        */
-                       scb->hscb->dataptr = sg->addr;
-                       scb->hscb->datacnt = sg->len;
-               } else {
-                       scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
-                       scb->hscb->dataptr = 0;
-                       scb->hscb->datacnt = 0;
-                       scb->sg_count = 0;
+                       bus_size_t len;
+                       int consumed;
+
+                       addr = sg_dma_address(cur_seg);
+                       len = sg_dma_len(cur_seg);
+                       consumed = ahc_linux_map_seg(ahc, scb,
+                                                    sg, addr, len);
+                       sg += consumed;
+                       scb->sg_count += consumed;
+                       cur_seg++;
                }
+               sg--;
+               sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
 
-               ahc_sync_sglist(ahc, scb, BUS_DMASYNC_PREWRITE);
-               LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
-               dev->openings--;
-               dev->active++;
-               dev->commands_issued++;
-               if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
-                       dev->commands_since_idle_or_otag++;
+               /*
+                * Reset the sg list pointer.
+                */
+               scb->hscb->sgptr =
+                       ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
+               
+               /*
+                * Copy the first SG into the "current"
+                * data pointer area.
+                */
+               scb->hscb->dataptr = scb->sg_list->addr;
+               scb->hscb->datacnt = scb->sg_list->len;
+       } else if (cmd->request_bufflen != 0) {
+               struct   ahc_dma_seg *sg;
+               dma_addr_t addr;
+
+               sg = scb->sg_list;
+               addr = pci_map_single(ahc->dev_softc,
+                                     cmd->request_buffer,
+                                     cmd->request_bufflen,
+                                     cmd->sc_data_direction);
+               scb->platform_data->buf_busaddr = addr;
+               scb->sg_count = ahc_linux_map_seg(ahc, scb,
+                                                 sg, addr,
+                                                 cmd->request_bufflen);
+               sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
 
                /*
-                * We only allow one untagged transaction
-                * per target in the initiator role unless
-                * we are storing a full busy target *lun*
-                * table in SCB space.
+                * Reset the sg list pointer.
                 */
-               if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0
-                && (ahc->features & AHC_SCB_BTT) == 0) {
-                       struct scb_tailq *untagged_q;
-                       int target_offset;
-
-                       target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
-                       untagged_q = &(ahc->untagged_queues[target_offset]);
-                       TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
-                       scb->flags |= SCB_UNTAGGEDQ;
-                       if (TAILQ_FIRST(untagged_q) != scb)
-                               continue;
-               }
-               scb->flags |= SCB_ACTIVE;
-               ahc_queue_scb(ahc, scb);
+               scb->hscb->sgptr =
+                       ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
+
+               /*
+                * Copy the first SG into the "current"
+                * data pointer area.
+                */
+               scb->hscb->dataptr = sg->addr;
+               scb->hscb->datacnt = sg->len;
+       } else {
+               scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
+               scb->hscb->dataptr = 0;
+               scb->hscb->datacnt = 0;
+               scb->sg_count = 0;
        }
+
+       LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
+       dev->openings--;
+       dev->active++;
+       dev->commands_issued++;
+       if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
+               dev->commands_since_idle_or_otag++;
+       
+       scb->flags |= SCB_ACTIVE;
+       if (untagged_q) {
+               TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
+               scb->flags |= SCB_UNTAGGEDQ;
+       }
+       ahc_queue_scb(ahc, scb);
+       return 0;
 }
 
 /*
@@ -2267,9 +1757,6 @@ ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
        ahc = (struct ahc_softc *) dev_id;
        ahc_lock(ahc, &flags); 
        ours = ahc_intr(ahc);
-       if (ahc_linux_next_device_to_run(ahc) != NULL)
-               ahc_schedule_runq(ahc);
-       ahc_linux_run_complete_queue(ahc);
        ahc_unlock(ahc, &flags);
        return IRQ_RETVAL(ours);
 }
@@ -2278,8 +1765,6 @@ void
 ahc_platform_flushwork(struct ahc_softc *ahc)
 {
 
-       while (ahc_linux_run_complete_queue(ahc) != NULL)
-               ;
 }
 
 static struct ahc_linux_target*
@@ -2335,8 +1820,6 @@ ahc_linux_free_target(struct ahc_softc *ahc, struct ahc_linux_target *targ)
                      AHC_TRANS_GOAL, /*paused*/FALSE);
        ahc_update_neg_request(ahc, &devinfo, tstate, tinfo, AHC_NEG_ALWAYS);
        ahc->platform_data->targets[target_offset] = NULL;
-       if (targ->inq_data != NULL)
-               free(targ->inq_data, M_DEVBUF);
        free(targ, M_DEVBUF);
 }
 
@@ -2350,9 +1833,6 @@ ahc_linux_alloc_device(struct ahc_softc *ahc,
        if (dev == NULL)
                return (NULL);
        memset(dev, 0, sizeof(*dev));
-       init_timer(&dev->timer);
-       TAILQ_INIT(&dev->busyq);
-       dev->flags = AHC_DEV_UNCONFIGURED;
        dev->lun = lun;
        dev->target = targ;
 
@@ -2375,7 +1855,7 @@ ahc_linux_alloc_device(struct ahc_softc *ahc,
 }
 
 static void
-__ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
+ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
 {
        struct ahc_linux_target *targ;
 
@@ -2387,13 +1867,6 @@ __ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
                ahc_linux_free_target(ahc, targ);
 }
 
-static void
-ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
-{
-       del_timer_sync(&dev->timer);
-       __ahc_linux_free_device(ahc, dev);
-}
-
 void
 ahc_send_async(struct ahc_softc *ahc, char channel,
               u_int target, u_int lun, ac_code code, void *arg)
@@ -2465,28 +1938,9 @@ ahc_send_async(struct ahc_softc *ahc, char channel,
        }
         case AC_SENT_BDR:
        {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
                WARN_ON(lun != CAM_LUN_WILDCARD);
                scsi_report_device_reset(ahc->platform_data->host,
                                         channel - 'A', target);
-#else
-               Scsi_Device *scsi_dev;
-
-               /*
-                * Find the SCSI device associated with this
-                * request and indicate that a UA is expected.
-                */
-               for (scsi_dev = ahc->platform_data->host->host_queue;
-                    scsi_dev != NULL; scsi_dev = scsi_dev->next) {
-                       if (channel - 'A' == scsi_dev->channel
-                        && target == scsi_dev->id
-                        && (lun == CAM_LUN_WILDCARD
-                         || lun == scsi_dev->lun)) {
-                               scsi_dev->was_reset = 1;
-                               scsi_dev->expecting_cc_ua = 1;
-                       }
-               }
-#endif
                break;
        }
         case AC_BUS_RESET:
@@ -2506,7 +1960,7 @@ ahc_send_async(struct ahc_softc *ahc, char channel,
 void
 ahc_done(struct ahc_softc *ahc, struct scb *scb)
 {
-       Scsi_Cmnd *cmd;
+       struct scsi_cmnd *cmd;
        struct     ahc_linux_device *dev;
 
        LIST_REMOVE(scb, pending_links);
@@ -2517,7 +1971,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
                target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
                untagged_q = &(ahc->untagged_queues[target_offset]);
                TAILQ_REMOVE(untagged_q, scb, links.tqe);
-               ahc_run_untagged_queue(ahc, untagged_q);
+               BUG_ON(!TAILQ_EMPTY(untagged_q));
        }
 
        if ((scb->flags & SCB_ACTIVE) == 0) {
@@ -2585,8 +2039,6 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
                }
        } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
                ahc_linux_handle_scsi_status(ahc, dev, scb);
-       } else if (ahc_get_transaction_status(scb) == CAM_SEL_TIMEOUT) {
-               dev->flags |= AHC_DEV_UNCONFIGURED;
        }
 
        if (dev->openings == 1
@@ -2608,16 +2060,6 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
        if (dev->active == 0)
                dev->commands_since_idle_or_otag = 0;
 
-       if (TAILQ_EMPTY(&dev->busyq)) {
-               if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0
-                && dev->active == 0
-                && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0)
-                       ahc_linux_free_device(ahc, dev);
-       } else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
-               TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
-               dev->flags |= AHC_DEV_ON_RUN_LIST;
-       }
-
        if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
                printf("Recovery SCB completes\n");
                if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
@@ -2661,7 +2103,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
        case SCSI_STATUS_CHECK_COND:
        case SCSI_STATUS_CMD_TERMINATED:
        {
-               Scsi_Cmnd *cmd;
+               struct scsi_cmnd *cmd;
 
                /*
                 * Copy sense information to the OS's cmd
@@ -2756,51 +2198,14 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
                ahc_platform_set_tags(ahc, &devinfo,
                             (dev->flags & AHC_DEV_Q_BASIC)
                           ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
-               /* FALLTHROUGH */
-       }
-       case SCSI_STATUS_BUSY:
-       {
-               /*
-                * Set a short timer to defer sending commands for
-                * a bit since Linux will not delay in this case.
-                */
-               if ((dev->flags & AHC_DEV_TIMER_ACTIVE) != 0) {
-                       printf("%s:%c:%d: Device Timer still active during "
-                              "busy processing\n", ahc_name(ahc),
-                               dev->target->channel, dev->target->target);
-                       break;
-               }
-               dev->flags |= AHC_DEV_TIMER_ACTIVE;
-               dev->qfrozen++;
-               init_timer(&dev->timer);
-               dev->timer.data = (u_long)dev;
-               dev->timer.expires = jiffies + (HZ/2);
-               dev->timer.function = ahc_linux_dev_timed_unfreeze;
-               add_timer(&dev->timer);
                break;
        }
        }
 }
 
 static void
-ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd)
+ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
 {
-       /*
-        * Typically, the complete queue has very few entries
-        * queued to it before the queue is emptied by
-        * ahc_linux_run_complete_queue, so sorting the entries
-        * by generation number should be inexpensive.
-        * We perform the sort so that commands that complete
-        * with an error are retuned in the order origionally
-        * queued to the controller so that any subsequent retries
-        * are performed in order.  The underlying ahc routines do
-        * not guarantee the order that aborted commands will be
-        * returned to us.
-        */
-       struct ahc_completeq *completeq;
-       struct ahc_cmd *list_cmd;
-       struct ahc_cmd *acmd;
-
        /*
         * Map CAM error codes into Linux Error codes.  We
         * avoid the conversion so that the DV code has the
@@ -2854,26 +2259,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd)
                        new_status = DID_ERROR;
                        break;
                case CAM_REQUEUE_REQ:
-                       /*
-                        * If we want the request requeued, make sure there
-                        * are sufficent retries.  In the old scsi error code,
-                        * we used to be able to specify a result code that
-                        * bypassed the retry count.  Now we must use this
-                        * hack.  We also "fake" a check condition with
-                        * a sense code of ABORTED COMMAND.  This seems to
-                        * evoke a retry even if this command is being sent
-                        * via the eh thread.  Ick!  Ick!  Ick!
-                        */
-                       if (cmd->retries > 0)
-                               cmd->retries--;
-                       new_status = DID_OK;
-                       ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
-                       cmd->result |= (DRIVER_SENSE << 24);
-                       memset(cmd->sense_buffer, 0,
-                              sizeof(cmd->sense_buffer));
-                       cmd->sense_buffer[0] = SSD_ERRCODE_VALID
-                                            | SSD_CURRENT_ERROR;
-                       cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND;
+                       new_status = DID_REQUEUE;
                        break;
                default:
                        /* We should never get here */
@@ -2884,17 +2270,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd)
                ahc_cmd_set_transaction_status(cmd, new_status);
        }
 
-       completeq = &ahc->platform_data->completeq;
-       list_cmd = TAILQ_FIRST(completeq);
-       acmd = (struct ahc_cmd *)cmd;
-       while (list_cmd != NULL
-           && acmd_scsi_cmd(list_cmd).serial_number
-            < acmd_scsi_cmd(acmd).serial_number)
-               list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe);
-       if (list_cmd != NULL)
-               TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe);
-       else
-               TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe);
+       cmd->scsi_done(cmd);
 }
 
 static void
@@ -2942,7 +2318,6 @@ ahc_linux_release_simq(u_long arg)
                ahc->platform_data->qfrozen--;
        if (ahc->platform_data->qfrozen == 0)
                unblock_reqs = 1;
-       ahc_schedule_runq(ahc);
        ahc_unlock(ahc, &s);
        /*
         * There is still a race here.  The mid-layer
@@ -2954,37 +2329,12 @@ ahc_linux_release_simq(u_long arg)
                scsi_unblock_requests(ahc->platform_data->host);
 }
 
-static void
-ahc_linux_dev_timed_unfreeze(u_long arg)
-{
-       struct ahc_linux_device *dev;
-       struct ahc_softc *ahc;
-       u_long s;
-
-       dev = (struct ahc_linux_device *)arg;
-       ahc = dev->target->ahc;
-       ahc_lock(ahc, &s);
-       dev->flags &= ~AHC_DEV_TIMER_ACTIVE;
-       if (dev->qfrozen > 0)
-               dev->qfrozen--;
-       if (dev->qfrozen == 0
-        && (dev->flags & AHC_DEV_ON_RUN_LIST) == 0)
-               ahc_linux_run_device_queue(ahc, dev);
-       if (TAILQ_EMPTY(&dev->busyq)
-        && dev->active == 0)
-               __ahc_linux_free_device(ahc, dev);
-       ahc_unlock(ahc, &s);
-}
-
 static int
-ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
+ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
 {
        struct ahc_softc *ahc;
-       struct ahc_cmd *acmd;
-       struct ahc_cmd *list_acmd;
        struct ahc_linux_device *dev;
        struct scb *pending_scb;
-       u_long s;
        u_int  saved_scbptr;
        u_int  active_scb_index;
        u_int  last_phase;
@@ -3000,7 +2350,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
        paused = FALSE;
        wait = FALSE;
        ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
-       acmd = (struct ahc_cmd *)cmd;
 
        printf("%s:%d:%d:%d: Attempting to queue a%s message\n",
               ahc_name(ahc), cmd->device->channel,
@@ -3012,22 +2361,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
                printf(" 0x%x", cmd->cmnd[cdb_byte]);
        printf("\n");
 
-       /*
-        * In all versions of Linux, we have to work around
-        * a major flaw in how the mid-layer is locked down
-        * if we are to sleep successfully in our error handler
-        * while allowing our interrupt handler to run.  Since
-        * the midlayer acquires either the io_request_lock or
-        * our lock prior to calling us, we must use the
-        * spin_unlock_irq() method for unlocking our lock.
-        * This will force interrupts to be enabled on the
-        * current CPU.  Since the EH thread should not have
-        * been running with CPU interrupts disabled other than
-        * by acquiring either the io_request_lock or our own
-        * lock, this *should* be safe.
-        */
-       ahc_midlayer_entrypoint_lock(ahc, &s);
-
        /*
         * First determine if we currently own this command.
         * Start by searching the device queue.  If not found
@@ -3036,7 +2369,7 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
         * command, return success.
         */
        dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
-                                  cmd->device->lun, /*alloc*/FALSE);
+                                  cmd->device->lun);
 
        if (dev == NULL) {
                /*
@@ -3050,24 +2383,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
                goto no_cmd;
        }
 
-       TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) {
-               if (list_acmd == acmd)
-                       break;
-       }
-
-       if (list_acmd != NULL) {
-               printf("%s:%d:%d:%d: Command found on device queue\n",
-                      ahc_name(ahc), cmd->device->channel, cmd->device->id,
-                      cmd->device->lun);
-               if (flag == SCB_ABORT) {
-                       TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
-                       cmd->result = DID_ABORT << 16;
-                       ahc_linux_queue_cmd_complete(ahc, cmd);
-                       retval = SUCCESS;
-                       goto done;
-               }
-       }
-
        if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
         && ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
                                       cmd->device->channel + 'A',
@@ -3301,53 +2616,42 @@ done:
                }
                spin_lock_irq(&ahc->platform_data->spin_lock);
        }
-       ahc_schedule_runq(ahc);
-       ahc_linux_run_complete_queue(ahc);
-       ahc_midlayer_entrypoint_unlock(ahc, &s);
        return (retval);
 }
 
 void
 ahc_platform_dump_card_state(struct ahc_softc *ahc)
 {
-       struct ahc_linux_device *dev;
-       int channel;
-       int maxchannel;
-       int target;
-       int maxtarget;
-       int lun;
-       int i;
-
-       maxchannel = (ahc->features & AHC_TWIN) ? 1 : 0;
-       maxtarget = (ahc->features & AHC_WIDE) ? 15 : 7;
-       for (channel = 0; channel <= maxchannel; channel++) {
+}
 
-               for (target = 0; target <=maxtarget; target++) {
+static void ahc_linux_exit(void);
 
-                       for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
-                               struct ahc_cmd *acmd;
+static void ahc_linux_get_width(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       spi_width(starget) = tinfo->curr.width;
+}
 
-                               dev = ahc_linux_get_device(ahc, channel, target,
-                                                          lun, /*alloc*/FALSE);
-                               if (dev == NULL)
-                                       continue;
+static void ahc_linux_set_width(struct scsi_target *starget, int width)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_devinfo devinfo;
+       unsigned long flags;
 
-                               printf("DevQ(%d:%d:%d): ",
-                                      channel, target, lun);
-                               i = 0;
-                               TAILQ_FOREACH(acmd, &dev->busyq,
-                                             acmd_links.tqe) {
-                                       if (i++ > AHC_SCB_MAX)
-                                               break;
-                               }
-                               printf("%d waiting\n", i);
-                       }
-               }
-       }
+       ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+                           starget->channel + 'A', ROLE_INITIATOR);
+       ahc_lock(ahc, &flags);
+       ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
+       ahc_unlock(ahc, &flags);
 }
 
-static void ahc_linux_exit(void);
-
 static void ahc_linux_get_period(struct scsi_target *starget)
 {
        struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -3378,8 +2682,21 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period)
        if (offset == 0)
                offset = MAX_OFFSET;
 
+       if (period < 9)
+               period = 9;     /* 12.5ns is our minimum */
+       if (period == 9)
+               ppr_options |= MSG_EXT_PPR_DT_REQ;
+
        ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
                            starget->channel + 'A', ROLE_INITIATOR);
+
+       /* all PPR requests apart from QAS require wide transfers */
+       if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) {
+               ahc_linux_get_width(starget);
+               if (spi_width(starget) == 0)
+                       ppr_options &= MSG_EXT_PPR_QAS_REQ;
+       }
+
        syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
        ahc_lock(ahc, &flags);
        ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
@@ -3427,32 +2744,6 @@ static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
        ahc_unlock(ahc, &flags);
 }
 
-static void ahc_linux_get_width(struct scsi_target *starget)
-{
-       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
-       struct ahc_tmode_tstate *tstate;
-       struct ahc_initiator_tinfo *tinfo 
-               = ahc_fetch_transinfo(ahc,
-                                     starget->channel + 'A',
-                                     shost->this_id, starget->id, &tstate);
-       spi_width(starget) = tinfo->curr.width;
-}
-
-static void ahc_linux_set_width(struct scsi_target *starget, int width)
-{
-       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
-       struct ahc_devinfo devinfo;
-       unsigned long flags;
-
-       ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
-                           starget->channel + 'A', ROLE_INITIATOR);
-       ahc_lock(ahc, &flags);
-       ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
-       ahc_unlock(ahc, &flags);
-}
-
 static void ahc_linux_get_dt(struct scsi_target *starget)
 {
        struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -3481,10 +2772,15 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
        unsigned long flags;
        struct ahc_syncrate *syncrate;
 
+       if (dt) {
+               period = 9;     /* 12.5ns is the only period valid for DT */
+               ppr_options |= MSG_EXT_PPR_DT_REQ;
+       } else if (period == 9)
+               period = 10;    /* if resetting DT, period must be >= 25ns */
+
        ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
                            starget->channel + 'A', ROLE_INITIATOR);
-       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
-                                    dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2);
+       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT);
        ahc_lock(ahc, &flags);
        ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
                         ppr_options, AHC_TRANS_GOAL, FALSE);
@@ -3516,7 +2812,6 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
        unsigned int ppr_options = tinfo->curr.ppr_options
                & ~MSG_EXT_PPR_QAS_REQ;
        unsigned int period = tinfo->curr.period;
-       unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
        unsigned long flags;
        struct ahc_syncrate *syncrate;
 
@@ -3525,8 +2820,7 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
 
        ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
                            starget->channel + 'A', ROLE_INITIATOR);
-       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
-                                    dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2);
+       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
        ahc_lock(ahc, &flags);
        ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
                         ppr_options, AHC_TRANS_GOAL, FALSE);
@@ -3558,7 +2852,6 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
        unsigned int ppr_options = tinfo->curr.ppr_options
                & ~MSG_EXT_PPR_IU_REQ;
        unsigned int period = tinfo->curr.period;
-       unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
        unsigned long flags;
        struct ahc_syncrate *syncrate;
 
@@ -3567,8 +2860,7 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
 
        ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
                            starget->channel + 'A', ROLE_INITIATOR);
-       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
-                                    dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2);
+       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
        ahc_lock(ahc, &flags);
        ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
                         ppr_options, AHC_TRANS_GOAL, FALSE);
@@ -3601,7 +2893,6 @@ static struct spi_function_template ahc_linux_transport_functions = {
 static int __init
 ahc_linux_init(void)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        ahc_linux_transport_template = spi_attach_transport(&ahc_linux_transport_functions);
        if (!ahc_linux_transport_template)
                return -ENODEV;
@@ -3610,29 +2901,11 @@ ahc_linux_init(void)
        spi_release_transport(ahc_linux_transport_template);
        ahc_linux_exit();
        return -ENODEV;
-#else
-       scsi_register_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
-       if (aic7xxx_driver_template.present == 0) {
-               scsi_unregister_module(MODULE_SCSI_HA,
-                                      &aic7xxx_driver_template);
-               return (-ENODEV);
-       }
-
-       return (0);
-#endif
 }
 
 static void
 ahc_linux_exit(void)
 {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       /*
-        * In 2.4 we have to unregister from the PCI core _after_
-        * unregistering from the scsi midlayer to avoid dangling
-        * references.
-        */
-       scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
-#endif
        ahc_linux_pci_exit();
        ahc_linux_eisa_exit();
        spi_release_transport(ahc_linux_transport_template);
index c401537067b65c25788cecf6b3c80be88272fc1c..30c200d5bcd5c298f9bfbba2116dd8ab11caed18 100644 (file)
@@ -59,6 +59,7 @@
 #ifndef _AIC7XXX_LINUX_H_
 #define _AIC7XXX_LINUX_H_
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/smp_lock.h>
 #include <linux/version.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/io.h>
 
-#include <linux/interrupt.h> /* For tasklet support. */
-#include <linux/config.h>
-#include <linux/slab.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 
 /* Core SCSI definitions */
 #define AIC_LIB_PREFIX ahc
-#include "scsi.h"
-#include <scsi/scsi_host.h>
 
 /* Name space conflict with BSD queue macros */
 #ifdef LIST_HEAD
 /************************* Forward Declarations *******************************/
 struct ahc_softc;
 typedef struct pci_dev *ahc_dev_softc_t;
-typedef Scsi_Cmnd      *ahc_io_ctx_t;
+typedef struct scsi_cmnd      *ahc_io_ctx_t;
 
 /******************************* Byte Order ***********************************/
 #define ahc_htobe16(x) cpu_to_be16(x)
@@ -144,7 +148,7 @@ typedef Scsi_Cmnd      *ahc_io_ctx_t;
 extern u_int aic7xxx_no_probe;
 extern u_int aic7xxx_allow_memio;
 extern int aic7xxx_detect_complete;
-extern Scsi_Host_Template aic7xxx_driver_template;
+extern struct scsi_host_template aic7xxx_driver_template;
 
 /***************************** Bus Space/DMA **********************************/
 
@@ -174,11 +178,7 @@ struct ahc_linux_dma_tag
 };
 typedef struct ahc_linux_dma_tag* bus_dma_tag_t;
 
-struct ahc_linux_dmamap
-{
-       dma_addr_t      bus_addr;
-};
-typedef struct ahc_linux_dmamap* bus_dmamap_t;
+typedef dma_addr_t bus_dmamap_t;
 
 typedef int bus_dma_filter_t(void*, dma_addr_t);
 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
@@ -281,12 +281,6 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec)
 /***************************** SMP support ************************************/
 #include <linux/spinlock.h>
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
-#define AHC_SCSI_HAS_HOST_LOCK 1
-#else
-#define AHC_SCSI_HAS_HOST_LOCK 0
-#endif
-
 #define AIC7XXX_DRIVER_VERSION "6.2.36"
 
 /**************************** Front End Queues ********************************/
@@ -328,20 +322,15 @@ struct ahc_cmd {
  */
 TAILQ_HEAD(ahc_busyq, ahc_cmd);
 typedef enum {
-       AHC_DEV_UNCONFIGURED     = 0x01,
        AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
-       AHC_DEV_TIMER_ACTIVE     = 0x04, /* Our timer is active */
-       AHC_DEV_ON_RUN_LIST      = 0x08, /* Queued to be run later */
        AHC_DEV_Q_BASIC          = 0x10, /* Allow basic device queuing */
        AHC_DEV_Q_TAGGED         = 0x20, /* Allow full SCSI2 command queueing */
        AHC_DEV_PERIODIC_OTAG    = 0x40, /* Send OTAG to prevent starvation */
-       AHC_DEV_SLAVE_CONFIGURED = 0x80  /* slave_configure() has been called */
 } ahc_linux_dev_flags;
 
 struct ahc_linux_target;
 struct ahc_linux_device {
        TAILQ_ENTRY(ahc_linux_device) links;
-       struct          ahc_busyq busyq;
 
        /*
         * The number of transactions currently
@@ -381,11 +370,6 @@ struct ahc_linux_device {
 
        ahc_linux_dev_flags     flags;
 
-       /*
-        * Per device timer.
-        */
-       struct timer_list       timer;
-
        /*
         * The high limit for the tags variable.
         */
@@ -419,14 +403,10 @@ struct ahc_linux_device {
 #define AHC_OTAG_THRESH        500
 
        int                     lun;
-       Scsi_Device            *scsi_device;
+       struct scsi_device       *scsi_device;
        struct                  ahc_linux_target *target;
 };
 
-typedef enum {
-       AHC_INQ_VALID            = 0x02,
-} ahc_linux_targ_flags;
-
 struct ahc_linux_target {
        struct ahc_linux_device  *devices[AHC_NUM_LUNS];
        int                       channel;
@@ -434,8 +414,6 @@ struct ahc_linux_target {
        int                       refcount;
        struct ahc_transinfo      last_tinfo;
        struct ahc_softc         *ahc;
-       ahc_linux_targ_flags      flags;
-       struct scsi_inquiry_data *inq_data;
 };
 
 /********************* Definitions Required by the Core ***********************/
@@ -445,32 +423,16 @@ struct ahc_linux_target {
  * manner and are allocated below 4GB, the number of S/G segments is
  * unrestricted.
  */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-/*
- * We dynamically adjust the number of segments in pre-2.5 kernels to
- * avoid fragmentation issues in the SCSI mid-layer's private memory
- * allocator.  See aic7xxx_osm.c ahc_linux_size_nseg() for details.
- */
-extern u_int ahc_linux_nseg;
-#define        AHC_NSEG ahc_linux_nseg
-#define        AHC_LINUX_MIN_NSEG 64
-#else
 #define        AHC_NSEG 128
-#endif
 
 /*
  * Per-SCB OSM storage.
  */
-typedef enum {
-       AHC_UP_EH_SEMAPHORE = 0x1
-} ahc_linux_scb_flags;
-
 struct scb_platform_data {
        struct ahc_linux_device *dev;
        dma_addr_t               buf_busaddr;
        uint32_t                 xfer_len;
        uint32_t                 sense_resid;   /* Auto-Sense residual */
-       ahc_linux_scb_flags      flags;
 };
 
 /*
@@ -479,39 +441,24 @@ struct scb_platform_data {
  * alignment restrictions of the various platforms supported by
  * this driver.
  */
-typedef enum {
-       AHC_RUN_CMPLT_Q_TIMER    = 0x10
-} ahc_linux_softc_flags;
-
-TAILQ_HEAD(ahc_completeq, ahc_cmd);
-
 struct ahc_platform_data {
        /*
         * Fields accessed from interrupt context.
         */
        struct ahc_linux_target *targets[AHC_NUM_TARGETS]; 
-       TAILQ_HEAD(, ahc_linux_device) device_runq;
-       struct ahc_completeq     completeq;
 
        spinlock_t               spin_lock;
-       struct tasklet_struct    runq_tasklet;
        u_int                    qfrozen;
-       pid_t                    dv_pid;
-       struct timer_list        completeq_timer;
        struct timer_list        reset_timer;
        struct semaphore         eh_sem;
-       struct semaphore         dv_sem;
-       struct semaphore         dv_cmd_sem;    /* XXX This needs to be in
-                                                * the target struct
-                                                */
-       struct scsi_device      *dv_scsi_dev;
        struct Scsi_Host        *host;          /* pointer to scsi host */
 #define AHC_LINUX_NOIRQ        ((uint32_t)~0)
        uint32_t                 irq;           /* IRQ for this adapter */
        uint32_t                 bios_address;
        uint32_t                 mem_busaddr;   /* Mem Base Addr */
-       uint64_t                 hw_dma_mask;
-       ahc_linux_softc_flags    flags;
+
+#define        AHC_UP_EH_SEMAPHORE      0x1
+       uint32_t                 flags;
 };
 
 /************************** OS Utility Wrappers *******************************/
@@ -600,7 +547,7 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
 
 /**************************** Initialization **********************************/
 int            ahc_linux_register_host(struct ahc_softc *,
-                                       Scsi_Host_Template *);
+                                       struct scsi_host_template *);
 
 uint64_t       ahc_linux_get_memsize(void);
 
@@ -621,17 +568,6 @@ static __inline void ahc_lockinit(struct ahc_softc *);
 static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags);
 static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags);
 
-/* Lock acquisition and release of the above lock in midlayer entry points. */
-static __inline void ahc_midlayer_entrypoint_lock(struct ahc_softc *,
-                                                 unsigned long *flags);
-static __inline void ahc_midlayer_entrypoint_unlock(struct ahc_softc *,
-                                                   unsigned long *flags);
-
-/* Lock held during command compeletion to the upper layer */
-static __inline void ahc_done_lockinit(struct ahc_softc *);
-static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags);
-static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags);
-
 /* Lock held during ahc_list manipulation and ahc softc frees */
 extern spinlock_t ahc_list_spinlock;
 static __inline void ahc_list_lockinit(void);
@@ -656,57 +592,6 @@ ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
        spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
 }
 
-static __inline void
-ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags)
-{
-       /*
-        * In 2.5.X and some 2.4.X versions, the midlayer takes our
-        * lock just before calling us, so we avoid locking again.
-        * For other kernel versions, the io_request_lock is taken
-        * just before our entry point is called.  In this case, we
-        * trade the io_request_lock for our per-softc lock.
-        */
-#if AHC_SCSI_HAS_HOST_LOCK == 0
-       spin_unlock(&io_request_lock);
-       spin_lock(&ahc->platform_data->spin_lock);
-#endif
-}
-
-static __inline void
-ahc_midlayer_entrypoint_unlock(struct ahc_softc *ahc, unsigned long *flags)
-{
-#if AHC_SCSI_HAS_HOST_LOCK == 0
-       spin_unlock(&ahc->platform_data->spin_lock);
-       spin_lock(&io_request_lock);
-#endif
-}
-
-static __inline void
-ahc_done_lockinit(struct ahc_softc *ahc)
-{
-       /*
-        * In 2.5.X, our own lock is held during completions.
-        * In previous versions, the io_request_lock is used.
-        * In either case, we can't initialize this lock again.
-        */
-}
-
-static __inline void
-ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags)
-{
-#if AHC_SCSI_HAS_HOST_LOCK == 0
-       spin_lock_irqsave(&io_request_lock, *flags);
-#endif
-}
-
-static __inline void
-ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags)
-{
-#if AHC_SCSI_HAS_HOST_LOCK == 0
-       spin_unlock_irqrestore(&io_request_lock, *flags);
-#endif
-}
-
 static __inline void
 ahc_list_lockinit(void)
 {
@@ -773,12 +658,6 @@ typedef enum
 } ahc_power_state;
 
 /**************************** VL/EISA Routines ********************************/
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \
-  && (defined(__i386__) || defined(__alpha__)) \
-  && (!defined(CONFIG_EISA)))
-#define CONFIG_EISA
-#endif
-
 #ifdef CONFIG_EISA
 extern uint32_t aic7xxx_probe_eisa_vl;
 int                     ahc_linux_eisa_init(void);
@@ -894,22 +773,18 @@ ahc_flush_device_writes(struct ahc_softc *ahc)
 }
 
 /**************************** Proc FS Support *********************************/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-int    ahc_linux_proc_info(char *, char **, off_t, int, int, int);
-#else
 int    ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
                            off_t, int, int);
-#endif
 
 /*************************** Domain Validation ********************************/
 /*********************** Transaction Access Wrappers *************************/
-static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
+static __inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
 static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
-static __inline void ahc_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t);
+static __inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
 static __inline void ahc_set_scsi_status(struct scb *, uint32_t);
-static __inline uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd);
+static __inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd);
 static __inline uint32_t ahc_get_transaction_status(struct scb *);
-static __inline uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd);
+static __inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd);
 static __inline uint32_t ahc_get_scsi_status(struct scb *);
 static __inline void ahc_set_transaction_tag(struct scb *, int, u_int);
 static __inline u_long ahc_get_transfer_length(struct scb *);
@@ -928,7 +803,7 @@ static __inline void ahc_platform_scb_free(struct ahc_softc *ahc,
 static __inline void ahc_freeze_scb(struct scb *scb);
 
 static __inline
-void ahc_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status)
+void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
 {
        cmd->result &= ~(CAM_STATUS_MASK << 16);
        cmd->result |= status << 16;
@@ -941,7 +816,7 @@ void ahc_set_transaction_status(struct scb *scb, uint32_t status)
 }
 
 static __inline
-void ahc_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status)
+void ahc_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
 {
        cmd->result &= ~0xFFFF;
        cmd->result |= status;
@@ -954,7 +829,7 @@ void ahc_set_scsi_status(struct scb *scb, uint32_t status)
 }
 
 static __inline
-uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd)
+uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd)
 {
        return ((cmd->result >> 16) & CAM_STATUS_MASK);
 }
@@ -966,7 +841,7 @@ uint32_t ahc_get_transaction_status(struct scb *scb)
 }
 
 static __inline
-uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd)
+uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd)
 {
        return (cmd->result & 0xFFFF);
 }
index 6f6674aa31ef4308700b2ed23b0741abceb59f35..2a0ebce83e7a61c4e0b11903fb523bdcd877fd21 100644 (file)
@@ -221,13 +221,11 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         && ahc_linux_get_memsize() > 0x80000000
         && pci_set_dma_mask(pdev, mask_39bit) == 0) {
                ahc->flags |= AHC_39BIT_ADDRESSING;
-               ahc->platform_data->hw_dma_mask = mask_39bit;
        } else {
                if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
                        printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
                        return (-ENODEV);
                }
-               ahc->platform_data->hw_dma_mask = DMA_32BIT_MASK;
        }
        ahc->dev_softc = pci;
        error = ahc_pci_config(ahc, entry);
@@ -236,15 +234,8 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                return (-error);
        }
        pci_set_drvdata(pdev, ahc);
-       if (aic7xxx_detect_complete) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       if (aic7xxx_detect_complete)
                ahc_linux_register_host(ahc, &aic7xxx_driver_template);
-#else
-               printf("aic7xxx: ignoring PCI device found after "
-                      "initialization\n");
-               return (-ENODEV);
-#endif
-       }
        return (0);
 }
 
index 85e80eecc9d044c539bc75a5b3d91d9a736ab6aa..5fece859fbd9ab8667f3a2c25e8985036c34ab68 100644 (file)
@@ -289,13 +289,8 @@ done:
  * Return information to handle /proc support for the driver.
  */
 int
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-ahc_linux_proc_info(char *buffer, char **start, off_t offset,
-                   int length, int hostno, int inout)
-#else
 ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
                    off_t offset, int length, int inout)
-#endif
 {
        struct  ahc_softc *ahc;
        struct  info_str info;
@@ -307,15 +302,7 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
 
        retval = -EINVAL;
        ahc_list_lock(&s);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-               if (ahc->platform_data->host->host_no == hostno)
-                       break;
-       }
-#else
        ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata);
-#endif
-
        if (ahc == NULL)
                goto done;
 
index 79bfd9efd8ed924451701fb1e73bdf8fd79eca22..7c5a6db0e6724c5a0aa933575f57bc603090609b 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/version.h>
 
 /* Core SCSI definitions */
-#include "scsi.h"
 #include <scsi/scsi_host.h>
 #include "aiclib.h"
 #include "cam.h"
index 3867f91ef8c7bebe3d0edf0bd2e3b326a1d4061b..3be546439252332131fac6aca81cbdea71d9934a 100644 (file)
@@ -153,6 +153,7 @@ static struct ata_port_operations piix_pata_ops = {
 
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static struct ata_port_operations piix_sata_ops = {
@@ -180,6 +181,7 @@ static struct ata_port_operations piix_sata_ops = {
 
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static struct ata_port_info piix_port_info[] = {
@@ -663,15 +665,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        return ata_pci_init_one(pdev, port_info, n_ports);
 }
 
-/**
- *     piix_init -
- *
- *     LOCKING:
- *
- *     RETURNS:
- *
- */
-
 static int __init piix_init(void)
 {
        int rc;
@@ -687,13 +680,6 @@ static int __init piix_init(void)
        return 0;
 }
 
-/**
- *     piix_exit -
- *
- *     LOCKING:
- *
- */
-
 static void __exit piix_exit(void)
 {
        pci_unregister_driver(&piix_pci_driver);
index 2e2486b035dd958352e648ff9012c2beeebc3552..83f062ed9082ac7e91e0dca720e3c57bd5a01ea7 100644 (file)
@@ -179,8 +179,18 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
                        return;
                }
                count = min(pc->sg->length - pc->b_count, bcount);
-               buf = page_address(pc->sg->page) + pc->sg->offset;
-               drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
+               if (PageHighMem(pc->sg->page)) {
+                       unsigned long flags;
+
+                       local_irq_save(flags);
+                       buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
+                       drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
+                       kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
+                       local_irq_restore(flags);
+               } else {
+                       buf = page_address(pc->sg->page) + pc->sg->offset;
+                       drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
+               }
                bcount -= count; pc->b_count += count;
                if (pc->b_count == pc->sg->length) {
                        pc->sg++;
@@ -201,8 +211,18 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
                        return;
                }
                count = min(pc->sg->length - pc->b_count, bcount);
-               buf = page_address(pc->sg->page) + pc->sg->offset;
-               drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
+               if (PageHighMem(pc->sg->page)) {
+                       unsigned long flags;
+
+                       local_irq_save(flags);
+                       buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
+                       drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
+                       kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
+                       local_irq_restore(flags);
+               } else {
+                       buf = page_address(pc->sg->page) + pc->sg->offset;
+                       drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
+               }
                bcount -= count; pc->b_count += count;
                if (pc->b_count == pc->sg->length) {
                        pc->sg++;
@@ -713,7 +733,6 @@ static void idescsi_add_settings(ide_drive_t *drive)
  */
 static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
 {
-       DRIVER(drive)->busy++;
        if (drive->id && (drive->id->config & 0x0060) == 0x20)
                set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
        set_bit(IDESCSI_TRANSFORM, &scsi->transform);
@@ -722,17 +741,16 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
        set_bit(IDESCSI_LOG_CMD, &scsi->log);
 #endif /* IDESCSI_DEBUG_LOG */
        idescsi_add_settings(drive);
-       DRIVER(drive)->busy--;
 }
 
-static int idescsi_cleanup (ide_drive_t *drive)
+static int ide_scsi_remove(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        struct Scsi_Host *scsihost = drive->driver_data;
        struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
        struct gendisk *g = scsi->disk;
 
-       if (ide_unregister_subdriver(drive))
-               return 1;
+       ide_unregister_subdriver(drive, scsi->driver);
 
        ide_unregister_region(g);
 
@@ -746,7 +764,7 @@ static int idescsi_cleanup (ide_drive_t *drive)
        return 0;
 }
 
-static int idescsi_attach(ide_drive_t *drive);
+static int ide_scsi_probe(struct device *);
 
 #ifdef CONFIG_PROC_FS
 static ide_proc_entry_t idescsi_proc[] = {
@@ -757,24 +775,22 @@ static ide_proc_entry_t idescsi_proc[] = {
 # define idescsi_proc  NULL
 #endif
 
-/*
- *     IDE subdriver functions, registered with ide.c
- */
 static ide_driver_t idescsi_driver = {
        .owner                  = THIS_MODULE,
-       .name                   = "ide-scsi",
+       .gen_driver = {
+               .name           = "ide-scsi",
+               .bus            = &ide_bus_type,
+               .probe          = ide_scsi_probe,
+               .remove         = ide_scsi_remove,
+       },
        .version                = IDESCSI_VERSION,
        .media                  = ide_scsi,
-       .busy                   = 0,
        .supports_dsc_overlap   = 0,
        .proc                   = idescsi_proc,
-       .attach                 = idescsi_attach,
-       .cleanup                = idescsi_cleanup,
        .do_request             = idescsi_do_request,
        .end_request            = idescsi_end_request,
        .error                  = idescsi_atapi_error,
        .abort                  = idescsi_atapi_abort,
-       .drives                 = LIST_HEAD_INIT(idescsi_driver.drives),
 };
 
 static int idescsi_ide_open(struct inode *inode, struct file *filp)
@@ -821,8 +837,6 @@ static struct block_device_operations idescsi_ops = {
        .ioctl          = idescsi_ide_ioctl,
 };
 
-static int idescsi_attach(ide_drive_t *drive);
-
 static int idescsi_slave_configure(struct scsi_device * sdp)
 {
        /* Configure detected device */
@@ -1095,8 +1109,9 @@ static struct scsi_host_template idescsi_template = {
        .proc_name              = "ide-scsi",
 };
 
-static int idescsi_attach(ide_drive_t *drive)
+static int ide_scsi_probe(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        idescsi_scsi_t *idescsi;
        struct Scsi_Host *host;
        struct gendisk *g;
@@ -1112,7 +1127,7 @@ static int idescsi_attach(ide_drive_t *drive)
            !drive->present ||
            drive->media == ide_disk ||
            !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
-               return 1;
+               return -ENODEV;
 
        g = alloc_disk(1 << PARTN_BITS);
        if (!g)
@@ -1138,20 +1153,19 @@ static int idescsi_attach(ide_drive_t *drive)
        idescsi->host = host;
        idescsi->disk = g;
        g->private_data = &idescsi->driver;
-       err = ide_register_subdriver(drive, &idescsi_driver);
+       ide_register_subdriver(drive, &idescsi_driver);
+       err = 0;
+       idescsi_setup(drive, idescsi);
+       g->fops = &idescsi_ops;
+       ide_register_region(g);
+       err = scsi_add_host(host, &drive->gendev);
        if (!err) {
-               idescsi_setup (drive, idescsi);
-               g->fops = &idescsi_ops;
-               ide_register_region(g);
-               err = scsi_add_host(host, &drive->gendev);
-               if (!err) {
-                       scsi_scan_host(host);
-                       return 0;
-               }
-               /* fall through on error */
-               ide_unregister_region(g);
-               ide_unregister_subdriver(drive);
+               scsi_scan_host(host);
+               return 0;
        }
+       /* fall through on error */
+       ide_unregister_region(g);
+       ide_unregister_subdriver(drive, &idescsi_driver);
 
        put_disk(g);
 out_host_put:
@@ -1161,12 +1175,12 @@ out_host_put:
 
 static int __init init_idescsi_module(void)
 {
-       return ide_register_driver(&idescsi_driver);
+       return driver_register(&idescsi_driver.gen_driver);
 }
 
 static void __exit exit_idescsi_module(void)
 {
-       ide_unregister_driver(&idescsi_driver);
+       driver_unregister(&idescsi_driver.gen_driver);
 }
 
 module_init(init_idescsi_module);
index 0b5d3a5b7edab5ce17889a0e698805ce346b4d1a..9e58f134f68bf45767813d249220b322a33b005b 100644 (file)
@@ -186,6 +186,28 @@ static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
        ata_wait_idle(ap);
 }
 
+
+/**
+ *     ata_tf_load - send taskfile registers to host controller
+ *     @ap: Port to which output is sent
+ *     @tf: ATA taskfile register set
+ *
+ *     Outputs ATA taskfile to standard ATA host controller using MMIO
+ *     or PIO as indicated by the ATA_FLAG_MMIO flag.
+ *     Writes the control, feature, nsect, lbal, lbam, and lbah registers.
+ *     Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
+ *     hob_lbal, hob_lbam, and hob_lbah.
+ *
+ *     This function waits for idle (!BUSY and !DRQ) after writing
+ *     registers.  If the control register has a new value, this
+ *     function also waits for idle after writing control and before
+ *     writing the remaining registers.
+ *
+ *     May be used as the tf_load() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
 void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
 {
        if (ap->flags & ATA_FLAG_MMIO)
@@ -195,11 +217,11 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
 }
 
 /**
- *     ata_exec_command - issue ATA command to host controller
+ *     ata_exec_command_pio - issue ATA command to host controller
  *     @ap: port to which command is being issued
  *     @tf: ATA taskfile register set
  *
- *     Issues PIO/MMIO write to ATA command register, with proper
+ *     Issues PIO write to ATA command register, with proper
  *     synchronization with interrupt handler / other threads.
  *
  *     LOCKING:
@@ -235,6 +257,18 @@ static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
        ata_pause(ap);
 }
 
+
+/**
+ *     ata_exec_command - issue ATA command to host controller
+ *     @ap: port to which command is being issued
+ *     @tf: ATA taskfile register set
+ *
+ *     Issues PIO/MMIO write to ATA command register, with proper
+ *     synchronization with interrupt handler / other threads.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
 void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
 {
        if (ap->flags & ATA_FLAG_MMIO)
@@ -305,7 +339,7 @@ void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf)
 }
 
 /**
- *     ata_tf_read - input device's ATA taskfile shadow registers
+ *     ata_tf_read_pio - input device's ATA taskfile shadow registers
  *     @ap: Port from which input is read
  *     @tf: ATA taskfile register set for storing input
  *
@@ -368,6 +402,23 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
        }
 }
 
+
+/**
+ *     ata_tf_read - input device's ATA taskfile shadow registers
+ *     @ap: Port from which input is read
+ *     @tf: ATA taskfile register set for storing input
+ *
+ *     Reads ATA taskfile registers for currently-selected device
+ *     into @tf.
+ *
+ *     Reads nsect, lbal, lbam, lbah, and device.  If ATA_TFLAG_LBA48
+ *     is set, also reads the hob registers.
+ *
+ *     May be used as the tf_read() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
 void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
 {
        if (ap->flags & ATA_FLAG_MMIO)
@@ -381,7 +432,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
  *     @ap: port where the device is
  *
  *     Reads ATA taskfile status register for currently-selected device
- *     and return it's value. This also clears pending interrupts
+ *     and return its value. This also clears pending interrupts
  *      from this device
  *
  *     LOCKING:
@@ -397,7 +448,7 @@ static u8 ata_check_status_pio(struct ata_port *ap)
  *     @ap: port where the device is
  *
  *     Reads ATA taskfile status register for currently-selected device
- *     via MMIO and return it's value. This also clears pending interrupts
+ *     via MMIO and return its value. This also clears pending interrupts
  *      from this device
  *
  *     LOCKING:
@@ -408,6 +459,20 @@ static u8 ata_check_status_mmio(struct ata_port *ap)
                return readb((void __iomem *) ap->ioaddr.status_addr);
 }
 
+
+/**
+ *     ata_check_status - Read device status reg & clear interrupt
+ *     @ap: port where the device is
+ *
+ *     Reads ATA taskfile status register for currently-selected device
+ *     and return its value. This also clears pending interrupts
+ *      from this device
+ *
+ *     May be used as the check_status() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
 u8 ata_check_status(struct ata_port *ap)
 {
        if (ap->flags & ATA_FLAG_MMIO)
@@ -415,6 +480,20 @@ u8 ata_check_status(struct ata_port *ap)
        return ata_check_status_pio(ap);
 }
 
+
+/**
+ *     ata_altstatus - Read device alternate status reg
+ *     @ap: port where the device is
+ *
+ *     Reads ATA taskfile alternate status register for
+ *     currently-selected device and return its value.
+ *
+ *     Note: may NOT be used as the check_altstatus() entry in
+ *     ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
 u8 ata_altstatus(struct ata_port *ap)
 {
        if (ap->ops->check_altstatus)
@@ -425,6 +504,20 @@ u8 ata_altstatus(struct ata_port *ap)
        return inb(ap->ioaddr.altstatus_addr);
 }
 
+
+/**
+ *     ata_chk_err - Read device error reg
+ *     @ap: port where the device is
+ *
+ *     Reads ATA taskfile error register for
+ *     currently-selected device and return its value.
+ *
+ *     Note: may NOT be used as the check_err() entry in
+ *     ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
 u8 ata_chk_err(struct ata_port *ap)
 {
        if (ap->ops->check_err)
@@ -873,10 +966,24 @@ void ata_dev_id_string(u16 *id, unsigned char *s,
        }
 }
 
+
+/**
+ *     ata_noop_dev_select - Select device 0/1 on ATA bus
+ *     @ap: ATA channel to manipulate
+ *     @device: ATA device (numbered from zero) to select
+ *
+ *     This function performs no actual function.
+ *
+ *     May be used as the dev_select() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     caller.
+ */
 void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
 {
 }
 
+
 /**
  *     ata_std_dev_select - Select device 0/1 on ATA bus
  *     @ap: ATA channel to manipulate
@@ -884,7 +991,9 @@ void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
  *
  *     Use the method defined in the ATA specification to
  *     make either device 0, or device 1, active on the
- *     ATA channel.
+ *     ATA channel.  Works with both PIO and MMIO.
+ *
+ *     May be used as the dev_select() entry in ata_port_operations.
  *
  *     LOCKING:
  *     caller.
@@ -1190,7 +1299,12 @@ err_out:
  *     ata_bus_probe - Reset and probe ATA bus
  *     @ap: Bus to probe
  *
+ *     Master ATA bus probing function.  Initiates a hardware-dependent
+ *     bus reset, then attempts to identify any devices found on
+ *     the bus.
+ *
  *     LOCKING:
+ *     PCI/etc. bus probe sem.
  *
  *     RETURNS:
  *     Zero on success, non-zero on error.
@@ -1229,10 +1343,14 @@ err_out:
 }
 
 /**
- *     ata_port_probe -
- *     @ap:
+ *     ata_port_probe - Mark port as enabled
+ *     @ap: Port for which we indicate enablement
  *
- *     LOCKING:
+ *     Modify @ap data structure such that the system
+ *     thinks that the entire port is enabled.
+ *
+ *     LOCKING: host_set lock, or some other form of
+ *     serialization.
  */
 
 void ata_port_probe(struct ata_port *ap)
@@ -1241,10 +1359,15 @@ void ata_port_probe(struct ata_port *ap)
 }
 
 /**
- *     __sata_phy_reset -
- *     @ap:
+ *     __sata_phy_reset - Wake/reset a low-level SATA PHY
+ *     @ap: SATA port associated with target SATA PHY.
+ *
+ *     This function issues commands to standard SATA Sxxx
+ *     PHY registers, to wake up the phy (and device), and
+ *     clear any reset condition.
  *
  *     LOCKING:
+ *     PCI/etc. bus probe sem.
  *
  */
 void __sata_phy_reset(struct ata_port *ap)
@@ -1253,11 +1376,11 @@ void __sata_phy_reset(struct ata_port *ap)
        unsigned long timeout = jiffies + (HZ * 5);
 
        if (ap->flags & ATA_FLAG_SATA_RESET) {
-               scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */
-               scr_read(ap, SCR_STATUS);       /* dummy read; flush */
+               /* issue phy wake/reset */
+               scr_write_flush(ap, SCR_CONTROL, 0x301);
                udelay(400);                    /* FIXME: a guess */
        }
-       scr_write(ap, SCR_CONTROL, 0x300);      /* issue phy wake/clear reset */
+       scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
 
        /* wait for phy to become ready, if necessary */
        do {
@@ -1289,10 +1412,14 @@ void __sata_phy_reset(struct ata_port *ap)
 }
 
 /**
- *     __sata_phy_reset -
- *     @ap:
+ *     sata_phy_reset - Reset SATA bus.
+ *     @ap: SATA port associated with target SATA PHY.
+ *
+ *     This function resets the SATA bus, and then probes
+ *     the bus for devices.
  *
  *     LOCKING:
+ *     PCI/etc. bus probe sem.
  *
  */
 void sata_phy_reset(struct ata_port *ap)
@@ -1304,10 +1431,16 @@ void sata_phy_reset(struct ata_port *ap)
 }
 
 /**
- *     ata_port_disable -
- *     @ap:
+ *     ata_port_disable - Disable port.
+ *     @ap: Port to be disabled.
  *
- *     LOCKING:
+ *     Modify @ap data structure such that the system
+ *     thinks that the entire port is disabled, and should
+ *     never attempt to probe or communicate with devices
+ *     on this port.
+ *
+ *     LOCKING: host_set lock, or some other form of
+ *     serialization.
  */
 
 void ata_port_disable(struct ata_port *ap)
@@ -1416,7 +1549,10 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
  *     ata_set_mode - Program timings and issue SET FEATURES - XFER
  *     @ap: port on which timings will be programmed
  *
+ *     Set ATA device disk transfer mode (PIO3, UDMA6, etc.).
+ *
  *     LOCKING:
+ *     PCI/etc. bus probe sem.
  *
  */
 static void ata_set_mode(struct ata_port *ap)
@@ -1467,7 +1603,10 @@ err_out:
  *     @tmout_pat: impatience timeout
  *     @tmout: overall timeout
  *
- *     LOCKING:
+ *     Sleep until ATA Status register bit BSY clears,
+ *     or a timeout occurs.
+ *
+ *     LOCKING: None.
  *
  */
 
@@ -1553,10 +1692,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
 }
 
 /**
- *     ata_bus_edd -
- *     @ap:
+ *     ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
+ *     @ap: Port to reset and probe
+ *
+ *     Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
+ *     probe the bus.  Not often used these days.
  *
  *     LOCKING:
+ *     PCI/etc. bus probe sem.
  *
  */
 
@@ -1633,8 +1776,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
  *     the device is ATA or ATAPI.
  *
  *     LOCKING:
- *     Inherited from caller.  Some functions called by this function
- *     obtain the host_set lock.
+ *     PCI/etc. bus probe sem.
+ *     Obtains host_set lock.
  *
  *     SIDE EFFECTS:
  *     Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
@@ -1876,7 +2019,11 @@ static int fgb(u32 bitmap)
  *     @xfer_mode_out: (output) SET FEATURES - XFER MODE code
  *     @xfer_shift_out: (output) bit shift that selects this mode
  *
+ *     Based on host and device capabilities, determine the
+ *     maximum transfer mode that is amenable to all.
+ *
  *     LOCKING:
+ *     PCI/etc. bus probe sem.
  *
  *     RETURNS:
  *     Zero on success, negative on error.
@@ -1909,7 +2056,11 @@ static int ata_choose_xfer_mode(struct ata_port *ap,
  *     @ap: Port associated with device @dev
  *     @dev: Device to which command will be sent
  *
+ *     Issue SET FEATURES - XFER MODE command to device @dev
+ *     on port @ap.
+ *
  *     LOCKING:
+ *     PCI/etc. bus probe sem.
  */
 
 static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
@@ -1947,10 +2098,13 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
 }
 
 /**
- *     ata_sg_clean -
- *     @qc:
+ *     ata_sg_clean - Unmap DMA memory associated with command
+ *     @qc: Command containing DMA memory to be released
+ *
+ *     Unmap all mapped DMA memory associated with this command.
  *
  *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
  */
 
 static void ata_sg_clean(struct ata_queued_cmd *qc)
@@ -1981,7 +2135,11 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
  *     ata_fill_sg - 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.
+ *
  *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
  *
  */
 static void ata_fill_sg(struct ata_queued_cmd *qc)
@@ -2028,7 +2186,13 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
  *     ata_check_atapi_dma - Check whether ATAPI DMA can be supported
  *     @qc: Metadata associated with taskfile to check
  *
+ *     Allow low-level driver to filter ATA PACKET commands, returning
+ *     a status indicating whether or not it is OK to use DMA for the
+ *     supplied PACKET command.
+ *
  *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ *
  *     RETURNS: 0 when ATAPI DMA can be used
  *               nonzero otherwise
  */
@@ -2046,6 +2210,8 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
  *     ata_qc_prep - Prepare taskfile for submission
  *     @qc: Metadata associated with taskfile to be prepared
  *
+ *     Prepare ATA taskfile for submission.
+ *
  *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
  */
@@ -2057,6 +2223,32 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
        ata_fill_sg(qc);
 }
 
+/**
+ *     ata_sg_init_one - Associate command with memory buffer
+ *     @qc: Command to be associated
+ *     @buf: Memory buffer
+ *     @buflen: Length of memory buffer, in bytes.
+ *
+ *     Initialize the data-related elements of queued_cmd @qc
+ *     to point to a single memory buffer, @buf of byte length @buflen.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+
+
+
+/**
+ *     ata_sg_init_one - Prepare a one-entry scatter-gather list.
+ *     @qc:  Queued command
+ *     @buf:  transfer buffer
+ *     @buflen:  length of buf
+ *
+ *     Builds a single-entry scatter-gather list to initiate a
+ *     transfer utilizing the specified buffer.
+ *
+ *     LOCKING:
+ */
 void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
 {
        struct scatterlist *sg;
@@ -2071,9 +2263,35 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
        sg = qc->sg;
        sg->page = virt_to_page(buf);
        sg->offset = (unsigned long) buf & ~PAGE_MASK;
-       sg_dma_len(sg) = buflen;
+       sg->length = buflen;
 }
 
+/**
+ *     ata_sg_init - Associate command with scatter-gather table.
+ *     @qc: Command to be associated
+ *     @sg: Scatter-gather table.
+ *     @n_elem: Number of elements in s/g table.
+ *
+ *     Initialize the data-related elements of queued_cmd @qc
+ *     to point to a scatter-gather table @sg, containing @n_elem
+ *     elements.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+
+
+/**
+ *     ata_sg_init - Assign a scatter gather list to a queued command
+ *     @qc:  Queued command
+ *     @sg:  Scatter-gather list
+ *     @n_elem:  length of sg list
+ *
+ *     Attaches a scatter-gather list to a queued command.
+ *
+ *     LOCKING:
+ */
+
 void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
                 unsigned int n_elem)
 {
@@ -2083,14 +2301,16 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
 }
 
 /**
- *     ata_sg_setup_one -
- *     @qc:
+ *     ata_sg_setup_one - DMA-map the memory buffer associated with a command.
+ *     @qc: Command with memory buffer to be mapped.
+ *
+ *     DMA-map the memory buffer associated with queued_cmd @qc.
  *
  *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
  *
  *     RETURNS:
- *
+ *     Zero on success, negative on error.
  */
 
 static int ata_sg_setup_one(struct ata_queued_cmd *qc)
@@ -2101,11 +2321,12 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
        dma_addr_t dma_address;
 
        dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
-                                    sg_dma_len(sg), dir);
+                                    sg->length, dir);
        if (dma_mapping_error(dma_address))
                return -1;
 
        sg_dma_address(sg) = dma_address;
+       sg_dma_len(sg) = sg->length;
 
        DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
                qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
@@ -2114,13 +2335,16 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
 }
 
 /**
- *     ata_sg_setup -
- *     @qc:
+ *     ata_sg_setup - DMA-map the scatter-gather table associated with a command.
+ *     @qc: Command with scatter-gather table to be mapped.
+ *
+ *     DMA-map the scatter-gather table associated with queued_cmd @qc.
  *
  *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
  *
  *     RETURNS:
+ *     Zero on success, negative on error.
  *
  */
 
@@ -2150,6 +2374,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
  *     @ap:
  *
  *     LOCKING:
+ *     None.  (executing in kernel thread context)
  *
  *     RETURNS:
  *
@@ -2197,6 +2422,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
  *     @ap:
  *
  *     LOCKING:
+ *     None.  (executing in kernel thread context)
  */
 
 static void ata_pio_complete (struct ata_port *ap)
@@ -2239,6 +2465,18 @@ static void ata_pio_complete (struct ata_port *ap)
        ata_qc_complete(qc, drv_stat);
 }
 
+
+/**
+ *     swap_buf_le16 -
+ *     @buf:  Buffer to swap
+ *     @buf_words:  Number of 16-bit words in buffer.
+ *
+ *     Swap halves of 16-bit words if needed to convert from
+ *     little-endian byte order to native cpu byte order, or
+ *     vice-versa.
+ *
+ *     LOCKING:
+ */
 void swap_buf_le16(u16 *buf, unsigned int buf_words)
 {
 #ifdef __BIG_ENDIAN
@@ -2310,7 +2548,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
        qc->cursect++;
        qc->cursg_ofs++;
 
-       if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) {
+       if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) {
                qc->cursg++;
                qc->cursg_ofs = 0;
        }
@@ -2339,7 +2577,6 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
 next_sg:
        sg = &qc->sg[qc->cursg];
 
-next_page:
        page = sg->page;
        offset = sg->offset + qc->cursg_ofs;
 
@@ -2347,7 +2584,8 @@ next_page:
        page = nth_page(page, (offset >> PAGE_SHIFT));
        offset %= PAGE_SIZE;
 
-       count = min(sg_dma_len(sg) - qc->cursg_ofs, bytes);
+       /* don't overrun current sg */
+       count = min(sg->length - qc->cursg_ofs, bytes);
 
        /* don't cross page boundaries */
        count = min(count, (unsigned int)PAGE_SIZE - offset);
@@ -2358,7 +2596,7 @@ next_page:
        qc->curbytes += count;
        qc->cursg_ofs += count;
 
-       if (qc->cursg_ofs == sg_dma_len(sg)) {
+       if (qc->cursg_ofs == sg->length) {
                qc->cursg++;
                qc->cursg_ofs = 0;
        }
@@ -2371,8 +2609,6 @@ next_page:
        kunmap(page);
 
        if (bytes) {
-               if (qc->cursg_ofs < sg_dma_len(sg))
-                       goto next_page;
                goto next_sg;
        }
 }
@@ -2414,6 +2650,7 @@ err_out:
  *     @ap:
  *
  *     LOCKING:
+ *     None.  (executing in kernel thread context)
  */
 
 static void ata_pio_block(struct ata_port *ap)
@@ -2539,7 +2776,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
        ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
        qc->dma_dir = DMA_FROM_DEVICE;
 
-       memset(&qc->cdb, 0, sizeof(ap->cdb_len));
+       memset(&qc->cdb, 0, ap->cdb_len);
        qc->cdb[0] = REQUEST_SENSE;
        qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
 
@@ -2582,6 +2819,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
  *     transaction completed successfully.
  *
  *     LOCKING:
+ *     Inherited from SCSI layer (none, can sleep)
  */
 
 static void ata_qc_timeout(struct ata_queued_cmd *qc)
@@ -2691,6 +2929,7 @@ out:
  *     @dev: Device from whom we request an available command structure
  *
  *     LOCKING:
+ *     None.
  */
 
 static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
@@ -2716,6 +2955,7 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
  *     @dev: Device from whom we request an available command structure
  *
  *     LOCKING:
+ *     None.
  */
 
 struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
@@ -2780,6 +3020,7 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
  *     in case something prevents using it.
  *
  *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
  *
  */
 void ata_qc_free(struct ata_queued_cmd *qc)
@@ -2793,9 +3034,13 @@ void ata_qc_free(struct ata_queued_cmd *qc)
 /**
  *     ata_qc_complete - Complete an active ATA command
  *     @qc: Command to complete
- *     @drv_stat: ATA status register contents
+ *     @drv_stat: ATA Status register contents
+ *
+ *     Indicate to the mid and upper layers that an ATA
+ *     command has completed, with either an ok or not-ok status.
  *
  *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
  *
  */
 
@@ -2811,6 +3056,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
 
        /* call completion callback */
        rc = qc->complete_fn(qc, drv_stat);
+       qc->flags &= ~ATA_QCFLAG_ACTIVE;
 
        /* if callback indicates not to complete command (non-zero),
         * return immediately
@@ -2890,6 +3136,7 @@ err_out:
        return -1;
 }
 
+
 /**
  *     ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
  *     @qc: command to issue to device
@@ -2899,6 +3146,8 @@ err_out:
  *     classes called "protocols", and issuing each type of protocol
  *     is slightly different.
  *
+ *     May be used as the qc_issue() entry in ata_port_operations.
+ *
  *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
  *
@@ -2956,7 +3205,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
 }
 
 /**
- *     ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+ *     ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
  *     @qc: Info associated with this ATA transaction.
  *
  *     LOCKING:
@@ -3063,6 +3312,18 @@ static void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
             ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 }
 
+
+/**
+ *     ata_bmdma_start - Start a PCI IDE BMDMA transaction
+ *     @qc: Info associated with this ATA transaction.
+ *
+ *     Writes the ATA_DMA_START flag to the DMA command register.
+ *
+ *     May be used as the bmdma_start() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
 void ata_bmdma_start(struct ata_queued_cmd *qc)
 {
        if (qc->ap->flags & ATA_FLAG_MMIO)
@@ -3071,6 +3332,20 @@ void ata_bmdma_start(struct ata_queued_cmd *qc)
                ata_bmdma_start_pio(qc);
 }
 
+
+/**
+ *     ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+ *     @qc: Info associated with this ATA transaction.
+ *
+ *     Writes address of PRD table to device's PRD Table Address
+ *     register, sets the DMA control register, and calls
+ *     ops->exec_command() to start the transfer.
+ *
+ *     May be used as the bmdma_setup() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
 void ata_bmdma_setup(struct ata_queued_cmd *qc)
 {
        if (qc->ap->flags & ATA_FLAG_MMIO)
@@ -3079,6 +3354,19 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
                ata_bmdma_setup_pio(qc);
 }
 
+
+/**
+ *     ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
+ *     @ap: Port associated with this ATA transaction.
+ *
+ *     Clear interrupt and error flags in DMA status register.
+ *
+ *     May be used as the irq_clear() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+
 void ata_bmdma_irq_clear(struct ata_port *ap)
 {
     if (ap->flags & ATA_FLAG_MMIO) {
@@ -3091,6 +3379,19 @@ void ata_bmdma_irq_clear(struct ata_port *ap)
 
 }
 
+
+/**
+ *     ata_bmdma_status - Read PCI IDE BMDMA status
+ *     @ap: Port associated with this ATA transaction.
+ *
+ *     Read and return BMDMA status register.
+ *
+ *     May be used as the bmdma_status() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+
 u8 ata_bmdma_status(struct ata_port *ap)
 {
        u8 host_stat;
@@ -3102,6 +3403,19 @@ u8 ata_bmdma_status(struct ata_port *ap)
        return host_stat;
 }
 
+
+/**
+ *     ata_bmdma_stop - Stop PCI IDE BMDMA transfer
+ *     @ap: Port associated with this ATA transaction.
+ *
+ *     Clears the ATA_DMA_START flag in the dma control register
+ *
+ *     May be used as the bmdma_stop() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+
 void ata_bmdma_stop(struct ata_port *ap)
 {
        if (ap->flags & ATA_FLAG_MMIO) {
@@ -3201,13 +3515,18 @@ idle_irq:
 
 /**
  *     ata_interrupt - Default ATA host interrupt handler
- *     @irq: irq line
- *     @dev_instance: pointer to our host information structure
+ *     @irq: irq line (unused)
+ *     @dev_instance: pointer to our ata_host_set information structure
  *     @regs: unused
  *
+ *     Default interrupt handler for PCI IDE devices.  Calls
+ *     ata_host_intr() for each port that is not disabled.
+ *
  *     LOCKING:
+ *     Obtains host_set lock during operation.
  *
  *     RETURNS:
+ *     IRQ_NONE or IRQ_HANDLED.
  *
  */
 
@@ -3229,7 +3548,8 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
                        struct ata_queued_cmd *qc;
 
                        qc = ata_qc_from_tag(ap, ap->active_tag);
-                       if (qc && (!(qc->tf.ctl & ATA_NIEN)))
+                       if (qc && (!(qc->tf.ctl & ATA_NIEN)) &&
+                           (qc->flags & ATA_QCFLAG_ACTIVE))
                                handled |= ata_host_intr(ap, qc);
                }
        }
@@ -3299,6 +3619,19 @@ err_out:
        ata_qc_complete(qc, ATA_ERR);
 }
 
+
+/**
+ *     ata_port_start - Set port up for dma.
+ *     @ap: Port to initialize
+ *
+ *     Called just after data structures for each port are
+ *     initialized.  Allocates space for PRD table.
+ *
+ *     May be used as the port_start() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ */
+
 int ata_port_start (struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
@@ -3312,6 +3645,18 @@ int ata_port_start (struct ata_port *ap)
        return 0;
 }
 
+
+/**
+ *     ata_port_stop - Undo ata_port_start()
+ *     @ap: Port to shut down
+ *
+ *     Frees the PRD table.
+ *
+ *     May be used as the port_stop() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ */
+
 void ata_port_stop (struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
@@ -3319,6 +3664,13 @@ void ata_port_stop (struct ata_port *ap)
        dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
 }
 
+void ata_host_stop (struct ata_host_set *host_set)
+{
+       if (host_set->mmio_base)
+               iounmap(host_set->mmio_base);
+}
+
+
 /**
  *     ata_host_remove - Unregister SCSI host structure with upper layers
  *     @ap: Port to unregister
@@ -3347,7 +3699,11 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
  *     @ent: Probe information provided by low-level driver
  *     @port_no: Port number associated with this ata_port
  *
+ *     Initialize a new ata_port structure, and its associated
+ *     scsi_host.
+ *
  *     LOCKING:
+ *     Inherited from caller.
  *
  */
 
@@ -3402,9 +3758,13 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
  *     @host_set: Collections of ports to which we add
  *     @port_no: Port number associated with this host
  *
+ *     Attach low-level ATA driver to system.
+ *
  *     LOCKING:
+ *     PCI/etc. bus probe sem.
  *
  *     RETURNS:
+ *     New ata_port on success, for NULL on error.
  *
  */
 
@@ -3437,12 +3797,22 @@ err_out:
 }
 
 /**
- *     ata_device_add -
- *     @ent:
+ *     ata_device_add - Register hardware device with ATA and SCSI layers
+ *     @ent: Probe information describing hardware device to be registered
+ *
+ *     This function processes the information provided in the probe
+ *     information struct @ent, allocates the necessary ATA and SCSI
+ *     host information structures, initializes them, and registers
+ *     everything with requisite kernel subsystems.
+ *
+ *     This function requests irqs, probes the ATA bus, and probes
+ *     the SCSI bus.
  *
  *     LOCKING:
+ *     PCI/etc. bus probe sem.
  *
  *     RETURNS:
+ *     Number of ports registered.  Zero on error (no ports registered).
  *
  */
 
@@ -3594,7 +3964,15 @@ int ata_scsi_release(struct Scsi_Host *host)
 /**
  *     ata_std_ports - initialize ioaddr with standard port offsets.
  *     @ioaddr: IO address structure to be initialized
+ *
+ *     Utility function which initializes data_addr, error_addr,
+ *     feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
+ *     device_addr, status_addr, and command_addr to standard offsets
+ *     relative to cmd_addr.
+ *
+ *     Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
  */
+
 void ata_std_ports(struct ata_ioports *ioaddr)
 {
        ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
@@ -3636,6 +4014,20 @@ ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
        return probe_ent;
 }
 
+
+
+/**
+ *     ata_pci_init_native_mode - Initialize native-mode driver
+ *     @pdev:  pci device to be initialized
+ *     @port:  array[2] of pointers to port info structures.
+ *
+ *     Utility function which allocates and initializes an
+ *     ata_probe_ent structure for a standard dual-port
+ *     PIO-based IDE controller.  The returned ata_probe_ent
+ *     structure can be passed to ata_device_add().  The returned
+ *     ata_probe_ent structure should then be freed with kfree().
+ */
+
 #ifdef CONFIG_PCI
 struct ata_probe_ent *
 ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
@@ -3717,10 +4109,19 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
  *     @port_info: Information from low-level host driver
  *     @n_ports: Number of ports attached to host controller
  *
+ *     This is a helper function which can be called from a driver's
+ *     xxx_init_one() probe function if the hardware uses traditional
+ *     IDE taskfile registers.
+ *
+ *     This function calls pci_enable_device(), reserves its register
+ *     regions, sets the dma mask, enables bus master mode, and calls
+ *     ata_device_add()
+ *
  *     LOCKING:
  *     Inherited from PCI layer (may sleep).
  *
  *     RETURNS:
+ *     Zero on success, negative on errno-based value on error.
  *
  */
 
@@ -3875,10 +4276,6 @@ void ata_pci_remove_one (struct pci_dev *pdev)
        }
 
        free_irq(host_set->irq, host_set);
-       if (host_set->ops->host_stop)
-               host_set->ops->host_stop(host_set);
-       if (host_set->mmio_base)
-               iounmap(host_set->mmio_base);
 
        for (i = 0; i < host_set->n_ports; i++) {
                ap = host_set->ports[i];
@@ -3897,6 +4294,9 @@ void ata_pci_remove_one (struct pci_dev *pdev)
                scsi_host_put(ap->host);
        }
 
+       if (host_set->ops->host_stop)
+               host_set->ops->host_stop(host_set);
+
        kfree(host_set);
 
        pci_release_regions(pdev);
@@ -3940,15 +4340,6 @@ int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits)
 #endif /* CONFIG_PCI */
 
 
-/**
- *     ata_init -
- *
- *     LOCKING:
- *
- *     RETURNS:
- *
- */
-
 static int __init ata_init(void)
 {
        ata_wq = create_workqueue("ata");
@@ -3994,6 +4385,7 @@ EXPORT_SYMBOL_GPL(ata_chk_err);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
 EXPORT_SYMBOL_GPL(ata_port_stop);
+EXPORT_SYMBOL_GPL(ata_host_stop);
 EXPORT_SYMBOL_GPL(ata_interrupt);
 EXPORT_SYMBOL_GPL(ata_qc_prep);
 EXPORT_SYMBOL_GPL(ata_bmdma_setup);
index 4c96df060c3bad9af44ab4c4664d8cba38c63030..7a4adc4c8f09d6ef9cdb7460f4e6846d0def4647 100644 (file)
@@ -347,7 +347,10 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
                 */
                if ((dev->flags & ATA_DFLAG_LBA48) &&
                    ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
-                       sdev->host->max_sectors = 2048;
+                       /*
+                        * do not overwrite sdev->host->max_sectors, since
+                        * other drives on this host may not support LBA48
+                        */
                        blk_queue_max_sectors(sdev->request_queue, 2048);
                }
        }
@@ -944,7 +947,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
 }
 
 /**
- *     ata_scsiop_noop -
+ *     ata_scsiop_noop - Command handler that simply returns success.
  *     @args: device IDENTIFY data / SCSI command of interest.
  *     @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *     @buflen: Response buffer length.
index 6518226b8f87f2e92d75694420d593498cba00e1..d90430bbb0de1032bc40e6835550962ac4dbdd5f 100644 (file)
@@ -26,7 +26,7 @@
 #define __LIBATA_H__
 
 #define DRV_NAME       "libata"
-#define DRV_VERSION    "1.10"  /* must be exactly four chars */
+#define DRV_VERSION    "1.11"  /* must be exactly four chars */
 
 struct ata_scsi_args {
        u16                     *id;
index 2240a0cde583d6c62279adc35b9b269377aeb4c5..9bc1f153f7eaf833f0aa3d77082b3ac5fc9b5f37 100644 (file)
@@ -300,7 +300,7 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
        rport->dev_loss_tmo = ha->port_down_retry_count + 5;
 }
 
-static struct fc_function_template qla2xxx_transport_functions = {
+struct fc_function_template qla2xxx_transport_functions = {
 
        .show_host_node_name = 1,
        .show_host_port_name = 1,
@@ -322,12 +322,6 @@ static struct fc_function_template qla2xxx_transport_functions = {
 
 };
 
-struct scsi_transport_template *
-qla2x00_alloc_transport_tmpl(void)
-{
-       return (fc_attach_transport(&qla2xxx_transport_functions));
-}
-
 void
 qla2x00_init_host_attr(scsi_qla_host_t *ha)
 {
index e4bfe4d5bbe4b6ed206b7365fdc286a3591a7488..2efec6c24d60f75aff6fb5721a496eabebcecf2c 100644 (file)
@@ -24,7 +24,6 @@
 #define        __QLA_GBL_H
 
 #include <linux/interrupt.h>
-#include <scsi/scsi_transport.h>
 
 extern void qla2x00_remove_one(struct pci_dev *);
 extern int qla2x00_probe_one(struct pci_dev *, struct qla_board_info *);
@@ -248,9 +247,10 @@ extern void qla2x00_cancel_io_descriptors(scsi_qla_host_t *);
 /*
  * Global Function Prototypes in qla_attr.c source file.
  */
+struct fc_function_template;
+extern struct fc_function_template qla2xxx_transport_functions;
 extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
 extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
-extern struct scsi_transport_template *qla2x00_alloc_transport_tmpl(void);
 extern void qla2x00_init_host_attr(scsi_qla_host_t *);
 extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
 extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
index 84db911318c61f095d32f85994521224784c32fa..3c97aa45772dc4aea2b7c4dbd759e76fa46c1745 100644 (file)
@@ -507,6 +507,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        int ret, i;
        unsigned int id, lun;
        unsigned long serial;
+       unsigned long flags;
 
        if (!CMD_SP(cmd))
                return FAILED;
@@ -519,7 +520,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 
        /* Check active list for command command. */
        spin_unlock_irq(ha->host->host_lock);
-       spin_lock(&ha->hardware_lock);
+       spin_lock_irqsave(&ha->hardware_lock, flags);
        for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
                sp = ha->outstanding_cmds[i];
 
@@ -534,7 +535,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
                    sp->state));
                DEBUG3(qla2x00_print_scsi_cmd(cmd);)
 
-               spin_unlock(&ha->hardware_lock);
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
                if (qla2x00_abort_command(ha, sp)) {
                        DEBUG2(printk("%s(%ld): abort_command "
                            "mbx failed.\n", __func__, ha->host_no));
@@ -543,20 +544,19 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
                            "mbx success.\n", __func__, ha->host_no));
                        ret = SUCCESS;
                }
-               spin_lock(&ha->hardware_lock);
+               spin_lock_irqsave(&ha->hardware_lock, flags);
 
                break;
        }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        /* Wait for the command to be returned. */
        if (ret == SUCCESS) {
-               spin_unlock(&ha->hardware_lock);
                if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) {
                        qla_printk(KERN_ERR, ha, 
                            "scsi(%ld:%d:%d): Abort handler timed out -- %lx "
                            "%x.\n", ha->host_no, id, lun, serial, ret);
                }
-               spin_lock(&ha->hardware_lock);
        }
        spin_lock_irq(ha->host->host_lock);
 
@@ -588,6 +588,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
        int     status;
        srb_t           *sp;
        struct scsi_cmnd *cmd;
+       unsigned long flags;
 
        status = 0;
 
@@ -596,11 +597,11 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
         * array
         */
        for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-               spin_lock(&ha->hardware_lock);
+               spin_lock_irqsave(&ha->hardware_lock, flags);
                sp = ha->outstanding_cmds[cnt];
                if (sp) {
                        cmd = sp->cmd;
-                       spin_unlock(&ha->hardware_lock);
+                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
                        if (cmd->device->id == t) {
                                if (!qla2x00_eh_wait_on_command(ha, cmd)) {
                                        status = 1;
@@ -608,7 +609,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
                                }
                        }
                } else {
-                       spin_unlock(&ha->hardware_lock);
+                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
                }
        }
        return (status);
@@ -740,6 +741,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
        int     status;
        srb_t           *sp;
        struct scsi_cmnd *cmd;
+       unsigned long flags;
 
        status = 1;
 
@@ -748,17 +750,17 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
         * array
         */
        for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-               spin_lock(&ha->hardware_lock);
+               spin_lock_irqsave(&ha->hardware_lock, flags);
                sp = ha->outstanding_cmds[cnt];
                if (sp) {
                        cmd = sp->cmd;
-                       spin_unlock(&ha->hardware_lock);
+                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
                        status = qla2x00_eh_wait_on_command(ha, cmd);
                        if (status == 0)
                                break;
                }
                else {
-                       spin_unlock(&ha->hardware_lock);
+                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
                }
        }
        return (status);
@@ -2350,7 +2352,8 @@ qla2x00_module_init(void)
 #if DEBUG_QLA2100
        strcat(qla2x00_version_str, "-debug");
 #endif
-       qla2xxx_transport_template = qla2x00_alloc_transport_tmpl();
+       qla2xxx_transport_template =
+           fc_attach_transport(&qla2xxx_transport_functions);
        if (!qla2xxx_transport_template)
                return -ENODEV;
 
index 69009f853a4917f54a88aa0c2cf3e6fb0428c8f7..b0403ccd8a25d97aec9e220d175844dd45448076 100644 (file)
@@ -329,6 +329,8 @@ static void nv_host_stop (struct ata_host_set *host_set)
                host->host_desc->disable_hotplug(host_set);
 
        kfree(host);
+
+       ata_host_stop(host_set);
 }
 
 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
index 19a13e3590f4eca5fab24675ffec12aaa56dd57f..b18c90582e67cf32216049f7aca031024779c966 100644 (file)
@@ -122,6 +122,7 @@ static struct ata_port_operations pdc_ata_ops = {
        .scr_write              = pdc_sata_scr_write,
        .port_start             = pdc_port_start,
        .port_stop              = pdc_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static struct ata_port_info pdc_port_info[] = {
@@ -151,6 +152,8 @@ static struct ata_port_info pdc_port_info[] = {
 static struct pci_device_id pdc_ata_pci_tbl[] = {
        { PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_2037x },
+       { PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+         board_2037x },
        { PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_2037x },
        { PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
index dfd3621047171dc748ba9a11c82a418f89faaed6..1383e8a28d728b34e936c0b9c7e04ffbf9a5818c 100644 (file)
@@ -536,6 +536,8 @@ static void qs_host_stop(struct ata_host_set *host_set)
 
        writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
        writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
+
+       ata_host_stop(host_set);
 }
 
 static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
index f0489dc302a03054d6461ba54c9705f30190a8f4..49ed557a4b661e4cfa9569b0d2af72f4375573d8 100644 (file)
@@ -82,6 +82,7 @@ static struct pci_device_id sil_pci_tbl[] = {
        { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
        { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
        { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+       { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
        { }     /* terminate list */
 };
 
@@ -160,6 +161,7 @@ static struct ata_port_operations sil_ops = {
        .scr_write              = sil_scr_write,
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static struct ata_port_info sil_port_info[] = {
@@ -430,7 +432,13 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                writeb(cls, mmio_base + SIL_FIFO_R0);
                writeb(cls, mmio_base + SIL_FIFO_W0);
                writeb(cls, mmio_base + SIL_FIFO_R1);
-               writeb(cls, mmio_base + SIL_FIFO_W2);
+               writeb(cls, mmio_base + SIL_FIFO_W1);
+               if (ent->driver_data == sil_3114) {
+                       writeb(cls, mmio_base + SIL_FIFO_R2);
+                       writeb(cls, mmio_base + SIL_FIFO_W2);
+                       writeb(cls, mmio_base + SIL_FIFO_R3);
+                       writeb(cls, mmio_base + SIL_FIFO_W3);
+               }
        } else
                printk(KERN_WARNING DRV_NAME "(%s): cache line size not set.  Driver may not function\n",
                        pci_name(pdev));
index 5105ddd08447807df3710492f70c31bf6f0d8767..e418b89c6b9d8cf67c57a1b03431b91a19b585f2 100644 (file)
@@ -114,6 +114,7 @@ static struct ata_port_operations sis_ops = {
        .scr_write              = sis_scr_write,
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static struct ata_port_info sis_port_info = {
index 8d1a5d25c05364e41e7f98198b94335ed30d0046..edef1fa969fcecba6907ae49b84bf81a5ecae7c3 100644 (file)
@@ -313,6 +313,7 @@ static struct ata_port_operations k2_sata_ops = {
        .scr_write              = k2_sata_scr_write,
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base)
@@ -395,7 +396,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
 
        /* Clear a magic bit in SCR1 according to Darwin, those help
         * some funky seagate drives (though so far, those were already
-        * set by the firmware on the machines I had access to
+        * set by the firmware on the machines I had access to)
         */
        writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000,
               mmio_base + K2_SATA_SICR1_OFFSET);
index 70118650c461e9d5d10ff0c3053ae5b49c6755a0..140cea05de3f23cdfa8d204af0d49b9f52f32913 100644 (file)
@@ -245,6 +245,8 @@ static void pdc20621_host_stop(struct ata_host_set *host_set)
 
        iounmap(dimm_mmio);
        kfree(hpriv);
+
+       ata_host_stop(host_set);
 }
 
 static int pdc_port_start(struct ata_port *ap)
index 0bff4f475f262c5c40254aecf85bd6a7137bd04e..a71fb54eebd301e07240310964a323b240db670d 100644 (file)
@@ -113,6 +113,7 @@ static struct ata_port_operations uli_ops = {
 
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static struct ata_port_info uli_port_info = {
index 3a7830667277f35f71a83db5705b8cb2d376bafc..f43183c19a12184ebd6902eadf154bc836a7e249 100644 (file)
@@ -134,6 +134,7 @@ static struct ata_port_operations svia_sata_ops = {
 
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static struct ata_port_info svia_port_info = {
index 2c28f0ad73c204420aa4b419a60341a8b801d7fa..c5e09dc6f3de67b3250250d7f064ff873d679bb6 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -230,6 +231,7 @@ static struct ata_port_operations vsc_sata_ops = {
        .scr_write              = vsc_sata_scr_write,
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base)
index 05d2bd075fd4e27a6f954e2b0662c400733790f9..184bcaeaf8127620cea60423ac35e7a50eaac5b6 100644 (file)
@@ -542,7 +542,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
                 * that the device is no longer present */
                cmd->result = DID_NO_CONNECT << 16;
                atomic_inc(&cmd->device->iorequest_cnt);
-               scsi_done(cmd);
+               __scsi_done(cmd);
                /* return 0 (because the command has been processed) */
                goto out;
        }
index cca772624ae701ea8278ce770c10c8617e710c5e..8d0d302844a1d5a5c3a9df8530e1be0974f5c4d6 100644 (file)
@@ -1197,6 +1197,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
        if (!starget)
                return ERR_PTR(-ENOMEM);
 
+       get_device(&starget->dev);
        down(&shost->scan_mutex);
        res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
        if (res != SCSI_SCAN_LUN_PRESENT)
index 303d7656f71021fa592ab0924212a03361f9a445..67c6cc40ce160893c0555302e4a39e1412f3b854 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/workqueue.h>
+#include <linux/blkdev.h>
 #include <asm/semaphore.h>
 #include <scsi/scsi.h>
 #include "scsi_priv.h"
 
 #define SPI_PRINTK(x, l, f, a...)      dev_printk(l, &(x)->dev, f , ##a)
 
-#define SPI_NUM_ATTRS 10       /* increase this if you add attributes */
+#define SPI_NUM_ATTRS 13       /* increase this if you add attributes */
 #define SPI_OTHER_ATTRS 1      /* Increase this if you add "always
                                 * on" attributes */
 #define SPI_HOST_ATTRS 1
 
 #define SPI_MAX_ECHO_BUFFER_SIZE       4096
 
+#define DV_LOOPS       3
+#define DV_TIMEOUT     (10*HZ)
+#define DV_RETRIES     3       /* should only need at most 
+                                * two cc/ua clears */
+
 /* Private data accessors (keep these out of the header file) */
 #define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)
 #define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem)
@@ -100,6 +106,29 @@ static int sprint_frac(char *dest, int value, int denom)
        return result;
 }
 
+/* Modification of scsi_wait_req that will clear UNIT ATTENTION conditions
+ * resulting from (likely) bus and device resets */
+static void spi_wait_req(struct scsi_request *sreq, const void *cmd,
+                        void *buffer, unsigned bufflen)
+{
+       int i;
+
+       for(i = 0; i < DV_RETRIES; i++) {
+               sreq->sr_request->flags |= REQ_FAILFAST;
+
+               scsi_wait_req(sreq, cmd, buffer, bufflen,
+                             DV_TIMEOUT, /* retries */ 1);
+               if (sreq->sr_result & DRIVER_SENSE) {
+                       struct scsi_sense_hdr sshdr;
+
+                       if (scsi_request_normalize_sense(sreq, &sshdr)
+                           && sshdr.sense_key == UNIT_ATTENTION)
+                               continue;
+               }
+               break;
+       }
+}
+
 static struct {
        enum spi_signal_type    value;
        char                    *name;
@@ -190,8 +219,11 @@ static int spi_setup_transport_attrs(struct device *dev)
        struct scsi_target *starget = to_scsi_target(dev);
 
        spi_period(starget) = -1;       /* illegal value */
+       spi_min_period(starget) = 0;
        spi_offset(starget) = 0;        /* async */
+       spi_max_offset(starget) = 255;
        spi_width(starget) = 0; /* narrow */
+       spi_max_width(starget) = 1;
        spi_iu(starget) = 0;    /* no IU */
        spi_dt(starget) = 0;    /* ST */
        spi_qas(starget) = 0;
@@ -206,6 +238,34 @@ static int spi_setup_transport_attrs(struct device *dev)
        return 0;
 }
 
+#define spi_transport_show_simple(field, format_string)                        \
+                                                                       \
+static ssize_t                                                         \
+show_spi_transport_##field(struct class_device *cdev, char *buf)       \
+{                                                                      \
+       struct scsi_target *starget = transport_class_to_starget(cdev); \
+       struct spi_transport_attrs *tp;                                 \
+                                                                       \
+       tp = (struct spi_transport_attrs *)&starget->starget_data;      \
+       return snprintf(buf, 20, format_string, tp->field);             \
+}
+
+#define spi_transport_store_simple(field, format_string)               \
+                                                                       \
+static ssize_t                                                         \
+store_spi_transport_##field(struct class_device *cdev, const char *buf, \
+                           size_t count)                               \
+{                                                                      \
+       int val;                                                        \
+       struct scsi_target *starget = transport_class_to_starget(cdev); \
+       struct spi_transport_attrs *tp;                                 \
+                                                                       \
+       tp = (struct spi_transport_attrs *)&starget->starget_data;      \
+       val = simple_strtoul(buf, NULL, 0);                             \
+       tp->field = val;                                                \
+       return count;                                                   \
+}
+
 #define spi_transport_show_function(field, format_string)              \
                                                                        \
 static ssize_t                                                         \
@@ -232,6 +292,25 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \
        struct spi_internal *i = to_spi_internal(shost->transportt);    \
                                                                        \
        val = simple_strtoul(buf, NULL, 0);                             \
+       i->f->set_##field(starget, val);                        \
+       return count;                                                   \
+}
+
+#define spi_transport_store_max(field, format_string)                  \
+static ssize_t                                                         \
+store_spi_transport_##field(struct class_device *cdev, const char *buf, \
+                           size_t count)                               \
+{                                                                      \
+       int val;                                                        \
+       struct scsi_target *starget = transport_class_to_starget(cdev); \
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);    \
+       struct spi_internal *i = to_spi_internal(shost->transportt);    \
+       struct spi_transport_attrs *tp                                  \
+               = (struct spi_transport_attrs *)&starget->starget_data; \
+                                                                       \
+       val = simple_strtoul(buf, NULL, 0);                             \
+       if (val > tp->max_##field)                                      \
+               val = tp->max_##field;                                  \
        i->f->set_##field(starget, val);                                \
        return count;                                                   \
 }
@@ -243,9 +322,24 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR,                 \
                         show_spi_transport_##field,                    \
                         store_spi_transport_##field);
 
+#define spi_transport_simple_attr(field, format_string)                        \
+       spi_transport_show_simple(field, format_string)                 \
+       spi_transport_store_simple(field, format_string)                \
+static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR,                     \
+                        show_spi_transport_##field,                    \
+                        store_spi_transport_##field);
+
+#define spi_transport_max_attr(field, format_string)                   \
+       spi_transport_show_function(field, format_string)               \
+       spi_transport_store_max(field, format_string)                   \
+       spi_transport_simple_attr(max_##field, format_string)           \
+static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR,                     \
+                        show_spi_transport_##field,                    \
+                        store_spi_transport_##field);
+
 /* The Parallel SCSI Tranport Attributes: */
-spi_transport_rd_attr(offset, "%d\n");
-spi_transport_rd_attr(width, "%d\n");
+spi_transport_max_attr(offset, "%d\n");
+spi_transport_max_attr(width, "%d\n");
 spi_transport_rd_attr(iu, "%d\n");
 spi_transport_rd_attr(dt, "%d\n");
 spi_transport_rd_attr(qas, "%d\n");
@@ -271,26 +365,18 @@ static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate);
 
 /* Translate the period into ns according to the current spec
  * for SDTR/PPR messages */
-static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf)
-
+static ssize_t
+show_spi_transport_period_helper(struct class_device *cdev, char *buf,
+                                int period)
 {
-       struct scsi_target *starget = transport_class_to_starget(cdev);
-       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-       struct spi_transport_attrs *tp;
        int len, picosec;
-       struct spi_internal *i = to_spi_internal(shost->transportt);
-
-       tp = (struct spi_transport_attrs *)&starget->starget_data;
 
-       if (i->f->get_period)
-               i->f->get_period(starget);
-
-       if (tp->period < 0 || tp->period > 0xff) {
+       if (period < 0 || period > 0xff) {
                picosec = -1;
-       } else if (tp->period <= SPI_STATIC_PPR) {
-               picosec = ppr_to_ps[tp->period];
+       } else if (period <= SPI_STATIC_PPR) {
+               picosec = ppr_to_ps[period];
        } else {
-               picosec = tp->period * 4000;
+               picosec = period * 4000;
        }
 
        if (picosec == -1) {
@@ -305,12 +391,9 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf)
 }
 
 static ssize_t
-store_spi_transport_period(struct class_device *cdev, const char *buf,
-                           size_t count)
+store_spi_transport_period_helper(struct class_device *cdev, const char *buf,
+                                 size_t count, int *periodp)
 {
-       struct scsi_target *starget = transport_class_to_starget(cdev);
-       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-       struct spi_internal *i = to_spi_internal(shost->transportt);
        int j, picosec, period = -1;
        char *endp;
 
@@ -339,15 +422,79 @@ store_spi_transport_period(struct class_device *cdev, const char *buf,
        if (period > 0xff)
                period = 0xff;
 
-       i->f->set_period(starget, period);
+       *periodp = period;
 
        return count;
 }
 
+static ssize_t
+show_spi_transport_period(struct class_device *cdev, char *buf)
+{
+       struct scsi_target *starget = transport_class_to_starget(cdev);
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct spi_internal *i = to_spi_internal(shost->transportt);
+       struct spi_transport_attrs *tp =
+               (struct spi_transport_attrs *)&starget->starget_data;
+
+       if (i->f->get_period)
+               i->f->get_period(starget);
+
+       return show_spi_transport_period_helper(cdev, buf, tp->period);
+}
+
+static ssize_t
+store_spi_transport_period(struct class_device *cdev, const char *buf,
+                           size_t count)
+{
+       struct scsi_target *starget = transport_class_to_starget(cdev);
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct spi_internal *i = to_spi_internal(shost->transportt);
+       struct spi_transport_attrs *tp =
+               (struct spi_transport_attrs *)&starget->starget_data;
+       int period, retval;
+
+       retval = store_spi_transport_period_helper(cdev, buf, count, &period);
+
+       if (period < tp->min_period)
+               period = tp->min_period;
+
+       i->f->set_period(starget, period);
+
+       return retval;
+}
+
 static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR, 
                         show_spi_transport_period,
                         store_spi_transport_period);
 
+static ssize_t
+show_spi_transport_min_period(struct class_device *cdev, char *buf)
+{
+       struct scsi_target *starget = transport_class_to_starget(cdev);
+       struct spi_transport_attrs *tp =
+               (struct spi_transport_attrs *)&starget->starget_data;
+
+       return show_spi_transport_period_helper(cdev, buf, tp->min_period);
+}
+
+static ssize_t
+store_spi_transport_min_period(struct class_device *cdev, const char *buf,
+                           size_t count)
+{
+       struct scsi_target *starget = transport_class_to_starget(cdev);
+       struct spi_transport_attrs *tp =
+               (struct spi_transport_attrs *)&starget->starget_data;
+
+       return store_spi_transport_period_helper(cdev, buf, count,
+                                                &tp->min_period);
+}
+
+
+static CLASS_DEVICE_ATTR(min_period, S_IRUGO | S_IWUSR, 
+                        show_spi_transport_min_period,
+                        store_spi_transport_min_period);
+
+
 static ssize_t show_spi_host_signalling(struct class_device *cdev, char *buf)
 {
        struct Scsi_Host *shost = transport_class_to_shost(cdev);
@@ -378,11 +525,6 @@ static CLASS_DEVICE_ATTR(signalling, S_IRUGO | S_IWUSR,
        if(i->f->set_##x)               \
                i->f->set_##x(sdev->sdev_target, y)
 
-#define DV_LOOPS       3
-#define DV_TIMEOUT     (10*HZ)
-#define DV_RETRIES     3       /* should only need at most 
-                                * two cc/ua clears */
-
 enum spi_compare_returns {
        SPI_COMPARE_SUCCESS,
        SPI_COMPARE_FAILURE,
@@ -446,8 +588,7 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer,
        for (r = 0; r < retries; r++) {
                sreq->sr_cmd_len = 0;   /* wait_req to fill in */
                sreq->sr_data_direction = DMA_TO_DEVICE;
-               scsi_wait_req(sreq, spi_write_buffer, buffer, len,
-                             DV_TIMEOUT, DV_RETRIES);
+               spi_wait_req(sreq, spi_write_buffer, buffer, len);
                if(sreq->sr_result || !scsi_device_online(sdev)) {
                        struct scsi_sense_hdr sshdr;
 
@@ -471,8 +612,7 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer,
                memset(ptr, 0, len);
                sreq->sr_cmd_len = 0;   /* wait_req to fill in */
                sreq->sr_data_direction = DMA_FROM_DEVICE;
-               scsi_wait_req(sreq, spi_read_buffer, ptr, len,
-                             DV_TIMEOUT, DV_RETRIES);
+               spi_wait_req(sreq, spi_read_buffer, ptr, len);
                scsi_device_set_state(sdev, SDEV_QUIESCE);
 
                if (memcmp(buffer, ptr, len) != 0)
@@ -500,8 +640,7 @@ spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer,
 
                memset(ptr, 0, len);
 
-               scsi_wait_req(sreq, spi_inquiry, ptr, len,
-                             DV_TIMEOUT, DV_RETRIES);
+               spi_wait_req(sreq, spi_inquiry, ptr, len);
                
                if(sreq->sr_result || !scsi_device_online(sdev)) {
                        scsi_device_set_state(sdev, SDEV_QUIESCE);
@@ -593,8 +732,7 @@ spi_dv_device_get_echo_buffer(struct scsi_request *sreq, u8 *buffer)
         * (reservation conflict, device not ready, etc) just
         * skip the write tests */
        for (l = 0; ; l++) {
-               scsi_wait_req(sreq, spi_test_unit_ready, NULL, 0,
-                             DV_TIMEOUT, DV_RETRIES);
+               spi_wait_req(sreq, spi_test_unit_ready, NULL, 0);
 
                if(sreq->sr_result) {
                        if(l >= 3)
@@ -608,8 +746,7 @@ spi_dv_device_get_echo_buffer(struct scsi_request *sreq, u8 *buffer)
        sreq->sr_cmd_len = 0;
        sreq->sr_data_direction = DMA_FROM_DEVICE;
 
-       scsi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4,
-                     DV_TIMEOUT, DV_RETRIES);
+       spi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4);
 
        if (sreq->sr_result)
                /* Device has no echo buffer */
@@ -623,6 +760,7 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
 {
        struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt);
        struct scsi_device *sdev = sreq->sr_device;
+       struct scsi_target *starget = sdev->sdev_target;
        int len = sdev->inquiry_len;
        /* first set us up for narrow async */
        DV_SET(offset, 0);
@@ -636,9 +774,11 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
        }
 
        /* test width */
-       if (i->f->set_width && sdev->wdtr) {
+       if (i->f->set_width && spi_max_width(starget) && sdev->wdtr) {
                i->f->set_width(sdev->sdev_target, 1);
 
+               printk("WIDTH IS %d\n", spi_max_width(starget));
+
                if (spi_dv_device_compare_inquiry(sreq, buffer,
                                                   buffer + len,
                                                   DV_LOOPS)
@@ -665,8 +805,8 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
  retry:
 
        /* now set up to the maximum */
-       DV_SET(offset, 255);
-       DV_SET(period, 1);
+       DV_SET(offset, spi_max_offset(starget));
+       DV_SET(period, spi_min_period(starget));
 
        if (len == 0) {
                SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n");
@@ -873,6 +1013,16 @@ EXPORT_SYMBOL(spi_display_xfer_agreement);
        if (i->f->show_##field)                                         \
                count++
 
+#define SETUP_RELATED_ATTRIBUTE(field, rel_field)                      \
+       i->private_attrs[count] = class_device_attr_##field;            \
+       if (!i->f->set_##rel_field) {                                   \
+               i->private_attrs[count].attr.mode = S_IRUGO;            \
+               i->private_attrs[count].store = NULL;                   \
+       }                                                               \
+       i->attrs[count] = &i->private_attrs[count];                     \
+       if (i->f->show_##rel_field)                                     \
+               count++
+
 #define SETUP_HOST_ATTRIBUTE(field)                                    \
        i->private_host_attrs[count] = class_device_attr_##field;       \
        if (!i->f->set_##field) {                                       \
@@ -956,8 +1106,11 @@ spi_attach_transport(struct spi_function_template *ft)
        i->f = ft;
 
        SETUP_ATTRIBUTE(period);
+       SETUP_RELATED_ATTRIBUTE(min_period, period);
        SETUP_ATTRIBUTE(offset);
+       SETUP_RELATED_ATTRIBUTE(max_offset, offset);
        SETUP_ATTRIBUTE(width);
+       SETUP_RELATED_ATTRIBUTE(max_width, width);
        SETUP_ATTRIBUTE(iu);
        SETUP_ATTRIBUTE(dt);
        SETUP_ATTRIBUTE(qas);
index 3471be05779a5220e40eb3e67d32ad3ee7b6bd8e..82d68fdb15484520abd80d1aa603d2395a86ad6b 100644 (file)
@@ -281,6 +281,9 @@ int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
        char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
        int result;
 
+       if (!buffer)
+               return -ENOMEM;
+
        memset(&cgc, 0, sizeof(struct packet_command));
        cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
        cgc.cmd[2] = 0x40;      /* I do want the subchannel info */
index f26c3a29e631e88184af3cca14254f0e6128cba0..ebfddd40ce67322840d8e115bbe773617126de2a 100644 (file)
@@ -809,7 +809,7 @@ static int sym53c416_host_reset(Scsi_Cmnd *SCpnt)
        /* printk("sym53c416_reset\n"); */
        base = SCpnt->device->host->io_port;
        /* search scsi_id - fixme, we shouldnt need to iterate for this! */
-       for(i = 0; i < host_index && scsi_id != -1; i++)
+       for(i = 0; i < host_index && scsi_id == -1; i++)
                if(hosts[i].base == base)
                        scsi_id = hosts[i].scsi_id;
        outb(RESET_CHIP, base + COMMAND_REG);
index 5ff83d214f128eed2ca780cf50fbc8f12a6fa07e..5b07c6ec3eccbc2845216d1fa1c1dce63039739d 100644 (file)
@@ -2038,8 +2038,9 @@ static void sym2_set_period(struct scsi_target *starget, int period)
        struct sym_hcb *np = sym_get_hcb(shost);
        struct sym_tcb *tp = &np->target[starget->id];
 
-       /* have to have DT for these transfers */
-       if (period <= np->minsync)
+       /* have to have DT for these transfers, but DT will also
+        * set width, so check that this is allowed */
+       if (period <= np->minsync && spi_width(starget))
                tp->tgoal.dt = 1;
 
        tp->tgoal.period = period;
index 33fbda79f3507f83f00ca3b9c8f9167f6500c136..0b10169961ebfe2898efecb192a00c5a47c4b1df 100644 (file)
@@ -126,18 +126,8 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *r
                                flag = TTY_FRAME;
                }
 
-               if ((rxs & port->ignore_status_mask) == 0) {
-                       tty_insert_flip_char(tty, ch, flag);
-               }
-               if ((rxs & RXSTAT_OVERRUN) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       /*
-                        * Overrun is special, since it's reported
-                        * immediately, and doesn't affect the current
-                        * character.
-                        */
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               }
+               uart_insert_char(port, rxs, RXSTAT_OVERRUN, ch, flag);
+
                status = *CSR_UARTFLG;
        }
        tty_flip_buffer_push(tty);
index 0d9358608fdfdc8c6d53824dfc9f11a4d1fe38f9..30e8beb71430cb5e6949bae02efa5315259750cb 100644 (file)
@@ -682,8 +682,6 @@ static void autoconfig_16550a(struct uart_8250_port *up)
         * from EXCR1. Switch back to bank 0, change it in MCR. Then
         * switch back to bank 2, read it from EXCR1 again and check
         * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
-        * On PowerPC we don't want to change baud_base, as we have
-        * a number of different divisors.  -- Tom Rini
         */
        serial_outp(up, UART_LCR, 0);
        status1 = serial_in(up, UART_MCR);
@@ -699,16 +697,25 @@ static void autoconfig_16550a(struct uart_8250_port *up)
                serial_outp(up, UART_MCR, status1);
 
                if ((status2 ^ status1) & UART_MCR_LOOP) {
-#ifndef CONFIG_PPC
+                       unsigned short quot;
+
                        serial_outp(up, UART_LCR, 0xE0);
+
+                       quot = serial_inp(up, UART_DLM) << 8;
+                       quot += serial_inp(up, UART_DLL);
+                       quot <<= 3;
+
                        status1 = serial_in(up, 0x04); /* EXCR1 */
                        status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
                        status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
                        serial_outp(up, 0x04, status1);
+                       
+                       serial_outp(up, UART_DLL, quot & 0xff);
+                       serial_outp(up, UART_DLM, quot >> 8);
+
                        serial_outp(up, UART_LCR, 0);
-                       up->port.uartclk = 921600*16;
-#endif
 
+                       up->port.uartclk = 921600*16;
                        up->port.type = PORT_NS16550A;
                        up->capabilities |= UART_NATSEMI;
                        return;
@@ -1122,18 +1129,9 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
                }
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        goto ignore_char;
-               if ((lsr & up->port.ignore_status_mask) == 0) {
-                       tty_insert_flip_char(tty, ch, flag);
-               }
-               if ((lsr & UART_LSR_OE) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       /*
-                        * Overrun is special, since it's reported
-                        * immediately, and doesn't affect the current
-                        * character.
-                        */
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               }
+
+               uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
+
        ignore_char:
                lsr = serial_inp(up, UART_LSR);
        } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
index f8d90d0ecfeac2e1a38690cc253b988714d667ef..de54bdc5398b96b6c44b01c881c91a5a1010a296 100644 (file)
@@ -1009,6 +1009,8 @@ get_pci_irq(struct pci_dev *dev, struct pci_board *board, int idx)
  *  n    = number of serial ports
  *  baud = baud rate
  *
+ * This table is sorted by (in order): baud, bt, bn, n.
+ *
  * Please note: in theory if n = 1, _bt infix should make no difference.
  * ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200
  */
index f2a5e2933c4709b2b56fc4167e041b0e366e5782..2884b310e54d2d01f50d012d4394343b08b5717a 100644 (file)
@@ -198,18 +198,8 @@ pl010_rx_chars(struct uart_port *port)
                if (uart_handle_sysrq_char(port, ch, regs))
                        goto ignore_char;
 
-               if ((rsr & port->ignore_status_mask) == 0) {
-                       tty_insert_flip_char(tty, ch, flag);
-               }
-               if ((rsr & UART01x_RSR_OE) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       /*
-                        * Overrun is special, since it's reported
-                        * immediately, and doesn't affect the current
-                        * character
-                        */
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               }
+               uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);
+
        ignore_char:
                status = UART_GET_FR(port);
        }
index d5cbef3fe8b6adb42cf900aaffbec87494c8fdf8..7db88ee18f75fb1f138f71921c05d833aa935a51 100644 (file)
@@ -163,18 +163,8 @@ pl011_rx_chars(struct uart_amba_port *uap)
                if (uart_handle_sysrq_char(&uap->port, ch, regs))
                        goto ignore_char;
 
-               if ((rsr & uap->port.ignore_status_mask) == 0) {
-                       tty_insert_flip_char(tty, ch, flag);
-               }
-               if ((rsr & UART01x_RSR_OE) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       /*
-                        * Overrun is special, since it's reported
-                        * immediately, and doesn't affect the current
-                        * character
-                        */
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               }
+               uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag);
+
        ignore_char:
                status = readw(uap->port.membase + UART01x_FR);
        }
index 6242f3090a96f76372ad8e35367bbbc790e68cf0..e92522b33c48e9e4e283b8fbd498d4e8b7e45c12 100644 (file)
@@ -143,10 +143,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re
                 * CHECK: does overrun affect the current character?
                 * ASSUMPTION: it does not.
                 */
-               if ((ch & port->ignore_status_mask & ~RXSTAT_OVERRUN) == 0)
-                       tty_insert_flip_char(tty, ch, flg);
-               if ((ch & ~port->ignore_status_mask & RXSTAT_OVERRUN) == 0)
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+               uart_insert_char(port, ch, UARTDR_OVERR, ch, flg);
 
        ignore_char:
                status = clps_readl(SYSFLG(port));
index 51d8a49f4477bb6f23048b361e4ad367ecdb9758..9dc151d8fa612bb16554f6d4d15382a5d4eaf7ab 100644 (file)
@@ -161,20 +161,12 @@ receive_chars(struct uart_pxa_port *up, int *status, struct pt_regs *regs)
                        else if (*status & UART_LSR_FE)
                                flag = TTY_FRAME;
                }
+
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        goto ignore_char;
-               if ((*status & up->port.ignore_status_mask) == 0) {
-                       tty_insert_flip_char(tty, ch, flag);
-               }
-               if ((*status & UART_LSR_OE) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       /*
-                        * Overrun is special, since it's reported
-                        * immediately, and doesn't affect the current
-                        * character.
-                        */
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               }
+
+               uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag);
+
        ignore_char:
                *status = serial_in(up, UART_LSR);
        } while ((*status & UART_LSR_DR) && (max_count-- > 0));
index 435750d40a471001c860ba0b21b0443901534eab..2a9f7ade2c9d58faa134e84d698d9025af5365b1 100644 (file)
@@ -394,20 +394,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
                if (uart_handle_sysrq_char(port, ch, regs))
                        goto ignore_char;
 
-               if ((uerstat & port->ignore_status_mask) == 0) {
-                       tty_insert_flip_char(tty, ch, flag);
-               }
-
-               if ((uerstat & S3C2410_UERSTAT_OVERRUN) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       /*
-                        * Overrun is special, since it's reported
-                        * immediately, and doesn't affect the current
-                        * character.
-                        */
-
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               }
+               uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag);
 
        ignore_char:
                continue;
index 157218bc6c6fba4ddbce2e2294d381903a620eb5..98641c3f5ab9dedb9de0dd1be2eb1806469fb692 100644 (file)
@@ -197,7 +197,7 @@ static void
 sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
 {
        struct tty_struct *tty = sport->port.info->tty;
-       unsigned int status, ch, flg, ignored = 0;
+       unsigned int status, ch, flg;
 
        status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
                 UTSR0_TO_SM(UART_GET_UTSR0(sport));
@@ -237,10 +237,7 @@ sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
                if (uart_handle_sysrq_char(&sport->port, ch, regs))
                        goto ignore_char;
 
-               if ((status & port->ignore_status_mask & ~UTSR1_TO_SM(UTSR1_ROR)) == 0)
-                       tty_insert_flip_char(tty, ch, flg);
-               if (status & ~port->ignore_status_mask & UTSR1_TO_SM(UTSR1_ROR))
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+               uart_insert_char(&sport->port, status, UTSR1_TO_SM(UTSR1_ROR), ch, flg);
 
        ignore_char:
                status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
index 6eeb48f6a482a739bd1b24071fc4a01637529db3..0d7b65f93e8de505602dbf26d0dd8734f84e3d23 100644 (file)
@@ -661,10 +661,10 @@ void serial_config(dev_link_t * link)
        /* Is this a multiport card? */
        tuple->DesiredTuple = CISTPL_MANFID;
        if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
-               info->manfid = le16_to_cpu(buf[0]);
+               info->manfid = parse->manfid.manf;
                for (i = 0; i < MULTI_COUNT; i++)
                        if ((info->manfid == multi_id[i].manfid) &&
-                           (le16_to_cpu(buf[1]) == multi_id[i].prodid))
+                           (parse->manfid.card == multi_id[i].prodid))
                                break;
                if (i < MULTI_COUNT)
                        info->multi = multi_id[i].multi;
index 85cfa08d3bad7955bb79279f73be920e332fb03f..56f269b6bfb12c53fb323c66dcab126010888bee 100644 (file)
@@ -190,18 +190,7 @@ lh7a40xuart_rx_chars (struct uart_port* port)
                if (uart_handle_sysrq_char (port, (unsigned char) data, regs))
                        continue;
 
-               if ((data & port->ignore_status_mask) == 0) {
-                       tty_insert_flip_char(tty, data, flag);
-               }
-               if ((data & RxOverrunError)
-                   && tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       /*
-                        * Overrun is special, since it's reported
-                        * immediately, and doesn't affect the current
-                        * character
-                        */
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               }
+               uart_insert_char(port, data, RxOverrunError, data, flag);
        }
        tty_flip_buffer_push (tty);
        return;
index 37b2ef297cbec3816b06d2a30ad588a80abbfdd1..3f1051a4a13f8f51cab2efa2783f287e734c8ecb 100644 (file)
@@ -350,18 +350,9 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
                }
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        goto ignore_char;
-               if ((disr & up->port.ignore_status_mask) == 0) {
-                       tty_insert_flip_char(tty, ch, flag);
-               }
-               if ((disr & TXX9_SIDISR_UOER) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       /*
-                        * Overrun is special, since it's reported
-                        * immediately, and doesn't affect the current
-                        * character.
-                        */
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               }
+
+               uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag);
+
        ignore_char:
                disr = sio_in(up, TXX9_SIDISR);
        } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
index 39b788d95e39d9eb8f11578552f03933ad0b4e52..10e2990a40d42a2453780c5e045642c28866411e 100644 (file)
@@ -61,6 +61,16 @@ struct uart_sunsab_port {
        unsigned char                   pvr_dtr_bit;    /* Which PVR bit is DTR */
        unsigned char                   pvr_dsr_bit;    /* Which PVR bit is DSR */
        int                             type;           /* SAB82532 version     */
+
+       /* Setting configuration bits while the transmitter is active
+        * can cause garbage characters to get emitted by the chip.
+        * Therefore, we cache such writes here and do the real register
+        * write the next time the transmitter becomes idle.
+        */
+       unsigned int                    cached_ebrg;
+       unsigned char                   cached_mode;
+       unsigned char                   cached_pvr;
+       unsigned char                   cached_dafo;
 };
 
 /*
@@ -236,6 +246,7 @@ receive_chars(struct uart_sunsab_port *up,
 }
 
 static void sunsab_stop_tx(struct uart_port *, unsigned int);
+static void sunsab_tx_idle(struct uart_sunsab_port *);
 
 static void transmit_chars(struct uart_sunsab_port *up,
                           union sab82532_irq_status *stat)
@@ -258,6 +269,7 @@ static void transmit_chars(struct uart_sunsab_port *up,
                return;
 
        set_bit(SAB82532_XPR, &up->irqflags);
+       sunsab_tx_idle(up);
 
        if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
                up->interrupt_mask1 |= SAB82532_IMR1_XPR;
@@ -397,21 +409,21 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl)
        struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
 
        if (mctrl & TIOCM_RTS) {
-               writeb(readb(&up->regs->rw.mode) & ~SAB82532_MODE_FRTS,
-                      &up->regs->rw.mode);
-               writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS,
-                      &up->regs->rw.mode);
+               up->cached_mode &= ~SAB82532_MODE_FRTS;
+               up->cached_mode |= SAB82532_MODE_RTS;
        } else {
-               writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS,
-                      &up->regs->rw.mode);
-               writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS,
-                      &up->regs->rw.mode);
+               up->cached_mode |= (SAB82532_MODE_FRTS |
+                                   SAB82532_MODE_RTS);
        }
        if (mctrl & TIOCM_DTR) {
-               writeb(readb(&up->regs->rw.pvr) & ~(up->pvr_dtr_bit), &up->regs->rw.pvr);
+               up->cached_pvr &= ~(up->pvr_dtr_bit);
        } else {
-               writeb(readb(&up->regs->rw.pvr) | up->pvr_dtr_bit, &up->regs->rw.pvr);
+               up->cached_pvr |= up->pvr_dtr_bit;
        }
+
+       set_bit(SAB82532_REGS_PENDING, &up->irqflags);
+       if (test_bit(SAB82532_XPR, &up->irqflags))
+               sunsab_tx_idle(up);
 }
 
 /* port->lock is not held.  */
@@ -449,6 +461,25 @@ static void sunsab_stop_tx(struct uart_port *port, unsigned int tty_stop)
        writeb(up->interrupt_mask1, &up->regs->w.imr1);
 }
 
+/* port->lock held by caller.  */
+static void sunsab_tx_idle(struct uart_sunsab_port *up)
+{
+       if (test_bit(SAB82532_REGS_PENDING, &up->irqflags)) {
+               u8 tmp;
+
+               clear_bit(SAB82532_REGS_PENDING, &up->irqflags);
+               writeb(up->cached_mode, &up->regs->rw.mode);
+               writeb(up->cached_pvr, &up->regs->rw.pvr);
+               writeb(up->cached_dafo, &up->regs->w.dafo);
+
+               writeb(up->cached_ebrg & 0xff, &up->regs->w.bgr);
+               tmp = readb(&up->regs->rw.ccr2);
+               tmp &= ~0xc0;
+               tmp |= (up->cached_ebrg >> 2) & 0xc0;
+               writeb(tmp, &up->regs->rw.ccr2);
+       }
+}
+
 /* port->lock held by caller.  */
 static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start)
 {
@@ -517,12 +548,16 @@ static void sunsab_break_ctl(struct uart_port *port, int break_state)
 
        spin_lock_irqsave(&up->port.lock, flags);
 
-       val = readb(&up->regs->rw.dafo);
+       val = up->cached_dafo;
        if (break_state)
                val |= SAB82532_DAFO_XBRK;
        else
                val &= ~SAB82532_DAFO_XBRK;
-       writeb(val, &up->regs->rw.dafo);
+       up->cached_dafo = val;
+
+       set_bit(SAB82532_REGS_PENDING, &up->irqflags);
+       if (test_bit(SAB82532_XPR, &up->irqflags))
+               sunsab_tx_idle(up);
 
        spin_unlock_irqrestore(&up->port.lock, flags);
 }
@@ -566,8 +601,9 @@ static int sunsab_startup(struct uart_port *port)
               SAB82532_CCR2_TOE, &up->regs->w.ccr2);
        writeb(0, &up->regs->w.ccr3);
        writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &up->regs->w.ccr4);
-       writeb(SAB82532_MODE_RTS | SAB82532_MODE_FCTS |
-              SAB82532_MODE_RAC, &up->regs->w.mode);
+       up->cached_mode = (SAB82532_MODE_RTS | SAB82532_MODE_FCTS |
+                          SAB82532_MODE_RAC);
+       writeb(up->cached_mode, &up->regs->w.mode);
        writeb(SAB82532_RFC_DPS|SAB82532_RFC_RFTH_32, &up->regs->w.rfc);
        
        tmp = readb(&up->regs->rw.ccr0);
@@ -598,7 +634,6 @@ static void sunsab_shutdown(struct uart_port *port)
 {
        struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
        unsigned long flags;
-       unsigned char tmp;
 
        spin_lock_irqsave(&up->port.lock, flags);
 
@@ -609,14 +644,13 @@ static void sunsab_shutdown(struct uart_port *port)
        writeb(up->interrupt_mask1, &up->regs->w.imr1);
 
        /* Disable break condition */
-       tmp = readb(&up->regs->rw.dafo);
-       tmp &= ~SAB82532_DAFO_XBRK;
-       writeb(tmp, &up->regs->rw.dafo);
+       up->cached_dafo = readb(&up->regs->rw.dafo);
+       up->cached_dafo &= ~SAB82532_DAFO_XBRK;
+       writeb(up->cached_dafo, &up->regs->rw.dafo);
 
        /* Disable Receiver */  
-       tmp = readb(&up->regs->rw.mode);
-       tmp &= ~SAB82532_MODE_RAC;
-       writeb(tmp, &up->regs->rw.mode);
+       up->cached_mode &= ~SAB82532_MODE_RAC;
+       writeb(up->cached_mode, &up->regs->rw.mode);
 
        /*
         * XXX FIXME
@@ -685,7 +719,6 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
                                  unsigned int iflag, unsigned int baud,
                                  unsigned int quot)
 {
-       unsigned int ebrg;
        unsigned char dafo;
        int bits, n, m;
 
@@ -714,10 +747,11 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
        } else {
                dafo |= SAB82532_DAFO_PAR_EVEN;
        }
+       up->cached_dafo = dafo;
 
        calc_ebrg(baud, &n, &m);
 
-       ebrg = n | (m << 6);
+       up->cached_ebrg = n | (m << 6);
 
        up->tec_timeout = (10 * 1000000) / baud;
        up->cec_timeout = up->tec_timeout >> 2;
@@ -770,16 +804,13 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
        uart_update_timeout(&up->port, cflag,
                            (up->port.uartclk / (16 * quot)));
 
-       /* Now bang the new settings into the chip.  */
-       sunsab_cec_wait(up);
-       sunsab_tec_wait(up);
-       writeb(dafo, &up->regs->w.dafo);
-       writeb(ebrg & 0xff, &up->regs->w.bgr);
-       writeb((readb(&up->regs->rw.ccr2) & ~0xc0) | ((ebrg >> 2) & 0xc0),
-              &up->regs->rw.ccr2);
-
-       writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RAC, &up->regs->rw.mode);
-
+       /* Now schedule a register update when the chip's
+        * transmitter is idle.
+        */
+       up->cached_mode |= SAB82532_MODE_RAC;
+       set_bit(SAB82532_REGS_PENDING, &up->irqflags);
+       if (test_bit(SAB82532_XPR, &up->irqflags))
+               sunsab_tx_idle(up);
 }
 
 /* port->lock is not held.  */
@@ -1084,11 +1115,13 @@ static void __init sunsab_init_hw(void)
                        up->pvr_dsr_bit = (1 << 3);
                        up->pvr_dtr_bit = (1 << 2);
                }
-               writeb((1 << 1) | (1 << 2) | (1 << 4), &up->regs->w.pvr);
-               writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS,
-                      &up->regs->rw.mode);
-               writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS,
-                      &up->regs->rw.mode);
+               up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4);
+               writeb(up->cached_pvr, &up->regs->w.pvr);
+               up->cached_mode = readb(&up->regs->rw.mode);
+               up->cached_mode |= SAB82532_MODE_FRTS;
+               writeb(up->cached_mode, &up->regs->rw.mode);
+               up->cached_mode |= SAB82532_MODE_RTS;
+               writeb(up->cached_mode, &up->regs->rw.mode);
 
                up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT;
                up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT;
index 686086fcbbf5e7acd5cc8151b3f60985f8c6a9c1..b78e1f7b8050c01e25489c8533cacd00d5caac09 100644 (file)
@@ -126,6 +126,7 @@ union sab82532_irq_status {
 /* irqflags bits */
 #define SAB82532_ALLS                  0x00000001
 #define SAB82532_XPR                   0x00000002
+#define SAB82532_REGS_PENDING          0x00000004
 
 /* RFIFO Status Byte */
 #define SAB82532_RSTAT_PE              0x80
index 307886199f2f6f1301d6aa240b1f3263e9ec8a90..1f985327b0d485ec8b4648073ef39a80d25d28f1 100644 (file)
@@ -234,7 +234,7 @@ static inline const char *siu_type_name(struct uart_port *port)
                return "DSIU";
        }
 
-       return "unknown";
+       return NULL;
 }
 
 static unsigned int siu_tx_empty(struct uart_port *port)
@@ -412,10 +412,8 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status,
 
                if (uart_handle_sysrq_char(port, ch, regs))
                        goto ignore_char;
-               if ((lsr & port->ignore_status_mask) == 0)
-                       tty_insert_flip_char(tty, ch, flag);
-               if ((lsr & UART_LSR_OE) && (tty->flip.count < TTY_FLIPBUF_SIZE))
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+
+               uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
 
        ignore_char:
                lsr = siu_read(port, UART_LSR);
@@ -484,9 +482,6 @@ static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        struct uart_port *port;
        uint8_t iir, lsr;
 
-       if (dev_id == NULL)
-               return IRQ_NONE;
-
        port = (struct uart_port *)dev_id;
 
        iir = siu_read(port, UART_IIR);
@@ -509,6 +504,9 @@ static int siu_startup(struct uart_port *port)
 {
        int retval;
 
+       if (port->membase == NULL)
+               return -ENODEV;
+
        siu_clear_fifo(port);
 
        (void)siu_read(port, UART_LSR);
@@ -547,9 +545,6 @@ static void siu_shutdown(struct uart_port *port)
        unsigned long flags;
        uint8_t lcr;
 
-       if (port->membase == NULL)
-               return;
-
        siu_write(port, UART_IER, 0);
 
        spin_lock_irqsave(&port->lock, flags);
@@ -804,53 +799,6 @@ static int siu_init_ports(void)
 
 #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
 
-static void early_set_termios(struct uart_port *port, struct termios *new,
-                              struct termios *old)
-{
-       tcflag_t c_cflag;
-       uint8_t lcr;
-       unsigned int baud, quot;
-
-       c_cflag = new->c_cflag;
-       switch (c_cflag & CSIZE) {
-       case CS5:
-               lcr = UART_LCR_WLEN5;
-               break;
-       case CS6:
-               lcr = UART_LCR_WLEN6;
-               break;
-       case CS7:
-               lcr = UART_LCR_WLEN7;
-               break;
-       default:
-               lcr = UART_LCR_WLEN8;
-               break;
-       }
-
-       if (c_cflag & CSTOPB)
-               lcr |= UART_LCR_STOP;
-       if (c_cflag & PARENB)
-               lcr |= UART_LCR_PARITY;
-       if ((c_cflag & PARODD) != PARODD)
-               lcr |= UART_LCR_EPAR;
-       if (c_cflag & CMSPAR)
-               lcr |= UART_LCR_SPAR;
-
-       baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
-       quot = uart_get_divisor(port, baud);
-
-       siu_write(port, UART_LCR, lcr | UART_LCR_DLAB);
-
-       siu_write(port, UART_DLL, (uint8_t)quot);
-       siu_write(port, UART_DLM, (uint8_t)(quot >> 8));
-
-       siu_write(port, UART_LCR, lcr);
-}
-
-static struct uart_ops early_uart_ops = {
-       .set_termios    = early_set_termios,
-};
-
 #define BOTH_EMPTY     (UART_LSR_TEMT | UART_LSR_THRE)
 
 static void wait_for_xmitr(struct uart_port *port)
@@ -917,7 +865,7 @@ static int siu_console_setup(struct console *con, char *options)
        if (port->membase == NULL) {
                if (port->mapbase == 0)
                        return -ENODEV;
-               port->membase = (unsigned char __iomem *)KSEG1ADDR(port->mapbase);
+               port->membase = ioremap(port->mapbase, siu_port_size(port));
        }
 
        vr41xx_select_siu_interface(SIU_INTERFACE_RS232C);
@@ -951,7 +899,7 @@ static int __devinit siu_console_init(void)
 
        for (i = 0; i < num; i++) {
                port = &siu_uart_ports[i];
-               port->ops = &early_uart_ops;
+               port->ops = &siu_uart_ops;
        }
 
        register_console(&siu_console);
@@ -996,8 +944,10 @@ static int siu_probe(struct device *dev)
                port->dev = dev;
 
                retval = uart_add_one_port(&siu_uart_driver, port);
-               if (retval)
+               if (retval < 0) {
+                       port->dev = NULL;
                        break;
+               }
        }
 
        if (i == 0 && retval < 0) {
index 5538756f13ba8d194e2f35f2889aa7b1ab3c5d26..d5863b8b56eeaf00745a03f3d3a76c11c12a512f 100644 (file)
@@ -41,9 +41,6 @@
  *
  ***************************************************************************/
 
-static char ixj_c_rcsid[] = "$Id: ixj.c,v 4.7 2001/08/13 06:19:33 craigs Exp $";
-static char ixj_c_revision[] = "$Revision: 4.7 $";
-
 /*
  * $Log: ixj.c,v $
  *
@@ -6172,8 +6169,14 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
                retval = j->serial;
                break;
        case IXJCTL_VERSION:
-               if (copy_to_user(argp, ixj_c_revision, strlen(ixj_c_revision))) 
-                       retval = -EFAULT;
+               {
+                       char arg_str[100];
+                       snprintf(arg_str, sizeof(arg_str),
+                               "\nDriver version %i.%i.%i", IXJ_VER_MAJOR,
+                               IXJ_VER_MINOR, IXJ_BLD_VER);
+                       if (copy_to_user(argp, arg_str, strlen(arg_str)))
+                               retval = -EFAULT;
+               }
                break;
        case PHONE_RING_CADENCE:
                j->ring_cadence = arg;
@@ -7168,9 +7171,6 @@ static int ixj_get_status_proc(char *buf)
        int cnt;
        IXJ *j;
        len = 0;
-       len += sprintf(buf + len, "%s", ixj_c_rcsid);
-       len += sprintf(buf + len, "\n%s", ixj_h_rcsid);
-       len += sprintf(buf + len, "\n%s", ixjuser_h_rcsid);
        len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER);
        len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ));
        len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS));
@@ -7790,7 +7790,7 @@ static int __init ixj_init(void)
        if ((probe = ixj_probe_pci(&cnt)) < 0) {
                return probe;
        }
-       printk("%s\n", ixj_c_rcsid);
+       printk(KERN_INFO "ixj driver initialized.\n");
        create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
        return probe;
 }
index 143818a5612116102ca271fe615466ae63a37409..51e3f7f6597b2dfba83ecc26bb23dbe95408e43c 100644 (file)
@@ -38,8 +38,6 @@
  * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  *****************************************************************************/
-static char ixj_h_rcsid[] = "$Id: ixj.h,v 4.1 2001/08/04 14:49:27 craigs Exp $";
-
 #define IXJ_VERSION 3031
 
 #include <linux/version.h>
index 233f9229badb66c23131de8b8c6b36ef8d24d7b0..2a1697bfd69579c11543931813f10b1dd1ddde0e 100644 (file)
@@ -386,6 +386,8 @@ static void speedtch_poll_status(struct speedtch_instance_data *instance)
                if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
                        instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
                        printk(KERN_NOTICE "ADSL line is down\n");
+                       /* It'll never resync again unless we ask it to... */
+                       speedtch_start_synchro(instance);
                }
                break;
 
index e12c5be1e0a345f12f430b17c17669ba32ba57f6..f50aaf25c98e309f08148f60d9045eb05bc9ba54 100644 (file)
@@ -431,7 +431,7 @@ nomem:
  * (2) error, where io->status is a negative errno value.  The number
  *     of io->bytes transferred before the error is usually less
  *     than requested, and can be nonzero.
- * (3) cancelation, a type of error with status -ECONNRESET that
+ * (3) cancellation, a type of error with status -ECONNRESET that
  *     is initiated by usb_sg_cancel().
  *
  * When this function returns, all memory allocated through usb_sg_init() or
@@ -1282,7 +1282,7 @@ static void release_interface(struct device *dev)
  * bus rwsem; usb device driver probe() methods cannot use this routine.
  *
  * Returns zero on success, or else the status code returned by the
- * underlying call that failed.  On succesful completion, each interface
+ * underlying call that failed.  On successful completion, each interface
  * in the original device configuration has been destroyed, and each one
  * in the new configuration has been probed by all relevant usb device
  * drivers currently known to the kernel.
index ec9b3bde8ae595e7e61f4e60823505d40c6a0a6a..4d0c9e65cd039e87612dedec707b4d0f4baf0675 100644 (file)
@@ -286,6 +286,37 @@ static ssize_t show_interface_string(struct device *dev, char *buf)
 }
 static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL);
 
+static ssize_t show_modalias(struct device *dev, char *buf)
+{
+       struct usb_interface *intf;
+       struct usb_device *udev;
+       int len;
+
+       intf = to_usb_interface(dev);
+       udev = interface_to_usbdev(intf);
+
+       len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic",
+                              le16_to_cpu(udev->descriptor.idVendor),
+                              le16_to_cpu(udev->descriptor.idProduct),
+                              le16_to_cpu(udev->descriptor.bcdDevice),
+                              udev->descriptor.bDeviceClass,
+                              udev->descriptor.bDeviceSubClass,
+                              udev->descriptor.bDeviceProtocol);
+       buf += len;
+
+       if (udev->descriptor.bDeviceClass == 0) {
+               struct usb_host_interface *alt = intf->cur_altsetting;
+
+               return len + sprintf(buf, "%02Xisc%02Xip%02X\n",
+                              alt->desc.bInterfaceClass,
+                              alt->desc.bInterfaceSubClass,
+                              alt->desc.bInterfaceProtocol);
+       } else {
+               return len + sprintf(buf, "*isc*ip*\n");
+       }
+}
+static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
+
 static struct attribute *intf_attrs[] = {
        &dev_attr_bInterfaceNumber.attr,
        &dev_attr_bAlternateSetting.attr,
@@ -293,6 +324,7 @@ static struct attribute *intf_attrs[] = {
        &dev_attr_bInterfaceClass.attr,
        &dev_attr_bInterfaceSubClass.attr,
        &dev_attr_bInterfaceProtocol.attr,
+       &dev_attr_modalias.attr,
        NULL,
 };
 static struct attribute_group intf_attr_grp = {
index 16972159a57ad855485f61e1e1a9421e88a95b0f..0faf18d511de607f4d665a3ed1075ab6238dc7f7 100644 (file)
@@ -121,7 +121,7 @@ struct urb * usb_get_urb(struct urb *urb)
  * describing that request to the USB subsystem.  Request completion will
  * be indicated later, asynchronously, by calling the completion handler.
  * The three types of completion are success, error, and unlink
- * (a software-induced fault, also called "request cancelation").  
+ * (a software-induced fault, also called "request cancellation").  
  *
  * URBs may be submitted in interrupt context.
  *
@@ -170,7 +170,7 @@ struct urb * usb_get_urb(struct urb *urb)
  * As of Linux 2.6, all USB endpoint transfer queues support depths greater
  * than one.  This was previously a HCD-specific behavior, except for ISO
  * transfers.  Non-isochronous endpoint queues are inactive during cleanup
- * after faults (transfer errors or cancelation).
+ * after faults (transfer errors or cancellation).
  *
  * Reserved Bandwidth Transfers:
  *
@@ -395,7 +395,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
  *
  * This routine cancels an in-progress request.  URBs complete only
  * once per submission, and may be canceled only once per submission.
- * Successful cancelation means the requests's completion handler will
+ * Successful cancellation means the requests's completion handler will
  * be called with a status code indicating that the request has been
  * canceled (rather than any other code) and will quickly be removed
  * from host controller data structures.
index 3993156c2e826ce8d95a8717338d151e805a8104..3f783cbdc7c3e18345af9f36308e90ade3a81bc1 100644 (file)
@@ -569,7 +569,7 @@ static const struct usb_cdc_ether_desc ether_desc = {
 
 /* include the status endpoint if we can, even where it's optional.
  * use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
- * packet, to simplify cancelation; and a big transfer interval, to
+ * packet, to simplify cancellation; and a big transfer interval, to
  * waste less bandwidth.
  *
  * some drivers (like Linux 2.4 cdc-ether!) "need" it to exist even
index 2cff67ccce452619850516efaade9d99a1624755..1e5e6ddef787443564071325af3d6e1945c4d50e 100644 (file)
@@ -275,7 +275,7 @@ static const char *CHIP;
  *
  * After opening, configure non-control endpoints.  Then use normal
  * stream read() and write() requests; and maybe ioctl() to get more
- * precise FIFO status when recovering from cancelation.
+ * precise FIFO status when recovering from cancellation.
  */
 
 static void epio_complete (struct usb_ep *ep, struct usb_request *req)
index 0def9f70e88920863b9f2a6380fdf42c33b4205a..df75ab65a5ec1adb235a7d68bfe4002ac7f3a98f 100644 (file)
@@ -705,7 +705,7 @@ void nuke(struct lh7a40x_ep *ep, int status)
                done(ep, req, status);
        }
 
-       /* Disable IRQ if EP is enabled (has decriptor) */
+       /* Disable IRQ if EP is enabled (has descriptor) */
        if (ep->desc)
                pio_irq_disable(ep_index(ep));
 }
index f1762ed6db6394aefd5340ddabc8692f56d89fbc..4d591c764e382640257e7bc569d13d58216f6a75 100644 (file)
@@ -240,7 +240,7 @@ struct gs_dev {
        struct usb_ep           *dev_notify_ep; /* address of notify endpoint */
        struct usb_ep           *dev_in_ep;     /* address of in endpoint */
        struct usb_ep           *dev_out_ep;    /* address of out endpoint */
-       struct usb_endpoint_descriptor          /* desciptor of notify ep */
+       struct usb_endpoint_descriptor          /* descriptor of notify ep */
                                *dev_notify_ep_desc;
        struct usb_endpoint_descriptor          /* descriptor of in endpoint */
                                *dev_in_ep_desc;
index 3196c3265ff53b1b32a5e0c7607d2f6cd2b7c7fb..19e598c9641f9661b83cefe7c996ef99d44e0fc3 100644 (file)
@@ -124,3 +124,14 @@ config USB_SL811_HCD
          To compile this driver as a module, choose M here: the
          module will be called sl811-hcd.
 
+config USB_SL811_CS
+       tristate "CF/PCMCIA support for SL811HS HCD"
+       depends on USB_SL811_HCD && PCMCIA
+       default N
+       help
+         Wraps a PCMCIA driver around the SL811HS HCD, supporting the RATOC
+         REX-CFU1U CF card (often used with PDAs).  If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called "sl811_cs".
+
index a574ca06cf6b9694a387e9cd3f9b9a659b7df8ee..5dbd3e7a27c709a447dc9515badb98975c16f1be 100644 (file)
@@ -7,4 +7,5 @@ obj-$(CONFIG_USB_EHCI_HCD)      += ehci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)     += ohci-hcd.o
 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_ETRAX_ARCH_V10)   += hc_crisv10.o
index 84d2b93aca37d51a7e13f9db9072ce76b8105372..bc69bd7acebe6b4849ea7797bb992348816b3c29 100644 (file)
@@ -346,6 +346,22 @@ ehci_reboot (struct notifier_block *self, unsigned long code, void *null)
        return 0;
 }
 
+static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
+{
+       unsigned port;
+
+       if (!HCS_PPC (ehci->hcs_params))
+               return;
+
+       ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down");
+       for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
+               (void) ehci_hub_control(ehci_to_hcd(ehci),
+                               is_on ? SetPortFeature : ClearPortFeature,
+                               USB_PORT_FEAT_POWER,
+                               port--, NULL, 0);
+       msleep(20);
+}
+
 
 /* called by khubd or root hub init threads */
 
@@ -362,8 +378,10 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
        dbg_hcs_params (ehci, "reset");
        dbg_hcc_params (ehci, "reset");
 
+       /* cache this readonly data; minimize chip reads */
+       ehci->hcs_params = readl (&ehci->caps->hcs_params);
+
 #ifdef CONFIG_PCI
-       /* EHCI 0.96 and later may have "extended capabilities" */
        if (hcd->self.controller->bus == &pci_bus_type) {
                struct pci_dev  *pdev = to_pci_dev(hcd->self.controller);
 
@@ -383,9 +401,30 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
                        break;
                }
 
+               /* optional debug port, normally in the first BAR */
+               temp = pci_find_capability (pdev, 0x0a);
+               if (temp) {
+                       pci_read_config_dword(pdev, temp, &temp);
+                       temp >>= 16;
+                       if ((temp & (3 << 13)) == (1 << 13)) {
+                               temp &= 0x1fff;
+                               ehci->debug = hcd->regs + temp;
+                               temp = readl (&ehci->debug->control);
+                               ehci_info (ehci, "debug port %d%s\n",
+                                       HCS_DEBUG_PORT(ehci->hcs_params),
+                                       (temp & DBGP_ENABLED)
+                                               ? " IN USE"
+                                               : "");
+                               if (!(temp & DBGP_ENABLED))
+                                       ehci->debug = NULL;
+                       }
+               }
+
                temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
        } else
                temp = 0;
+
+       /* EHCI 0.96 and later may have "extended capabilities" */
        while (temp && count--) {
                u32             cap;
 
@@ -414,8 +453,7 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
                ehci_reset (ehci);
 #endif
 
-       /* cache this readonly data; minimize PCI reads */
-       ehci->hcs_params = readl (&ehci->caps->hcs_params);
+       ehci_port_power (ehci, 0);
 
        /* at least the Genesys GL880S needs fixup here */
        temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
@@ -657,16 +695,11 @@ done2:
 static void ehci_stop (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
-       u8                      rh_ports, port;
 
        ehci_dbg (ehci, "stop\n");
 
        /* Turn off port power on all root hub ports. */
-       rh_ports = HCS_N_PORTS (ehci->hcs_params);
-       for (port = 1; port <= rh_ports; port++)
-               (void) ehci_hub_control(hcd,
-                       ClearPortFeature, USB_PORT_FEAT_POWER,
-                       port, NULL, 0);
+       ehci_port_power (ehci, 0);
 
        /* no more interrupts ... */
        del_timer_sync (&ehci->watchdog);
@@ -748,7 +781,6 @@ static int ehci_resume (struct usb_hcd *hcd)
        unsigned                port;
        struct usb_device       *root = hcd->self.root_hub;
        int                     retval = -EINVAL;
-       int                     powerup = 0;
 
        // maybe restore (PCI) FLADJ
 
@@ -766,8 +798,6 @@ static int ehci_resume (struct usb_hcd *hcd)
                        up (&hcd->self.root_hub->serialize);
                        break;
                }
-               if ((status & PORT_POWER) == 0)
-                       powerup = 1;
                if (!root->children [port])
                        continue;
                dbg_port (ehci, __FUNCTION__, port + 1, status);
@@ -794,16 +824,9 @@ static int ehci_resume (struct usb_hcd *hcd)
                retval = ehci_start (hcd);
 
                /* here we "know" root ports should always stay powered;
-                * but some controllers may lost all power.
+                * but some controllers may lose all power.
                 */
-               if (powerup) {
-                       ehci_dbg (ehci, "...powerup ports...\n");
-                       for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
-                               (void) ehci_hub_control(hcd,
-                                       SetPortFeature, USB_PORT_FEAT_POWER,
-                                               port--, NULL, 0);
-                       msleep(20);
-               }
+               ehci_port_power (ehci, 1);
        }
 
        return retval;
index 2373537fabed3eeaa7083c9d9b4577292287acd1..d7b4f7939ded4d16989478ca58fa3edc573fb728 100644 (file)
@@ -72,6 +72,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd)
        }
 
        /* turn off now-idle HC */
+       del_timer_sync (&ehci->watchdog);
        ehci_halt (ehci);
        hcd->state = HC_STATE_SUSPENDED;
 
@@ -281,6 +282,8 @@ ehci_hub_descriptor (
        temp = 0x0008;                  /* per-port overcurrent reporting */
        if (HCS_PPC (ehci->hcs_params))
                temp |= 0x0001;         /* per-port power control */
+       else
+               temp |= 0x0002;         /* no power switching */
 #if 0
 // re-enable when we support USB_PORT_FEAT_INDICATOR below.
        if (HCS_INDICATOR (ehci->hcs_params))
@@ -436,9 +439,12 @@ static int ehci_hub_control (
                        /* force reset to complete */
                        writel (temp & ~PORT_RESET,
                                        &ehci->regs->port_status [wIndex]);
+                       /* REVISIT:  some hardware needs 550+ usec to clear
+                        * this bit; seems too long to spin routinely...
+                        */
                        retval = handshake (
                                        &ehci->regs->port_status [wIndex],
-                                       PORT_RESET, 0, 500);
+                                       PORT_RESET, 0, 750);
                        if (retval != 0) {
                                ehci_err (ehci, "port %d reset error %d\n",
                                        wIndex + 1, retval);
index e763a8399a7522ee627db7c37779c4cb4c4d1c5f..4df498231752812afd20b67c4f995a4ee50fbddd 100644 (file)
@@ -47,6 +47,12 @@ struct ehci_stats {
 #define        EHCI_MAX_ROOT_PORTS     15              /* see HCS_N_PORTS */
 
 struct ehci_hcd {                      /* one per controller */
+       /* glue to PCI and HCD framework */
+       struct ehci_caps __iomem *caps;
+       struct ehci_regs __iomem *regs;
+       struct ehci_dbg_port __iomem *debug;
+
+       __u32                   hcs_params;     /* cached register copy */
        spinlock_t              lock;
 
        /* async schedule support */
@@ -84,11 +90,6 @@ struct ehci_hcd {                    /* one per controller */
 
        unsigned                is_tdi_rh_tt:1; /* TDI roothub with TT */
 
-       /* glue to PCI and HCD framework */
-       struct ehci_caps __iomem *caps;
-       struct ehci_regs __iomem *regs;
-       __u32                   hcs_params;     /* cached register copy */
-
        /* irq statistics */
 #ifdef EHCI_STATS
        struct ehci_stats       stats;
@@ -165,7 +166,7 @@ struct ehci_caps {
        /* these fields are specified as 8 and 16 bit registers,
         * but some hosts can't perform 8 or 16 bit PCI accesses.
         */
-       u32     hc_capbase;
+       u32             hc_capbase;
 #define HC_LENGTH(p)           (((p)>>00)&0x00ff)      /* bits 7:0 */
 #define HC_VERSION(p)          (((p)>>16)&0xffff)      /* bits 31:16 */
        u32             hcs_params;     /* HCSPARAMS - offset 0x4 */
@@ -273,7 +274,7 @@ struct ehci_dbg_port {
 #define DBGP_ENABLED   (1<<28)
 #define DBGP_DONE      (1<<16)
 #define DBGP_INUSE     (1<<10)
-#define DBGP_ERRCODE(x)        (((x)>>7)&0x0f)
+#define DBGP_ERRCODE(x)        (((x)>>7)&0x07)
 #      define DBGP_ERR_BAD     1
 #      define DBGP_ERR_SIGNAL  2
 #define DBGP_ERROR     (1<<6)
@@ -282,11 +283,11 @@ struct ehci_dbg_port {
 #define DBGP_LEN(x)    (((x)>>0)&0x0f)
        u32     pids;
 #define DBGP_PID_GET(x)                (((x)>>16)&0xff)
-#define DBGP_PID_SET(data,tok) (((data)<<8)|(tok));
+#define DBGP_PID_SET(data,tok) (((data)<<8)|(tok))
        u32     data03;
        u32     data47;
        u32     address;
-#define DBGP_EPADDR(dev,ep)    (((dev)<<8)|(ep));
+#define DBGP_EPADDR(dev,ep)    (((dev)<<8)|(ep))
 } __attribute__ ((packed));
 
 /*-------------------------------------------------------------------------*/
index 376f8a034f658856b91be40d79ed6f8a7ad108da..d9883d774d3a4a8ab02807a628df41ac2767fcff 100644 (file)
@@ -4329,7 +4329,7 @@ static int __init etrax_usb_hc_init(void)
        bus->bus_name="ETRAX 100LX";
        bus->hcpriv = hc;
 
-       /* Initalize RH to the default address.
+       /* Initialize RH to the default address.
           And make sure that we have no status change indication */
        hc->rh.numports = 2;  /* The RH has two ports */
        hc->rh.devnum = 1;
index d309e292198ed2d068c121d91eeabb243f2279a5..99d43f758ad0e85d524d00cedaf93bed8793ac15 100644 (file)
@@ -2,8 +2,8 @@
  * SL811HS HCD (Host Controller Driver) for USB.
  *
  * Copyright (C) 2004 Psion Teklogix (for NetBook PRO)
- * Copyright (C) 2004 David Brownell
- * 
+ * Copyright (C) 2004-2005 David Brownell
+ *
  * Periodic scheduling is based on Roman's OHCI code
  *     Copyright (C) 1999 Roman Weissgaerber
  *
@@ -15,7 +15,7 @@
  * For documentation, see the SL811HS spec and the "SL811HS Embedded Host"
  * document (providing significant pieces missing from that spec); plus
  * the SL811S spec if you want peripheral side info.
- */ 
+ */
 
 /*
  * Status:  Passed basic stress testing, works with hubs, mice, keyboards,
@@ -67,7 +67,7 @@
 MODULE_DESCRIPTION("SL811HS USB Host Controller Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION "15 Dec 2004"
+#define DRIVER_VERSION "19 May 2005"
 
 
 #ifndef DEBUG
@@ -121,6 +121,10 @@ static void port_power(struct sl811 *sl811, int is_on)
        /* reset as thoroughly as we can */
        if (sl811->board && sl811->board->reset)
                sl811->board->reset(hcd->self.controller);
+       else {
+               sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0);
+               mdelay(20);
+       }
 
        sl811_write(sl811, SL11H_IRQ_ENABLE, 0);
        sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1);
@@ -134,7 +138,7 @@ static void port_power(struct sl811 *sl811, int is_on)
 
 /* This is a PIO-only HCD.  Queueing appends URBs to the endpoint's queue,
  * and may start I/O.  Endpoint queues are scanned during completion irq
- * handlers (one per packet: ACK, NAK, faults, etc) and urb cancelation.
+ * handlers (one per packet: ACK, NAK, faults, etc) and urb cancellation.
  *
  * Using an external DMA engine to copy a packet at a time could work,
  * though setup/teardown costs may be too big to make it worthwhile.
@@ -443,6 +447,7 @@ static void finish_request(
        spin_lock(&urb->lock);
        if (urb->status == -EINPROGRESS)
                urb->status = status;
+       urb->hcpriv = NULL;
        spin_unlock(&urb->lock);
 
        spin_unlock(&sl811->lock);
@@ -472,7 +477,7 @@ static void finish_request(
                if (*prev)
                        *prev = ep->next;
                sl811->load[i] -= ep->load;
-       }       
+       }
        ep->branch = PERIODIC_SIZE;
        sl811->periodic_count--;
        sl811_to_hcd(sl811)->self.bandwidth_allocated
@@ -661,9 +666,9 @@ retry:
 
 #ifdef QUIRK2
        /* this may no longer be necessary ... */
-       if (irqstat == 0 && ret == IRQ_NONE) {
+       if (irqstat == 0) {
                irqstat = checkdone(sl811);
-               if (irqstat /* && irq != ~0 */ )
+               if (irqstat)
                        sl811->stat_lost++;
        }
 #endif
@@ -722,7 +727,8 @@ retry:
                if (sl811->active_a) {
                        sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0);
                        finish_request(sl811, sl811->active_a,
-                               container_of(sl811->active_a->hep->urb_list.next,
+                               container_of(sl811->active_a
+                                               ->hep->urb_list.next,
                                        struct urb, urb_list),
                                NULL, -ESHUTDOWN);
                        sl811->active_a = NULL;
@@ -731,14 +737,15 @@ retry:
                if (sl811->active_b) {
                        sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0);
                        finish_request(sl811, sl811->active_b,
-                               container_of(sl811->active_b->hep->urb_list.next,
+                               container_of(sl811->active_b
+                                               ->hep->urb_list.next,
                                        struct urb, urb_list),
                                NULL, -ESHUTDOWN);
                        sl811->active_b = NULL;
                }
 #endif
 
-               /* port status seems wierd until after reset, so
+               /* port status seems weird until after reset, so
                 * force the reset and make khubd clean up later.
                 */
                sl811->port1 |= (1 << USB_PORT_FEAT_C_CONNECTION)
@@ -761,7 +768,7 @@ retry:
                        goto retry;
        }
 
-       if (sl811->periodic_count == 0 && list_empty(&sl811->async)) 
+       if (sl811->periodic_count == 0 && list_empty(&sl811->async))
                sofirq_off(sl811);
        sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable);
 
@@ -796,7 +803,7 @@ static int balance(struct sl811 *sl811, u16 period, u16 load)
                        }
                        if (j < PERIODIC_SIZE)
                                continue;
-                       branch = i; 
+                       branch = i;
                }
        }
        return branch;
@@ -890,6 +897,7 @@ static int sl811h_urb_enqueue(
                        break;
                }
 
+               ep->hep = hep;
                hep->hcpriv = ep;
        }
 
@@ -961,15 +969,16 @@ fail:
 static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
 {
        struct sl811            *sl811 = hcd_to_sl811(hcd);
-       struct usb_host_endpoint *hep = urb->hcpriv;
+       struct usb_host_endpoint *hep;
        unsigned long           flags;
        struct sl811h_ep        *ep;
        int                     retval = 0;
 
+       spin_lock_irqsave(&sl811->lock, flags);
+       hep = urb->hcpriv;
        if (!hep)
-               return -EINVAL;
+               goto fail;
 
-       spin_lock_irqsave(&sl811->lock, flags);
        ep = hep->hcpriv;
        if (ep) {
                /* finish right away if this urb can't be active ...
@@ -1017,6 +1026,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
                        VDBG("dequeue, urb %p active %s; wait4irq\n", urb,
                                (sl811->active_a == ep) ? "A" : "B");
        } else
+fail:
                retval = -EINVAL;
        spin_unlock_irqrestore(&sl811->lock, flags);
        return retval;
@@ -1576,6 +1586,9 @@ sl811h_start(struct usb_hcd *hcd)
        if (sl811->board && sl811->board->power)
                hub_set_power_budget(udev, sl811->board->power * 2);
 
+       /* enable power and interupts */
+       port_power(sl811, 1);
+
        return 0;
 }
 
@@ -1618,7 +1631,7 @@ static struct hc_driver sl811h_hc_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __init_or_module
+static int __devexit
 sl811h_remove(struct device *dev)
 {
        struct usb_hcd          *hcd = dev_get_drvdata(dev);
@@ -1631,21 +1644,20 @@ sl811h_remove(struct device *dev)
        remove_debug_file(sl811);
        usb_remove_hcd(hcd);
 
-       iounmap(sl811->data_reg);
+       /* some platforms may use IORESOURCE_IO */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       release_mem_region(res->start, 1);
+       if (res)
+               iounmap(sl811->data_reg);
 
-       iounmap(sl811->addr_reg);
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, 1);
+       if (res)
+               iounmap(sl811->addr_reg);
 
        usb_put_hcd(hcd);
        return 0;
 }
 
-#define resource_len(r) (((r)->end - (r)->start) + 1)
-
-static int __init
+static int __devinit
 sl811h_probe(struct device *dev)
 {
        struct usb_hcd          *hcd;
@@ -1656,7 +1668,7 @@ sl811h_probe(struct device *dev)
        void __iomem            *addr_reg;
        void __iomem            *data_reg;
        int                     retval;
-       u8                      tmp;
+       u8                      tmp, ioaddr = 0;
 
        /* basic sanity checks first.  board-specific init logic should
         * have initialized these three resources and probably board
@@ -1664,13 +1676,8 @@ sl811h_probe(struct device *dev)
         * minimal sanity checking.
         */
        pdev = container_of(dev, struct platform_device, dev);
-       if (pdev->num_resources < 3)
-               return -ENODEV;
-
-       addr = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       data = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        irq = platform_get_irq(pdev, 0);
-       if (!addr || !data || irq < 0)
+       if (pdev->num_resources < 3 || irq < 0)
                return -ENODEV;
 
        /* refuse to confuse usbcore */
@@ -1679,24 +1686,31 @@ sl811h_probe(struct device *dev)
                return -EINVAL;
        }
 
-       if (!request_mem_region(addr->start, 1, hcd_name)) {
-               retval = -EBUSY;
-               goto err1;
-       }
-       addr_reg = ioremap(addr->start, resource_len(addr));
-       if (addr_reg == NULL) {
-               retval = -ENOMEM;
-               goto err2;
-       }
+       /* the chip may be wired for either kind of addressing */
+       addr = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       data = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       retval = -EBUSY;
+       if (!addr || !data) {
+               addr = platform_get_resource(pdev, IORESOURCE_IO, 0);
+               data = platform_get_resource(pdev, IORESOURCE_IO, 1);
+               if (!addr || !data)
+                       return -ENODEV;
+               ioaddr = 1;
+
+               addr_reg = (void __iomem *) addr->start;
+               data_reg = (void __iomem *) data->start;
+       } else {
+               addr_reg = ioremap(addr->start, 1);
+               if (addr_reg == NULL) {
+                       retval = -ENOMEM;
+                       goto err2;
+               }
 
-       if (!request_mem_region(data->start, 1, hcd_name)) {
-               retval = -EBUSY;
-               goto err3;
-       }
-       data_reg = ioremap(data->start, resource_len(addr));
-       if (data_reg == NULL) {
-               retval = -ENOMEM;
-               goto err4;
+               data_reg = ioremap(data->start, 1);
+               if (data_reg == NULL) {
+                       retval = -ENOMEM;
+                       goto err4;
+               }
        }
 
        /* allocate and initialize hcd */
@@ -1737,12 +1751,14 @@ sl811h_probe(struct device *dev)
                goto err6;
        }
 
-       /* sl811s would need a different handler for this irq */
-#ifdef CONFIG_ARM
-       /* Cypress docs say the IRQ is IRQT_HIGH ... */
-       set_irq_type(irq, IRQT_RISING);
-#endif
-       retval = usb_add_hcd(hcd, irq, SA_INTERRUPT);
+       /* The chip's IRQ is level triggered, active high.  A requirement
+        * for platform device setup is to cope with things like signal
+        * inverters (e.g. CF is active low) or working only with edge
+        * triggers (e.g. most ARM CPUs).  Initial driver stress testing
+        * was on a system with single edge triggering, so most sorts of
+        * triggering arrangement should work.
+        */
+       retval = usb_add_hcd(hcd, irq, SA_INTERRUPT | SA_SHIRQ);
        if (retval != 0)
                goto err6;
 
@@ -1752,14 +1768,12 @@ sl811h_probe(struct device *dev)
  err6:
        usb_put_hcd(hcd);
  err5:
-       iounmap(data_reg);
+       if (!ioaddr)
+               iounmap(data_reg);
  err4:
-       release_mem_region(data->start, 1);
- err3:
-       iounmap(addr_reg);
+       if (!ioaddr)
+               iounmap(addr_reg);
  err2:
-       release_mem_region(addr->start, 1);
- err1:
        DBG("init error, %d\n", retval);
        return retval;
 }
@@ -1767,7 +1781,7 @@ sl811h_probe(struct device *dev)
 #ifdef CONFIG_PM
 
 /* for this device there's no useful distinction between the controller
- * and its root hub, except that the root hub only gets direct PM calls 
+ * and its root hub, except that the root hub only gets direct PM calls
  * when CONFIG_USB_SUSPEND is enabled.
  */
 
@@ -1821,20 +1835,22 @@ sl811h_resume(struct device *dev, u32 phase)
 #endif
 
 
-static struct device_driver sl811h_driver = {
+/* this driver is exported so sl811_cs can depend on it */
+struct device_driver sl811h_driver = {
        .name =         (char *) hcd_name,
        .bus =          &platform_bus_type,
 
        .probe =        sl811h_probe,
-       .remove =       sl811h_remove,
+       .remove =       __devexit_p(sl811h_remove),
 
        .suspend =      sl811h_suspend,
        .resume =       sl811h_resume,
 };
+EXPORT_SYMBOL(sl811h_driver);
 
 /*-------------------------------------------------------------------------*/
-static int __init sl811h_init(void) 
+
+static int __init sl811h_init(void)
 {
        if (usb_disabled())
                return -ENODEV;
@@ -1844,8 +1860,8 @@ static int __init sl811h_init(void)
 }
 module_init(sl811h_init);
 
-static void __exit sl811h_cleanup(void) 
-{      
+static void __exit sl811h_cleanup(void)
+{
        driver_unregister(&sl811h_driver);
 }
 module_exit(sl811h_cleanup);
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
new file mode 100644 (file)
index 0000000..6e17326
--- /dev/null
@@ -0,0 +1,442 @@
+/*
+ * PCMCIA driver for SL811HS (as found in REX-CFU1U)
+ * Filename: sl811_cs.c
+ * Author:   Yukio Yamamoto
+ *
+ *  Port to sl811-hcd and 2.6.x by
+ *    Botond Botyanszki <boti@rocketmail.com>
+ *    Simon Pickering
+ *
+ *  Last update: 2005-05-12
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+#include <linux/usb_sl811.h>
+
+MODULE_AUTHOR("Botond Botyanszki");
+MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6");
+MODULE_LICENSE("GPL");
+
+
+/*====================================================================*/
+/* MACROS                                                             */
+/*====================================================================*/
+
+#if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG)
+
+static int pc_debug = 0;
+module_param(pc_debug, int, 0644);
+
+#define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args)
+
+#else
+#define DBG(n, args...) do{}while(0)
+#endif /* no debugging */
+
+#define INFO(args...) printk(KERN_INFO "sl811_cs: " args)
+
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
+
+#define CS_CHECK(fn, ret) \
+       do { \
+               last_fn = (fn); \
+               if ((last_ret = (ret)) != 0) \
+                       goto cs_failed; \
+       } while (0)
+
+/*====================================================================*/
+/* VARIABLES                                                          */
+/*====================================================================*/
+
+static const char driver_name[DEV_NAME_LEN]  = "sl811_cs";
+
+static dev_link_t *dev_list = NULL;
+
+static int irq_list[4] = { -1 };
+static int irq_list_count;
+
+module_param_array(irq_list, int, &irq_list_count, 0444);
+
+INT_MODULE_PARM(irq_mask, 0xdeb8);
+
+typedef struct local_info_t {
+       dev_link_t              link;
+       dev_node_t              node;
+} local_info_t;
+
+/*====================================================================*/
+
+static void release_platform_dev(struct device * dev)
+{
+       DBG(0, "sl811_cs platform_dev release\n");
+       dev->parent = NULL;
+}
+
+static struct sl811_platform_data platform_data = {
+       .potpg          = 100,
+       .power          = 50,           /* == 100mA */
+       // .reset       = ... FIXME:  invoke CF reset on the card
+};
+
+static struct resource resources[] = {
+       [0] = {
+               .flags  = IORESOURCE_IRQ,
+       },
+       [1] = {
+               // .name   = "address",
+               .flags  = IORESOURCE_IO,
+       },
+       [2] = {
+               // .name   = "data",
+               .flags  = IORESOURCE_IO,
+       },
+};
+
+extern struct device_driver sl811h_driver;
+
+static struct platform_device platform_dev = {
+       .id                     = -1,
+       .dev = {
+               .platform_data = &platform_data,
+               .release       = release_platform_dev,
+       },
+       .resource               = resources,
+       .num_resources          = ARRAY_SIZE(resources),
+};
+
+static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
+{
+       if (platform_dev.dev.parent)
+               return -EBUSY;
+       platform_dev.dev.parent = parent;
+
+       /* finish seting up the platform device */
+       resources[0].start = irq;
+
+       resources[1].start = base_addr;
+       resources[1].end = base_addr;
+
+       resources[2].start = base_addr + 1;
+       resources[2].end   = base_addr + 1;
+
+       /* The driver core will probe for us.  We know sl811-hcd has been
+        * initialized already because of the link order dependency.
+        */
+       platform_dev.name = sl811h_driver.name;
+       return platform_device_register(&platform_dev);
+}
+
+/*====================================================================*/
+
+static void sl811_cs_detach(dev_link_t *link)
+{
+       dev_link_t **linkp;
+
+       DBG(0, "sl811_cs_detach(0x%p)\n", link);
+
+       /* Locate device structure */
+       for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
+               if (*linkp == link)
+                       break;
+       }
+       if (*linkp == NULL)
+               return;
+
+       /* Break the link with Card Services */
+       if (link->handle)
+               pcmcia_deregister_client(link->handle);
+
+       /* Unlink device structure, and free it */
+       *linkp = link->next;
+       /* This points to the parent local_info_t struct */
+       kfree(link->priv);
+}
+
+static void sl811_cs_release(dev_link_t * link)
+{
+
+       DBG(0, "sl811_cs_release(0x%p)\n", link);
+
+       if (link->open) {
+               DBG(1, "sl811_cs: release postponed, '%s' still open\n",
+                   link->dev->dev_name);
+               link->state |= DEV_STALE_CONFIG;
+               return;
+       }
+
+       /* Unlink the device chain */
+       link->dev = NULL;
+
+       platform_device_unregister(&platform_dev);
+       pcmcia_release_configuration(link->handle);
+       if (link->io.NumPorts1)
+               pcmcia_release_io(link->handle, &link->io);
+       if (link->irq.AssignedIRQ)
+               pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+
+       if (link->state & DEV_STALE_LINK)
+               sl811_cs_detach(link);
+}
+
+static void sl811_cs_config(dev_link_t *link)
+{
+       client_handle_t         handle = link->handle;
+       struct device           *parent = &handle_to_dev(handle);
+       local_info_t            *dev = link->priv;
+       tuple_t                 tuple;
+       cisparse_t              parse;
+       int                     last_fn, last_ret;
+       u_char                  buf[64];
+       config_info_t           conf;
+       cistpl_cftable_entry_t  dflt = { 0 };
+
+       DBG(0, "sl811_cs_config(0x%p)\n", link);
+
+       tuple.DesiredTuple = CISTPL_CONFIG;
+       tuple.Attributes = 0;
+       tuple.TupleData = buf;
+       tuple.TupleDataMax = sizeof(buf);
+       tuple.TupleOffset = 0;
+       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+       CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.Present = parse.config.rmask[0];
+
+       /* Configure card */
+       link->state |= DEV_CONFIG;
+
+       /* Look up the current Vcc */
+       CS_CHECK(GetConfigurationInfo,
+                       pcmcia_get_configuration_info(handle, &conf));
+       link->conf.Vcc = conf.Vcc;
+
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       while (1) {
+               cistpl_cftable_entry_t  *cfg = &(parse.cftable_entry);
+
+               if (pcmcia_get_tuple_data(handle, &tuple) != 0
+                               || pcmcia_parse_tuple(handle, &tuple, &parse)
+                                               != 0)
+                       goto next_entry;
+
+               if (cfg->flags & CISTPL_CFTABLE_DEFAULT) {
+                       dflt = *cfg;
+               }
+
+               if (cfg->index == 0)
+                       goto next_entry;
+
+               link->conf.ConfigIndex = cfg->index;
+
+               /* Use power settings for Vcc and Vpp if present */
+               /*  Note that the CIS values need to be rescaled */
+               if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
+                       if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000
+                                       != conf.Vcc)
+                               goto next_entry;
+               } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
+                       if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000
+                                       != conf.Vcc)
+                               goto next_entry;
+               }
+
+               if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
+                       link->conf.Vpp1 = link->conf.Vpp2 =
+                               cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
+               else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
+                       link->conf.Vpp1 = link->conf.Vpp2 =
+                               dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
+
+               /* we need an interrupt */
+               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+                       link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+               /* IO window settings */
+               link->io.NumPorts1 = link->io.NumPorts2 = 0;
+               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+
+                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+                       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+                       link->io.BasePort1 = io->win[0].base;
+                       link->io.NumPorts1 = io->win[0].len;
+
+                       if (pcmcia_request_io(link->handle, &link->io) != 0)
+                               goto next_entry;
+               }
+               break;
+
+next_entry:
+               if (link->io.NumPorts1)
+                       pcmcia_release_io(link->handle, &link->io);
+               last_ret = pcmcia_get_next_tuple(handle, &tuple);
+       }
+
+       /* require an IRQ and two registers */
+       if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
+               goto cs_failed;
+       if (link->conf.Attributes & CONF_ENABLE_IRQ)
+               CS_CHECK(RequestIRQ,
+                       pcmcia_request_irq(link->handle, &link->irq));
+       else
+               goto cs_failed;
+
+       CS_CHECK(RequestConfiguration,
+               pcmcia_request_configuration(link->handle, &link->conf));
+
+       sprintf(dev->node.dev_name, driver_name);
+       dev->node.major = dev->node.minor = 0;
+       link->dev = &dev->node;
+
+       printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
+              dev->node.dev_name, link->conf.ConfigIndex,
+              link->conf.Vcc/10, link->conf.Vcc%10);
+       if (link->conf.Vpp1)
+               printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
+       printk(", irq %d", link->irq.AssignedIRQ);
+       printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+              link->io.BasePort1+link->io.NumPorts1-1);
+       printk("\n");
+
+       link->state &= ~DEV_CONFIG_PENDING;
+
+       if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
+                       < 0) {
+cs_failed:
+               printk("sl811_cs_config failed\n");
+               cs_error(link->handle, last_fn, last_ret);
+               sl811_cs_release(link);
+               link->state &= ~DEV_CONFIG_PENDING;
+       }
+}
+
+static int
+sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
+{
+       dev_link_t *link = args->client_data;
+
+       DBG(1, "sl811_cs_event(0x%06x)\n", event);
+
+       switch (event) {
+       case CS_EVENT_CARD_REMOVAL:
+               link->state &= ~DEV_PRESENT;
+               if (link->state & DEV_CONFIG)
+                       sl811_cs_release(link);
+               break;
+
+       case CS_EVENT_CARD_INSERTION:
+               link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+               sl811_cs_config(link);
+               break;
+
+       case CS_EVENT_PM_SUSPEND:
+               link->state |= DEV_SUSPEND;
+               /* Fall through... */
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG)
+                       pcmcia_release_configuration(link->handle);
+               break;
+
+       case CS_EVENT_PM_RESUME:
+               link->state &= ~DEV_SUSPEND;
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (link->state & DEV_CONFIG)
+                       pcmcia_request_configuration(link->handle, &link->conf);
+               DBG(0, "reset sl811-hcd here?\n");
+               break;
+       }
+       return 0;
+}
+
+static dev_link_t *sl811_cs_attach(void)
+{
+       local_info_t *local;
+       dev_link_t *link;
+       client_reg_t client_reg;
+       int ret, i;
+
+       local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+       if (!local)
+               return NULL;
+       memset(local, 0, sizeof(local_info_t));
+       link = &local->link;
+       link->priv = local;
+
+       /* Initialize */
+       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+       link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
+       if (irq_list[0] == -1)
+               link->irq.IRQInfo2 = irq_mask;
+       else
+               for (i = 0; i < irq_list_count; i++)
+                       link->irq.IRQInfo2 |= 1 << irq_list[i];
+       link->irq.Handler = NULL;
+
+       link->conf.Attributes = 0;
+       link->conf.Vcc = 33;
+       link->conf.IntType = INT_MEMORY_AND_IO;
+
+       /* Register with Card Services */
+       link->next = dev_list;
+       dev_list = link;
+       client_reg.dev_info = (dev_info_t *) &driver_name;
+       client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+       client_reg.EventMask =
+               CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+               CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+               CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+       client_reg.event_handler = &sl811_cs_event;
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+       ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               sl811_cs_detach(link);
+               return NULL;
+       }
+
+       return link;
+}
+
+static struct pcmcia_driver sl811_cs_driver = {
+       .owner          = THIS_MODULE,
+       .drv            = {
+               .name   = (char *)driver_name,
+       },
+       .attach         = sl811_cs_attach,
+       .detach         = sl811_cs_detach,
+};
+
+/*====================================================================*/
+
+static int __init init_sl811_cs(void)
+{
+       return pcmcia_register_driver(&sl811_cs_driver);
+}
+module_init(init_sl811_cs);
+
+static void __exit exit_sl811_cs(void)
+{
+       pcmcia_unregister_driver(&sl811_cs_driver);
+}
+module_exit(exit_sl811_cs);
index 5791723e6083bbccd8d268aad6834a7f9e3cf678..a330a4b50e1672402743685102a3f1f38618f37e 100644 (file)
@@ -23,7 +23,7 @@
  *
  *
  * The driver brings the USB functions of the MDC800 to Linux.
- * To use the Camera you must support the USB Protocoll of the camera
+ * To use the Camera you must support the USB Protocol of the camera
  * to the Kernel Node.
  * The Driver uses a misc device Node. Create it with :
  * mknod /dev/mustek c 180 32
index 2d76be62f4e0f2e040c89c11047e423246d2d9fd..94ce2a9ad50f5e9b71b5abdf49f862b3745a0a24 100644 (file)
@@ -386,7 +386,7 @@ static int aiptek_convert_from_2s_complement(unsigned char c)
  * convention above.) I therefore have taken over REL_MISC and ABS_MISC
  * (for relative and absolute reports, respectively) for communicating
  * Proximity. Why two events? I thought it interesting to know if the
- * Proximity event occured while the tablet was in absolute or relative
+ * Proximity event occurred while the tablet was in absolute or relative
  * mode.
  *
  * Other tablets use the notion of a certain minimum stylus pressure
index 869ff73690acebf04655691c4edc01a017a6abe4..2d8bd9dcc6edae2b8d1c4ea112f0c5e66cddc149 100644 (file)
@@ -1315,6 +1315,8 @@ void hid_init_reports(struct hid_device *hid)
 #define USB_DEVICE_ID_WACOM_INTUOS2    0x0040
 #define USB_DEVICE_ID_WACOM_VOLITO     0x0060
 #define USB_DEVICE_ID_WACOM_PTU                0x0003
+#define USB_DEVICE_ID_WACOM_INTUOS3    0x00B0
+#define USB_DEVICE_ID_WACOM_CINTIQ     0x003F
 
 #define USB_VENDOR_ID_KBGEAR           0x084e
 #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
@@ -1401,6 +1403,7 @@ void hid_init_reports(struct hid_device *hid)
 
 #define USB_VENDOR_ID_DELORME          0x1163
 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
+#define USB_DEVICE_ID_DELORME_EM_LT20  0x0200
 
 #define USB_VENDOR_ID_MCC              0x09db
 #define USB_DEVICE_ID_MCC_PMD1024LS    0x0076
@@ -1412,6 +1415,12 @@ void hid_init_reports(struct hid_device *hid)
 #define USB_VENDOR_ID_BTC              0x046e
 #define USB_DEVICE_ID_BTC_KEYBOARD     0x5303
 
+#define USB_VENDOR_ID_VERNIER          0x08f7
+#define USB_DEVICE_ID_VERNIER_LABPRO   0x0001
+#define USB_DEVICE_ID_VERNIER_GOTEMP   0x0002
+#define USB_DEVICE_ID_VERNIER_SKIP     0x0003
+#define USB_DEVICE_ID_VERNIER_CYCLOPS  0x0004
+
 
 /*
  * Alphabetically sorted blacklist by quirk type.
@@ -1437,6 +1446,7 @@ static struct hid_blacklist {
        { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
@@ -1456,6 +1466,10 @@ static struct hid_blacklist {
        { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },
@@ -1481,6 +1495,10 @@ static struct hid_blacklist {
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
 
index 6b45a66d58c157fee46a7b10c165cde5d380a6a1..ab1a2a30ce7ca273c683533826fc859965767119 100644 (file)
@@ -32,7 +32,7 @@
  *    Changed reset from standard USB dev reset to vendor reset
  *    Changed data sent to host from compensated to raw coordinates
  *    Eliminated vendor/product module params
- *    Performed multiple successfull tests with an EXII-5010UC
+ *    Performed multiple successful tests with an EXII-5010UC
  *
  *  1.5 02/27/2005 ddstreet@ieee.org
  *    Added module parameter to select raw or hw-calibrated coordinate reporting
index d6051822416e0a4601828e41545125fe25f9819b..036c485d1d1eeb6ef582930f9f9356cc858f943e 100644 (file)
@@ -5041,7 +5041,7 @@ ov6xx0_configure(struct usb_ov511 *ov)
                { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
 //             { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
                { OV511_I2C_BUS, 0x2d, 0x99 },
-               { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Procesing Parameter */
+               { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Processing Parameter */
                { OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */
                { OV511_I2C_BUS, 0x38, 0x8b },
                { OV511_I2C_BUS, 0x39, 0x40 },
diff --git a/drivers/usb/media/pwc/ChangeLog b/drivers/usb/media/pwc/ChangeLog
deleted file mode 100644 (file)
index b2eb71a..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-9.0.2
-
-* Adding #ifdef to compile PWC before and after 2.6.5
-
-9.0.1
-
-9.0
-
-
-8.12
-
-* Implement motorized pan/tilt feature for Logitech QuickCam Orbit/Spere.
-
-8.11.1
-
-* Fix for PCVC720/40, would not be able to set videomode
-* Fix for Samsung MPC models, appearantly they are based on a newer chipset
-
-8.11
-
-* 20 dev_hints (per request)
-* Hot unplugging should be better, no more dangling pointers or memory leaks
-* Added reserved Logitech webcam IDs
-* Device now remembers size & fps between close()/open()
-* Removed palette stuff altogether
-
-8.10.1
-
-* Added IDs for PCVC720K/40 and Creative Labs Webcam Pro
-
-8.10
-
-* Fixed ID for QuickCam Notebook pro
-* Added GREALSIZE ioctl() call
-* Fixed bug in case PWCX was not loaded and invalid size was set
-
-8.9
-
-* Merging with kernel 2.5.49
-* Adding IDs for QuickCam Zoom & QuickCam Notebook
-
-8.8
-
-* Fixing 'leds' parameter
-* Adding IDs for Logitech QuickCam Pro 4000
-* Making URB init/cleanup a little nicer
-
-8.7
-
-* Incorporating changes in ioctl() parameter passing
-* Also changes to URB mechanism
-
-8.6
-
-* Added ID's for Visionite VCS UM100 and UC300
-* Removed YUV420-interlaced palette altogether (was confusing)
-* Removed MIRROR stuff as it didn't work anyway
-* Fixed a problem with the 'leds' parameter (wouldn't blink)
-* Added ioctl()s for advanced features: 'extended' whitebalance ioctl()s,
-  CONTOUR, BACKLIGHT, FLICKER, DYNNOISE.
-* VIDIOCGCAP.name now contains real camera model name instead of
-  'Philips xxx webcam'
-* Added PROBE ioctl (see previous point & API doc)
-
-8.5
-
-* Adding IDs for Creative Labs Webcam 5
-* Adding IDs for SOTEC CMS-001 webcam
-* Solving possible hang in VIDIOCSYNC when unplugging the cam 
-* Forgot to return structure in VIDIOCPWCGAWB, oops
-* Time interval for the LEDs are now in milliseconds
-
-8.4
-
-* Fixing power_save option for Vesta range
-* Handling new error codes in ISOC callback
-* Adding dev_hint module parameter, to specify /dev/videoX device nodes
-
-8.3
-
-* Adding Samsung C10 and C30 cameras
-* Removing palette module parameter
-* Fixed typo in ID of QuickCam 3000 Pro
-* Adding LED settings (blinking while in use) for ToUCam cameras.
-* Turns LED off when camera is not in use.
-
-8.2
-
-* Making module more silent when trace = 0 
-* Adding QuickCam 3000 Pro IDs
-* Chrominance control for the Vesta cameras
-* Hopefully fixed problems on machines with BIGMEM and > 1GB of RAM
-* Included Oliver Neukem's lock_kernel() patch
-* Allocates less memory for image buffers
-* Adds ioctl()s for the whitebalancing
-
-8.1
-
-* Adding support for 750
-* Adding V4L GAUDIO/SAUDIO/UNIT ioctl() calls
-
-8.0
-* 'damage control' after inclusion in 2.4.5.
-* Changed wait-queue mechanism in read/mmap/poll according to the book.
-* Included YUV420P palette.
-* Changed interface to decompressor module.
-* Cleaned up pwc structure a bit.
-
-7.0
-
-* Fixed bug in vcvt_420i_yuyv; extra variables on stack were misaligned.
-* There is now a clear error message when an image size is selected that
-  is only supported using the decompressor, and the decompressor isn't
-  loaded.
-* When the decompressor wasn't loaded, selecting large image size
-  would create skewed or double images.
-
-6.3
-
-* Introduced spinlocks for the buffer pointer manipulation; a number of
-  reports seem to suggest the down()/up() semaphores were the cause of
-  lockups, since they are not suitable for interrupt/user locking.
-* Separated decompressor and core code into 2 modules.
-
-6.2
-
-* Non-integral image sizes are now padded with gray or black.
-* Added SHUTTERSPEED ioctl().
-* Fixed buglet in VIDIOCPWCSAGC; the function would always return an error,
-  even though the call succeeded.
-* Added hotplug support for 2.4.*.
-* Memory: the 645/646 uses less memory now.
-
-6.1
-
-* VIDIOCSPICT returns -EINVAL with invalid palettes.
-* Added saturation control.
-* Split decompressors from rest.
-* Fixed bug that would reset the framerate to the default framerate if 
-  the rate field was set to 0 (which is not what I intended, nl. do not 
-  change the framerate!).
-* VIDIOCPWCSCQUAL (setting compression quality) now takes effect immediately.
-* Workaround for a bug in the 730 sensor.
index e0b41ed4407f5fa8767c90d66e00e2bb234b3a9d..2d93a775011a3d390fcf277d46225f273a74a7be 100644 (file)
@@ -1,6 +1,6 @@
 ifneq ($(KERNELRELEASE),)
 
-pwc-objs       := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o
+pwc-objs       := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o
 
 obj-$(CONFIG_USB_PWC) += pwc.o
 
index 42352f531bc0a8debe64ac3de12b632bcd70d06b..53099190952ce022338b7fad0df8c82c941bcbcd 100644 (file)
@@ -48,8 +48,6 @@
 #include "pwc-uncompress.h"
 #include "pwc-kiara.h"
 #include "pwc-timon.h"
-#include "pwc-dec1.h"
-#include "pwc-dec23.h"
 
 /* Request types: video */
 #define SET_LUM_CTL                    0x01
@@ -246,7 +244,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
           switch(pdev->type) {
             case 645:
             case 646:
-              pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data);
+/*            pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
               break;
 
             case 675:
@@ -256,7 +254,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
             case 730:
             case 740:
             case 750:
-              pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data);
+/*            pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
               break;
           }
        }
@@ -318,8 +316,8 @@ static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int fr
        if (ret < 0)
                return ret;
 
-       if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
-          pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data);
+/*     if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
+          pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
 
        pdev->cmd_len = 13;
        memcpy(pdev->cmd_buf, buf, 13);
@@ -397,8 +395,8 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
        if (ret < 0)
                return ret;
 
-       if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
-         pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data);
+/*     if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
+         pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */
 
        pdev->cmd_len = 12;
        memcpy(pdev->cmd_buf, buf, 12);
@@ -1100,7 +1098,7 @@ static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
        unsigned char buf[4];
        
        /* set new relative angle; angles are expressed in degrees * 100,
-          but cam as .5 degree resolution, hence devide by 200. Also
+          but cam as .5 degree resolution, hence divide by 200. Also
           the angle must be multiplied by 64 before it's send to
           the cam (??)
         */
diff --git a/drivers/usb/media/pwc/pwc-dec1.c b/drivers/usb/media/pwc/pwc-dec1.c
deleted file mode 100644 (file)
index 57d03d9..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Linux driver for Philips webcam
-   Decompression for chipset version 1
-   (C) 2004      Luc Saillard (luc@saillard.org)
-
-   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
-   driver and thus may have bugs that are not present in the original version.
-   Please send bug reports and support requests to <luc@saillard.org>.
-   The decompression routines have been implemented by reverse-engineering the
-   Nemosoft binary pwcx module. Caveat emptor.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You 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 "pwc-dec1.h"
-
-
-void pwc_dec1_init(int type, int release, void *buffer, void *table)
-{
-
-}
-
-void pwc_dec1_exit(void)
-{
-
-
-
-}
-
diff --git a/drivers/usb/media/pwc/pwc-dec1.h b/drivers/usb/media/pwc/pwc-dec1.h
deleted file mode 100644 (file)
index a7ffd9c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Linux driver for Philips webcam
-   (C) 2004      Luc Saillard (luc@saillard.org)
-
-   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
-   driver and thus may have bugs that are not present in the original version.
-   Please send bug reports and support requests to <luc@saillard.org>.
-   The decompression routines have been implemented by reverse-engineering the
-   Nemosoft binary pwcx module. Caveat emptor.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You 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 PWC_DEC1_H
-#define PWC_DEC1_H
-
-void pwc_dec1_init(int type, int release, void *buffer, void *private_data);
-void pwc_dec1_exit(void);
-
-#endif
-
-
-
diff --git a/drivers/usb/media/pwc/pwc-dec23.c b/drivers/usb/media/pwc/pwc-dec23.c
deleted file mode 100644 (file)
index 98fa3f7..0000000
+++ /dev/null
@@ -1,623 +0,0 @@
-/* Linux driver for Philips webcam
-   Decompression for chipset version 2 et 3
-   (C) 2004      Luc Saillard (luc@saillard.org)
-
-   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
-   driver and thus may have bugs that are not present in the original version.
-   Please send bug reports and support requests to <luc@saillard.org>.
-   The decompression routines have been implemented by reverse-engineering the
-   Nemosoft binary pwcx module. Caveat emptor.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You 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 "pwc-timon.h"
-#include "pwc-kiara.h"
-#include "pwc-dec23.h"
-#include "pwc-ioctl.h"
-
-#include <linux/string.h>
-
-/****
- *
- *
- *
- */
-
-
-static void fill_table_a000(unsigned int *p)
-{
-  static unsigned int initial_values[12] = {
-     0xFFAD9B00, 0xFFDDEE00, 0x00221200, 0x00526500,
-     0xFFC21E00, 0x003DE200, 0xFF924B80, 0xFFD2A300,
-     0x002D5D00, 0x006DB480, 0xFFED3E00, 0x0012C200
-  };
-  static unsigned int values_derivated[12] = {
-     0x0000A4CA, 0x00004424, 0xFFFFBBDC, 0xFFFF5B36,
-     0x00007BC4, 0xFFFF843C, 0x0000DB69, 0x00005ABA,
-     0xFFFFA546, 0xFFFF2497, 0x00002584, 0xFFFFDA7C
-  };
-  unsigned int temp_values[12];
-  int i,j;
-
-  memcpy(temp_values,initial_values,sizeof(initial_values));
-  for (i=0;i<256;i++)
-   {
-     for (j=0;j<12;j++)
-      {
-       *p++ = temp_values[j];
-       temp_values[j] += values_derivated[j];
-      }
-   }
-}
-
-static void fill_table_d000(unsigned char *p)
-{
-  int bit,byte;
-
-  for (bit=0; bit<8; bit++)
-   {
-     unsigned char bitpower = 1<<bit;
-     unsigned char mask = bitpower-1;
-     for (byte=0; byte<256; byte++)
-      {
-       if (byte & bitpower)
-         *p++ = -(byte & mask);
-       else
-         *p++ = (byte & mask);
-      }
-   }
-}
-
-/*
- *
- * Kiara: 0 <= ver <= 7
- * Timon: 0 <= ver <= 15
- *
- */
-static void fill_table_color(unsigned int version, const unsigned int *romtable, 
-    unsigned char *p0004, 
-    unsigned char *p8004)
-{
-  const unsigned int *table;
-  unsigned char *p0, *p8;
-  int i,j,k;
-  int dl,bit,pw;
-
-  romtable += version*256;
-
-  for (i=0; i<2; i++)
-   {
-     table = romtable + i*128;
-
-     for (dl=0; dl<16; dl++)
-      {
-       p0 = p0004 + (i<<14) + (dl<<10);
-       p8 = p8004 + (i<<12) + (dl<<8);
-
-       for (j=0; j<8; j++ , table++, p0+=128)
-        {
-          for (k=0; k<16; k++)
-           {
-             if (k==0)
-               bit=1;
-             else if (k>=1 && k<3)
-               bit=(table[0]>>15)&7;
-             else if (k>=3 && k<6)
-               bit=(table[0]>>12)&7;
-             else if (k>=6 && k<10)
-               bit=(table[0]>>9)&7;
-             else if (k>=10 && k<13)
-               bit=(table[0]>>6)&7;
-             else if (k>=13 && k<15)
-               bit=(table[0]>>3)&7;
-             else
-               bit=(table[0])&7;
-             if (k == 0)
-               *(unsigned char *)p8++ = 8;
-             else
-               *(unsigned char *)p8++ = j - bit;
-             *(unsigned char *)p8++ = bit;
-
-             pw = 1<<bit;
-             p0[k+0x00] = (1*pw)  + 0x80;
-             p0[k+0x10] = (2*pw)  + 0x80;
-             p0[k+0x20] = (3*pw)  + 0x80;
-             p0[k+0x30] = (4*pw)  + 0x80;
-             p0[k+0x40] = (-pw)   + 0x80;
-             p0[k+0x50] = (2*-pw) + 0x80;
-             p0[k+0x60] = (3*-pw) + 0x80;
-             p0[k+0x70] = (4*-pw) + 0x80;
-           } /* end of for (k=0; k<16; k++, p8++) */
-        } /* end of for (j=0; j<8; j++ , table++) */
-      } /* end of for (dl=0; dl<16; dl++) */
-   } /* end of for (i=0; i<2; i++) */
-}
-
-/*
- * precision = (pdev->xx + pdev->yy)
- *
- */
-static void fill_table_dc00_d800(unsigned int precision, unsigned int *pdc00, unsigned int *pd800)
-{
-  int i;
-  unsigned int offset1, offset2;
-  for(i=0,offset1=0x4000, offset2=0; i<256 ; i++,offset1+=0x7BC4, offset2+=0x7BC4)
-   {
-     unsigned int msb = offset1 >> 15;
-
-     if ( msb > 255)
-      {
-       if (msb)
-         msb=0;
-       else
-         msb=255;
-      }
-
-     *pdc00++ = msb << precision;
-     *pd800++ = offset2;
-   }
-
-}
-
-/*
- * struct {
- *   unsigned char op;     // operation to execute
- *   unsigned char bits;    // bits use to perform operation
- *   unsigned char offset1; // offset to add to access in the table_0004 % 16
- *   unsigned char offset2; // offset to add to access in the table_0004
- * }
- *
- */
-static unsigned int table_ops[] = {
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x30,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x10,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x70,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x50,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40,
-0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00
-};
-
-/*
- * TODO: multiply by 4 all values
- *
- */
-static unsigned int MulIdx[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
- 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
- 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,
- 6, 7, 8, 9, 7,10,11, 8, 8,11,10, 7, 9, 8, 7, 6,
- 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,
- 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,
- 0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,
- 0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,
- 1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,
- 7,10,11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8,11,10, 7,
- 4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,
- 7, 9, 6, 8,10, 8, 7,11,11, 7, 8,10, 8, 6, 9, 7,
- 1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,
- 1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,
-10, 8, 7,11, 8, 6, 9, 7, 7, 9, 6, 8,11, 7, 8,10
-};
-
-
-
-void pwc_dec23_init(int type, int release, unsigned char *mode, void *data)
-{
-  int flags;
-  struct pwc_dec23_private *pdev = data;
-  release = release;
-
-  switch (type)
-   {
-    case 720:
-    case 730:
-    case 740:
-    case 750:
-      flags = mode[2]&0x18;    /* our: flags = 8, mode[2]==e8 */
-      if (flags==8)
-       pdev->zz = 7;
-      else if (flags==0x10)
-       pdev->zz = 8;
-      else
-       pdev->zz = 6;
-      flags = mode[2]>>5;      /* our: 7 */
-
-      fill_table_color(flags, (unsigned int *)KiaraRomTable, pdev->table_0004, pdev->table_8004);
-      break;
-
-
-    case 675:
-    case 680:
-    case 690:
-      flags = mode[2]&6;
-      if (flags==2)
-       pdev->zz = 7;
-      else if (flags==4)
-       pdev->zz = 8;
-      else
-       pdev->zz = 6;
-      flags = mode[2]>>3;
-
-      fill_table_color(flags, (unsigned int *)TimonRomTable, pdev->table_0004, pdev->table_8004);
-      break;
-
-    default:
-      /* Not supported */
-      return;
-   }
-
-  /* * * * ** */
-  pdev->xx = 8 - pdev->zz;
-  pdev->yy = 15 - pdev->xx;
-  pdev->zzmask = 0xFF>>pdev->xx;
-  //pdev->zzmask = (1U<<pdev->zz)-1;
-
-
-  fill_table_dc00_d800(pdev->xx + pdev->yy, pdev->table_dc00, pdev->table_d800);
-  fill_table_a000(pdev->table_a004);
-  fill_table_d000(pdev->table_d004);
-}
-
-
-/*
- * To manage the stream, we keep in a 32 bits variables,
- * the next bits in the stream. fill_reservoir() add to
- * the reservoir at least wanted nbits.
- *
- *
- */
-#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
-   while (nbits_in_reservoir<nbits_wanted) \
-    { \
-      reservoir |= (*(stream)++) << nbits_in_reservoir; \
-      nbits_in_reservoir+=8; \
-    } \
-}  while(0);
-
-#define get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \
-   fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted); \
-   result = (reservoir) & ((1U<<nbits_wanted)-1); \
-   reservoir >>= nbits_wanted; \
-   nbits_in_reservoir -= nbits_wanted; \
-}  while(0);
-
-
-
-static void DecompressBand23(const struct pwc_dec23_private *pdev,
-                             const unsigned char *rawyuv,
-                            unsigned char *planar_y,
-                            unsigned char *planar_u,
-                            unsigned char *planar_v,
-                            unsigned int image_x,              /* aka number of pixels wanted ??? */
-                            unsigned int pixels_per_line,      /* aka number of pixels per line */
-                            int flags)
-{
-
-
-  unsigned int reservoir, nbits_in_reservoir;
-  int first_4_bits;
-  unsigned int bytes_per_channel;
-  int line_size;       /* size of the line (4Y+U+V) */
-  int passes;
-  const unsigned char *ptable0004, *ptable8004;
-
-  int even_line;
-  unsigned int temp_colors[16];
-  int nblocks;
-
-  const unsigned char *stream;
-  unsigned char *dest_y, *dest_u=NULL, *dest_v=NULL;
-  unsigned int offset_to_plane_u, offset_to_plane_v;
-
-  int i;
-
-
-  reservoir = 0;
-  nbits_in_reservoir = 0;
-  stream = rawyuv+1;   /* The first byte of the stream is skipped */
-  even_line = 1;
-
-  get_nbits(reservoir,nbits_in_reservoir,stream,4,first_4_bits);
-
-  line_size = pixels_per_line*3;
-
-  for (passes=0;passes<2;passes++)
-   {
-     if (passes==0)
-      {
-       bytes_per_channel = pixels_per_line;
-       dest_y = planar_y;
-       nblocks = image_x/4;
-      }
-     else
-      {
-       /* Format planar: All Y, then all U, then all V */
-       bytes_per_channel = pixels_per_line/2;
-       dest_u = planar_u;
-       dest_v = planar_v;
-       dest_y = dest_u;
-       nblocks = image_x/8;
-      }
-
-     offset_to_plane_u = bytes_per_channel*2;
-     offset_to_plane_v = bytes_per_channel*3;
-     /*
-     printf("bytes_per_channel = %d\n",bytes_per_channel);
-     printf("offset_to_plane_u = %d\n",offset_to_plane_u);
-     printf("offset_to_plane_v = %d\n",offset_to_plane_v);
-     */
-
-     while (nblocks-->0)
-      {
-       unsigned int gray_index;
-
-       fill_nbits(reservoir,nbits_in_reservoir,stream,16);
-       gray_index = reservoir & pdev->zzmask;
-       reservoir >>= pdev->zz;
-       nbits_in_reservoir -= pdev->zz;
-
-       fill_nbits(reservoir,nbits_in_reservoir,stream,2);
-
-       if ( (reservoir & 3) == 0)
-        {
-          reservoir>>=2;
-          nbits_in_reservoir-=2;
-          for (i=0;i<16;i++)
-            temp_colors[i] = pdev->table_dc00[gray_index];
-
-        }
-       else
-        {
-          unsigned int channel_v, offset1;
-
-          /* swap bit 0 and 2 of offset_OR */
-          channel_v = ((reservoir & 1) << 2) | (reservoir & 2) | ((reservoir & 4)>>2);
-          reservoir>>=3;
-          nbits_in_reservoir-=3;
-
-          for (i=0;i<16;i++)
-            temp_colors[i] = pdev->table_d800[gray_index];
-
-          ptable0004 = pdev->table_0004 + (passes*16384) + (first_4_bits*1024) + (channel_v*128);
-          ptable8004 = pdev->table_8004 + (passes*4096)  + (first_4_bits*256)  + (channel_v*32);
-
-          offset1 = 0;
-          while(1) 
-           {
-             unsigned int index_in_table_ops, op, rows=0;
-             fill_nbits(reservoir,nbits_in_reservoir,stream,16);
-
-             /* mode is 0,1 or 2 */
-             index_in_table_ops = (reservoir&0x3F);
-             op = table_ops[ index_in_table_ops*4 ];
-             if (op == 2)
-              {
-                reservoir >>= 2;
-                nbits_in_reservoir -= 2;
-                break; /* exit the while(1) */
-              }
-             if (op == 0)
-              {
-                unsigned int shift;
-
-                offset1 = (offset1 + table_ops[index_in_table_ops*4+2]) & 0x0F;
-                shift = table_ops[ index_in_table_ops*4+1 ];
-                reservoir >>= shift;
-                nbits_in_reservoir -= shift;
-                rows = ptable0004[ offset1 + table_ops[index_in_table_ops*4+3] ];
-              }
-             if (op == 1)
-              {
-                 /* 10bits [ xxxx xxxx yyyy 000 ]
-                  * yyy => offset in the table8004
-                  * xxx => offset in the tabled004
-                  */
-                unsigned int mask, shift;
-                unsigned int col1, row1, total_bits;
-
-                offset1 = (offset1 + ((reservoir>>3)&0x0F)+1) & 0x0F;
-
-                col1 = (reservoir>>7) & 0xFF;
-                row1 = ptable8004 [ offset1*2 ];
-
-                /* Bit mask table */
-                mask = pdev->table_d004[ (row1<<8) + col1 ];
-                shift = ptable8004 [ offset1*2 + 1];
-                rows = ((mask << shift) + 0x80) & 0xFF;
-
-                total_bits = row1 + 8;
-                reservoir >>= total_bits;
-                nbits_in_reservoir -= total_bits;
-              }
-              {
-                const unsigned int *table_a004 = pdev->table_a004 + rows*12;
-                unsigned int *poffset = MulIdx + offset1*16;   /* 64/4 (int) */
-                for (i=0;i<16;i++)
-                 {
-                   temp_colors[i] += table_a004[ *poffset ];
-                   poffset++;
-                 }
-              }
-          }
-        }
-#define USE_SIGNED_INT_FOR_COLOR
-#ifdef USE_SIGNED_INT_FOR_COLOR
-#  define CLAMP(x) ((x)>255?255:((x)<0?0:x))
-#else
-#  define CLAMP(x) ((x)>255?255:x)
-#endif
-
-       if (passes == 0)
-        {
-#ifdef USE_SIGNED_INT_FOR_COLOR
-          const int *c = temp_colors;
-#else
-          const unsigned int *c = temp_colors;
-#endif
-          unsigned char *d;
-
-          d = dest_y;
-          for (i=0;i<4;i++,c++)
-            *d++ = CLAMP((*c) >> pdev->yy);
-
-          d = dest_y + bytes_per_channel;
-          for (i=0;i<4;i++,c++)
-            *d++ = CLAMP((*c) >> pdev->yy);
-
-          d = dest_y + offset_to_plane_u;
-          for (i=0;i<4;i++,c++)
-            *d++ = CLAMP((*c) >> pdev->yy);
-
-          d = dest_y + offset_to_plane_v;
-          for (i=0;i<4;i++,c++)
-            *d++ = CLAMP((*c) >> pdev->yy);
-
-          dest_y += 4;
-        }
-       else if (passes == 1)
-        {
-#ifdef USE_SIGNED_INT_FOR_COLOR
-          int *c1 = temp_colors;
-          int *c2 = temp_colors+4;
-#else
-          unsigned int *c1 = temp_colors;
-          unsigned int *c2 = temp_colors+4;
-#endif
-          unsigned char *d;
-
-          d = dest_y;
-          for (i=0;i<4;i++,c1++,c2++)
-           {
-             *d++ = CLAMP((*c1) >> pdev->yy);
-             *d++ = CLAMP((*c2) >> pdev->yy);
-           }
-          c1 = temp_colors+12;
-          //c2 = temp_colors+8;
-          d = dest_y + bytes_per_channel;
-          for (i=0;i<4;i++,c1++,c2++)
-           {
-             *d++ = CLAMP((*c1) >> pdev->yy);
-             *d++ = CLAMP((*c2) >> pdev->yy);
-           }
-
-          if (even_line)       /* Each line, swap u/v */
-           {
-             even_line=0;
-             dest_y = dest_v;
-             dest_u += 8;
-           }
-          else
-           {
-             even_line=1;
-             dest_y = dest_u;
-             dest_v += 8;
-           }
-        }
-
-      } /* end of while (nblocks-->0) */
-
-   } /* end of for (passes=0;passes<2;passes++) */
-
-}
-
-
-/**
- *
- * image: size of the image wanted
- * view : size of the image returned by the camera
- * offset: (x,y) to displayer image in the view
- *
- * src: raw data
- * dst: image output
- * flags: PWCX_FLAG_PLANAR
- * pdev: private buffer
- * bandlength:
- *
- */
-void pwc_dec23_decompress(const struct pwc_coord *image,
-                            const struct pwc_coord *view,
-                           const struct pwc_coord *offset,
-                           const void *src,
-                           void *dst,
-                           int flags,
-                           const void *data,
-                           int bandlength)
-{
-  const struct pwc_dec23_private *pdev = data;
-  unsigned char *pout, *pout_planar_y=NULL, *pout_planar_u=NULL, *pout_planar_v=NULL;
-  int i,n,stride,pixel_size;
-
-
-  if (flags & PWCX_FLAG_BAYER)
-   {
-     pout = dst + (view->x * offset->y) + offset->x;
-     pixel_size = view->x * 4;
-   }
-  else
-   {
-     n = view->x * view->y;
-
-     /* offset in Y plane */
-     stride = view->x * offset->y;
-     pout_planar_y = dst + stride + offset->x;
-
-     /* offsets in U/V planes */
-     stride = (view->x * offset->y)/4 + offset->x/2;
-     pout_planar_u = dst + n +     + stride;
-     pout_planar_v = dst + n + n/4 + stride;
-
-     pixel_size = view->x * 4;
-   }
-
-
-  for (i=0;i<image->y;i+=4)
-   {
-     if (flags & PWCX_FLAG_BAYER)
-      {
-       //TODO:
-       //DecompressBandBayer(pdev,src,pout,image.x,view->x,flags);
-       src += bandlength;
-       pout += pixel_size;
-      }
-     else
-      {
-       DecompressBand23(pdev,src,pout_planar_y,pout_planar_u,pout_planar_v,image->x,view->x,flags);
-       src += bandlength;
-       pout_planar_y += pixel_size;
-       pout_planar_u += view->x;
-       pout_planar_v += view->x;
-      }
-   }
-}
-
-void pwc_dec23_exit(void)
-{
-  /* Do nothing */
-
-}
-
diff --git a/drivers/usb/media/pwc/pwc-dec23.h b/drivers/usb/media/pwc/pwc-dec23.h
deleted file mode 100644 (file)
index 5b2aacd..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Linux driver for Philips webcam
-   (C) 2004      Luc Saillard (luc@saillard.org)
-
-   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
-   driver and thus may have bugs that are not present in the original version.
-   Please send bug reports and support requests to <luc@saillard.org>.
-   The decompression routines have been implemented by reverse-engineering the
-   Nemosoft binary pwcx module. Caveat emptor.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You 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 PWC_DEC23_H
-#define PWC_DEC23_H
-
-struct pwc_dec23_private
-{
-  unsigned char xx,yy,zz,zzmask;
-
-  unsigned char table_0004[2*0x4000];
-  unsigned char table_8004[2*0x1000];
-  unsigned int  table_a004[256*12];
-
-  unsigned char table_d004[8*256];
-  unsigned int  table_d800[256];
-  unsigned int  table_dc00[256];
-};
-
-
-void pwc_dec23_init(int type, int release, unsigned char *buffer, void *private_data);
-void pwc_dec23_exit(void);
-void pwc_dec23_decompress(const struct pwc_coord *image,
-                            const struct pwc_coord *view,
-                           const struct pwc_coord *offset,
-                           const void *src,
-                           void *dst,
-                           int flags,
-                           const void *data,
-                           int bandlength);
-
-
-
-#endif
-
-
-
index c53e2263b7fbe09c3f70adeee1631b7adcf30dd9..b77e65c03659a0bdffda1a758f7ef04beb44201d 100644 (file)
@@ -68,8 +68,6 @@
 #include "pwc-ioctl.h"
 #include "pwc-kiara.h"
 #include "pwc-timon.h"
-#include "pwc-dec23.h"
-#include "pwc-dec1.h"
 #include "pwc-uncompress.h"
 
 /* Function prototypes and driver templates */
@@ -272,7 +270,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
                return -ENXIO;
        }
 #endif 
-       /* Allocate Isochronuous pipe buffers */
+       /* Allocate Isochronous pipe buffers */
        for (i = 0; i < MAX_ISO_BUFS; i++) {
                if (pdev->sbuf[i].data == NULL) {
                        kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
@@ -322,6 +320,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
          case 730:
          case 740:
          case 750:
+#if 0    
            Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private));
            kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);       /* Timon & Kiara */
            break;
@@ -330,11 +329,9 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
            /* TODO & FIXME */
            kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
            break;
+#endif  
+       ;
         }
-       if (kbuf == NULL) {
-          Err("Failed to allocate decompress table.\n");
-          return -ENOMEM;
-       }
        pdev->decompress_data = kbuf;
        
        /* Allocate image buffer; double buffer for mmap() */
@@ -850,7 +847,7 @@ static int pwc_isoc_init(struct pwc_device *pdev)
        
        if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
                Err("Failed to find packet size for video endpoint in current alternate setting.\n");
-               return -ENFILE; /* Odd error, that should be noticable */
+               return -ENFILE; /* Odd error, that should be noticeable */
        }
 
        /* Set alternate interface */
@@ -1131,11 +1128,11 @@ static int pwc_video_close(struct inode *inode, struct file *file)
          case 730:
          case 740:
          case 750:
-           pwc_dec23_exit();   /* Timon & Kiara */
+/*         pwc_dec23_exit();   *//* Timon & Kiara */
            break;
          case 645:
          case 646:
-           pwc_dec1_exit();
+/*         pwc_dec1_exit(); */
            break;
         }
 
@@ -2128,7 +2125,7 @@ static int __init usb_pwc_init(void)
        if (leds[1] >= 0)
                led_off = leds[1];
 
-       /* Big device node whoopla. Basicly, it allows you to assign a
+       /* Big device node whoopla. Basically, it allows you to assign a
           device node (/dev/videoX) to a camera, based on its type
           & serial number. The format is [type[.serialnumber]:]node.
 
index 65805eaa9a1c879bbd01648b680dc80476594d4e..5f9cb08bc02e5de6d578f9f150742f99622aa184 100644 (file)
@@ -75,7 +75,7 @@
 #define PWC_FPS_SNAPSHOT       0x00400000
 
 
-/* structure for transfering x & y coordinates */
+/* structure for transferring x & y coordinates */
 struct pwc_coord
 {
        int x, y;               /* guess what */
index 5485800efd833e9bdd0d6b7603e9ae7b64912854..c498c68bace198f7d7469f26dc187337ddd3edb2 100644 (file)
@@ -316,576 +316,3 @@ const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
    },
 };
 
-
-/*
- * Rom table for kiara chips
- *
- * 32 roms tables (one for each resolution ?)
- *  2 tables per roms (one for each passes) (Y, and U&V)
- * 128 bytes per passes
- */
-
-const unsigned int KiaraRomTable [8][2][16][8] =  
-{
- { /* version 0 */
-  { /* version 0, passes 0 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000001,0x00000001},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000009,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000009,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000249,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000249,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x00000249,0x0000124a,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x0000124a,0x00009252,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00009252,0x00009292,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009292,0x00009292,0x00009493,0x000124db},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009492,0x0000a49b,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x0000a493,0x000124db,0x000124db,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x000124db,0x000126dc,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000124db,0x000136e4,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 0, passes 1 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000001,0x00000009,
-    0x00000009,0x00000009,0x00000009,0x00000001},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000249,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00001252},
-   {0x00000000,0x00000000,0x00000049,0x00001249,
-    0x0000124a,0x0000124a,0x00001252,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009252,0x00009292,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009292,0x00009292,0x00009292,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x00009292,
-    0x00009492,0x00009493,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x000124db,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00009252,0x00009493,
-    0x000126dc,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000136e4,0x000136e4,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 1 */
-  { /* version 1, passes 0 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000001},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000009,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00001252},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x0000124a,0x00009252,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009292,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009252,0x00009493,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009292,0x00009493,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x00009252,
-    0x00009492,0x00009493,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x000124db,0x000124db,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000126dc,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 1, passes 1 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000049,0x00000009,
-    0x00000049,0x00000009,0x00000001,0x00000000},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000000},
-   {0x00000000,0x00000000,0x00000249,0x00000049,
-    0x00000249,0x00000049,0x0000024a,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x0000024a,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x0000024a,0x00000009},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00009252,0x00001252,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00009292,0x00001252,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00009292,0x00001252,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009292,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x0000924a,0x0000924a,
-    0x00009492,0x00009493,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 2 */
-  { /* version 2, passes 0 */
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x00001252,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x00009252,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x0000124a,0x00009292,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009493,0x00009493,0x0000a49b},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009292,0x00009493,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009292,0x00009493,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x0000a49b,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x000124db,0x000124db,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x000124db,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0001249b,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000136e4,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x00009252,0x000124db,
-    0x000126dc,0x0001b724,0x0001b725,0x0001b925},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 2, passes 1 */
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00000249,
-    0x0000124a,0x0000124a,0x00001252,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00009292,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x0000a49b,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x0000a49b,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x0000a49b,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x0000a49b,0x0000a49b,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x00009252,0x0000a49b,
-    0x0001249b,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 3 */
-  { /* version 3, passes 0 */
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x0000a49b,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x000124db,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0001249b,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000136e4,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000136e4,0x0001b725,0x0001b925},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 3, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00000249,
-    0x0000124a,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x00009493,0x0000a49b,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x000126dc,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00009492,0x0000a49b,
-    0x000136e4,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001b724,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 4 */
-  { /* version 4, passes 0 */
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000249,0x00000049,
-    0x00000249,0x00000249,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x00009252,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009493,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009292,0x00009493,0x00009493,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0001249b,0x000126dc,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00009252,0x00009493,
-    0x000124db,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009252,0x0000a49b,
-    0x000124db,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 4, passes 1 */
-   {0x00000000,0x00000000,0x00000249,0x00000049,
-    0x00000009,0x00000009,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000049,0x00000049,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00000249,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x0000124a,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009252,0x0000124a,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x00009252,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x00009292,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x00009292,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x00009493,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009252,0x000124db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 5 */
-  { /* version 5, passes 0 */
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b725,0x000136e4},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 5, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009252,0x00009252,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000124db,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000124db,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000126dc,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009292,0x000124db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 6 */
-  { /* version 6, passes 0 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b725,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
-   {0x00000000,0x00000000,0x00012492,0x000126db,
-    0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 6, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x00009252,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x00009292,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x0000a49b,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000124db,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001c924,0x0001b724,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 7 */
-  { /* version 7, passes 0 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x0000a49b,
-    0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x0001b725,0x000124db},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b725,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x000124db,
-    0x000136e4,0x0001b724,0x0001b725,0x000126dc},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
-   {0x00000000,0x00000000,0x00012492,0x000136db,
-    0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 7, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x00009492,0x00009292,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x0000a49b,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000124db,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000136db,
-    0x0001b724,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000136db,
-    0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00009292,0x000136db,
-    0x0001b724,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009492,0x000136db,
-    0x0001b724,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00012492,0x0001b6db,
-    0x0001c924,0x0001b724,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- }
-};
-
index f950a4e5ed96d47764fbbd28cc15e74a60786b96..dee967173d6c0856f239e1c3e8f1243919a32c14 100644 (file)
@@ -314,1133 +314,3 @@ const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
    },
 };
 
-/*
- * 16 versions:
- *   2 tables  (one for Y, and one for U&V)
- *   16 levels of details per tables
- *   8 blocs
- */
-
-const unsigned int TimonRomTable [16][2][16][8] =  
-{
- { /* version 0 */
-  { /* version 0, passes 0 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000001},
-   {0x00000000,0x00000000,0x00000001,0x00000001,
-    0x00000001,0x00000001,0x00000001,0x00000001},
-   {0x00000000,0x00000000,0x00000001,0x00000001,
-    0x00000001,0x00000009,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000009,0x00000001,
-    0x00000009,0x00000009,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000009,0x00000049,0x00000009},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000009,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000249,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000249,0x00000249,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000249,0x0000124a,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x00000249,0x0000124a,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x0000124a,0x00009252,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 0, passes 1 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000001,0x00000001,
-    0x00000001,0x00000001,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000009,0x00000001,
-    0x00000001,0x00000009,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000009,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000009,0x00000001,0x00000000},
-   {0x00000000,0x00000000,0x00000049,0x00000009,
-    0x00000009,0x00000049,0x00000001,0x00000001},
-   {0x00000000,0x00000000,0x00000049,0x00000009,
-    0x00000009,0x00000049,0x00000001,0x00000001},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000009,0x00000001},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000009,0x00000001},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000009,0x00000001},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000249,0x00000049,0x00000009},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000249,0x00000049,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000049,
-    0x00000249,0x00000249,0x00000049,0x00000009},
-   {0x00000000,0x00000000,0x00001249,0x00000249,
-    0x0000124a,0x0000124a,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 1 */
-  { /* version 1, passes 0 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000001},
-   {0x00000000,0x00000000,0x00000001,0x00000001,
-    0x00000001,0x00000009,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000009,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000009,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000249,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00001252},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x00000249,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x0000124a,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x0000124a,0x00009252,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009252,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009292,0x00009493,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 1, passes 1 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000001,0x00000001,0x00000000},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000009,0x00000001,0x00000000},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000009,0x00000001,0x00000000},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000001,0x00000001},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000009,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000049,
-    0x00000049,0x00000249,0x00000009,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000049,
-    0x00000249,0x00000249,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x00000049,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x00000049,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x00000049,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009252,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 2 */
-  { /* version 2, passes 0 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000001},
-   {0x00000000,0x00000000,0x00000009,0x00000009,
-    0x00000009,0x00000009,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00001252},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x0000124a,0x00009252,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009292,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009252,0x00009493,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009292,0x00009493,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x00009252,
-    0x00009492,0x00009493,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x000124db,0x000124db,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000126dc,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 2, passes 1 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000049,0x00000009,
-    0x00000049,0x00000009,0x00000001,0x00000000},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000000},
-   {0x00000000,0x00000000,0x00000249,0x00000049,
-    0x00000249,0x00000049,0x0000024a,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x0000024a,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x0000024a,0x00000009},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00009252,0x00001252,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00009292,0x00001252,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00009292,0x00001252,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009292,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x0000924a,0x0000924a,
-    0x00009492,0x00009493,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 3 */
-  { /* version 3, passes 0 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000001},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000049,0x00000249,
-    0x00000249,0x00000249,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x00009252,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x0000124a,0x00009292,0x00009292,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009292,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009292,0x00009493,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x00009252,
-    0x00009292,0x00009493,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009292,0x0000a49b,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x0000a49b,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x000124db,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x0000a49b,0x000124db,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0001249b,0x000126dc,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000136e4,0x0001b725,0x000136e4},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 3, passes 1 */
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000},
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000001,0x00000000},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x00000049,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x00001252,0x00000001},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x00001252,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x0000124a,0x00009252,0x00009292,0x00000009},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00009252,0x00009292,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009252,0x00009292,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009493,0x00009292,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009493,0x00009292,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009493,0x00009493,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009292,0x00009493,0x00009493,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x00009493,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x0000a49b,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x00009292,
-    0x0000a493,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 4 */
-  { /* version 4, passes 0 */
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x00001252,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x00009252,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x0000124a,0x00009292,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009493,0x00009493,0x0000a49b},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009292,0x00009493,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009292,0x00009493,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x0000a49b,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x000124db,0x000124db,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x000124db,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0001249b,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000136e4,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x00009252,0x000124db,
-    0x000126dc,0x0001b724,0x0001b725,0x0001b925},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 4, passes 1 */
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00000249,
-    0x0000124a,0x0000124a,0x00001252,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00009292,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x0000a49b,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x0000a49b,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x0000a49b,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x0000a49b,0x0000a49b,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x00009252,0x0000a49b,
-    0x0001249b,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 5 */
-  { /* version 5, passes 0 */
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x0000124a,0x00001252,0x00009292},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x0000124a,0x00009292,0x00009292,0x00009493},
-   {0x00000000,0x00000000,0x00000249,0x0000924a,
-    0x00009292,0x00009493,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009292,0x00009493,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x0000a49b,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x000124db,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x000124db,0x000124db,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0001249b,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0001249b,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0001249b,0x000126dc,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000126dc,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b724,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 5, passes 1 */
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x00009493,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x00009493,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x0000a49b,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x00009493,0x000124db,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x00009493,0x000124db,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x000124db,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x000124db,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009252,0x000124db,
-    0x000126dc,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 6 */
-  { /* version 6, passes 0 */
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x0000124a,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x0000a49b,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x000124db,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0001249b,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000136e4,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000136e4,0x0001b725,0x0001b925},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x000136e4,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x000136e4,0x0001b925,0x00025bb6,0x00024b77},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 6, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00000249,
-    0x0000124a,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x00009493,0x0000a49b,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x000126dc,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00009492,0x0000a49b,
-    0x000136e4,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001b724,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 7 */
-  { /* version 7, passes 0 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x0000a49b,0x000124db,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0001249b,0x000126dc,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000136e4,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x0001b725,0x0001b925},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x00009292,0x000124db,
-    0x000126dc,0x0001b724,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b724,0x0001c96e,0x0002496e},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x000136e4,0x0001b925,0x0001c96e,0x0002496e},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x0002496d,0x00025bb6,0x00025bbf},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 7, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x00009493,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x000124db,0x000136e4,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x000124db,0x000136e4,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000124db,0x000136e4,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x000136e4,0x0001b724,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00012492,0x000126db,
-    0x0001b724,0x0001b925,0x0001b725,0x000136e4},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 8 */
-  { /* version 8, passes 0 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009292,0x00009493,0x0000a49b,0x000124db},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x000124db,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x000136e4},
-   {0x00000000,0x00000000,0x00001249,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000136e4,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x0001b725,0x0001b925},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
-   {0x00000000,0x00000000,0x00009252,0x000124db,
-    0x000126dc,0x0001b724,0x0001b92d,0x0001c92d},
-   {0x00000000,0x00000000,0x00009292,0x000124db,
-    0x000126dc,0x0001b925,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b925,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b925,0x00024b76,0x00024b77},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x000136e4,0x0001b925,0x00024b76,0x00025bbf},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x000136e4,0x0001c92d,0x00024b76,0x00025bbf},
-   {0x00000000,0x00000000,0x00012492,0x000136db,
-    0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 8, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009493,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x000124db,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000126dc,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000136e4,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00009292,0x000124db,
-    0x000136e4,0x0001b724,0x0001b725,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x000136e4,0x0001b925,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x000136e4,0x0001b925,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x0002496d,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 9 */
-  { /* version 9, passes 0 */
-   {0x00000000,0x00000000,0x00000049,0x00000049,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00000249,0x00000049,
-    0x00000249,0x00000249,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x0000124a,0x00009252,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009493,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009292,0x00009493,0x00009493,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0001249b,0x000126dc,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00009252,0x00009493,
-    0x000124db,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009252,0x0000a49b,
-    0x000124db,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 9, passes 1 */
-   {0x00000000,0x00000000,0x00000249,0x00000049,
-    0x00000009,0x00000009,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000049,0x00000049,0x00000009,0x00000009},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00000249,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x0000124a,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009252,0x0000124a,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x00009252,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x00009292,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x00009292,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x00009493,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000124db,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009252,0x000124db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 10 */
-  { /* version 10, passes 0 */
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00000249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x00009493,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x000124db,0x000124db,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0001249b,0x000126dc,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000126dc,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009252,0x0000a49b,
-    0x000124db,0x000136e4,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b92d,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000126dc,0x0001b925,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x000136e4,0x0002496d,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 10, passes 1 */
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000049,0x00000049,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00000249,0x00000049,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x00009252,0x0000024a,0x00000049},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009493,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00009252,
-    0x00009492,0x00009493,0x00001252,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x00009493,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x00009492,0x00009493,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x00009493,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009252,0x000126db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 11 */
-  { /* version 11, passes 0 */
-   {0x00000000,0x00000000,0x00000249,0x00000249,
-    0x00000249,0x00000249,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009492,0x0000a49b,0x0000a49b,0x00009292},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x000124db,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b725,0x000136e4},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b925,0x0001c96e,0x0001b925},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 11, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00000249,
-    0x00000249,0x00000249,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009252,0x00009252,0x0000024a,0x0000024a},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x0000a49b,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x0000a49b,0x00009292,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000124db,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000124db,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000126dc,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009292,0x000124db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 12 */
-  { /* version 12, passes 0 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x0000a493,0x0000a49b,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x000126dc,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b725,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b92d,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b724,0x0001b92d,0x0001b724},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b925,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x0001b724,0x0001b925,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
-   {0x00000000,0x00000000,0x00012492,0x000126db,
-    0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 12, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x00001249,0x00009292,
-    0x00009492,0x00009252,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x00009292,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x0000a49b,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000124db,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000124db,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000126dc,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x000136e4,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00009492,0x000126db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001c924,0x0001b724,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 13 */
-  { /* version 13, passes 0 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x00009252,0x00009292,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x000124db,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x0000a49b,
-    0x0001249b,0x000126dc,0x000126dc,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x000136e4,0x0001b725,0x000124db},
-   {0x00000000,0x00000000,0x00009292,0x0000a49b,
-    0x000136e4,0x0001b724,0x0001b725,0x000126dc},
-   {0x00000000,0x00000000,0x00009292,0x000124db,
-    0x000136e4,0x0001b724,0x0001b725,0x000126dc},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b724,0x0001c96e,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x000136e4,0x0001c92d,0x0001c96e,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b924,0x0001c92d,0x00024b76,0x0002496e},
-   {0x00000000,0x00000000,0x00012492,0x000136db,
-    0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 13, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x00009492,0x00009292,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x0000a49b,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000124db,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000136db,
-    0x0001b724,0x000124db,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000136db,
-    0x0001b724,0x000126dc,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00009292,0x000136db,
-    0x0001b724,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x00009492,0x000136db,
-    0x0001b724,0x000126dc,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00012492,0x0001b6db,
-    0x0001c924,0x0001b724,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 14 */
-  { /* version 14, passes 0 */
-   {0x00000000,0x00000000,0x00001249,0x0000924a,
-    0x00009292,0x00009493,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00001249,0x0000a49b,
-    0x0000a493,0x000124db,0x000126dc,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x0000a49b},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x000136e4,0x0001b725,0x000124db},
-   {0x00000000,0x00000000,0x00009292,0x000124db,
-    0x000126dc,0x0001b724,0x0001b92d,0x000126dc},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001c92d,0x0001c96e,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001c92d,0x00024b76,0x0001b925},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b724,0x0001c92d,0x00024b76,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x0001c92d,0x00024b76,0x0002496e},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b924,0x0002496d,0x00024b76,0x00024b77},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf},
-   {0x00000000,0x00000000,0x00012492,0x0001b6db,
-    0x00024924,0x0002db6d,0x00036db6,0x0002efff},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 14, passes 1 */
-   {0x00000000,0x00000000,0x00001249,0x00001249,
-    0x0000124a,0x0000124a,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x00009493,
-    0x0000a493,0x00009292,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x0000a49b,0x00001252,0x00001252},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000136e4,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000136e4,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x000136e4,0x00009493,0x00009292},
-   {0x00000000,0x00000000,0x00009492,0x000136db,
-    0x0001b724,0x000136e4,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x00009492,0x000136db,
-    0x0001b724,0x000136e4,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x00009492,0x000136db,
-    0x0001b724,0x000136e4,0x0000a49b,0x00009493},
-   {0x00000000,0x00000000,0x00009492,0x000136db,
-    0x0001b724,0x000136e4,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x000136e4,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x000136e4,0x000124db,0x0000a49b},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b724,0x000136e4,0x000126dc,0x000124db},
-   {0x00000000,0x00000000,0x00012492,0x0001b6db,
-    0x0001c924,0x0001b724,0x000136e4,0x000126dc},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- },
- { /* version 15 */
-  { /* version 15, passes 0 */
-   {0x00000000,0x00000000,0x00001249,0x00009493,
-    0x0000a493,0x0000a49b,0x000124db,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0001249b,0x000126dc,0x000136e4,0x000124db},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x000126dc,0x0001b724,0x0001b725,0x000126dc},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x0001b724,0x0001b92d,0x000126dc},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x000136e4,0x0001b925,0x0001c96e,0x000136e4},
-   {0x00000000,0x00000000,0x00009492,0x000124db,
-    0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000124db,
-    0x0001b724,0x0001c92d,0x0001c96e,0x0001b724},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b724,0x0001c92d,0x0001c96e,0x0001b925},
-   {0x00000000,0x00000000,0x0000a492,0x000126db,
-    0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b924,0x0001c92d,0x00024b76,0x0001c92d},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001b924,0x0002496d,0x00024b76,0x0002496e},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001c924,0x0002496d,0x00025bb6,0x00024b77},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001c924,0x00024b6d,0x00025bb6,0x00024b77},
-   {0x00000000,0x00000000,0x00012492,0x000136db,
-    0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf},
-   {0x00000000,0x00000000,0x00012492,0x0001b6db,
-    0x00024924,0x0002db6d,0x00036db6,0x0002efff},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  },
-  { /* version 15, passes 1 */
-   {0x00000000,0x00000000,0x0000924a,0x0000924a,
-    0x00009292,0x00009292,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x0000a49b,
-    0x0000a493,0x000124db,0x00009292,0x00009292},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000124db,0x0001b724,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000126dc,0x0001b724,0x00009493,0x00009493},
-   {0x00000000,0x00000000,0x0000924a,0x000124db,
-    0x000136e4,0x0001b724,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00009292,0x000136db,
-    0x0001b724,0x0001b724,0x0000a49b,0x0000a49b},
-   {0x00000000,0x00000000,0x00009492,0x000136db,
-    0x0001c924,0x0001b724,0x000124db,0x000124db},
-   {0x00000000,0x00000000,0x00009492,0x000136db,
-    0x0001c924,0x0001b724,0x000124db,0x000124db},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001c924,0x0001b724,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001c924,0x0001b925,0x000126dc,0x000126dc},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001c924,0x0001b925,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001c924,0x0001b925,0x000136e4,0x000136e4},
-   {0x00000000,0x00000000,0x0000a492,0x000136db,
-    0x0001c924,0x0001b925,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x00012492,0x000136db,
-    0x0001c924,0x0001b925,0x0001b725,0x0001b724},
-   {0x00000000,0x00000000,0x00012492,0x0001b6db,
-    0x00024924,0x0002496d,0x0001b92d,0x0001b925},
-   {0x00000000,0x00000000,0x00000000,0x00000000,
-    0x00000000,0x00000000,0x00000000,0x00000000}
-  }
- }
-};
index c062e43b3ac56207a18749626ec2d8be45779590..bc3b1635eab0083fb6bff88ce22d0dba44b1f9cb 100644 (file)
@@ -29,8 +29,6 @@
 
 #include "pwc.h"
 #include "pwc-uncompress.h"
-#include "pwc-dec1.h"
-#include "pwc-dec23.h"
 
 int pwc_decompress(struct pwc_device *pdev)
 {
@@ -122,6 +120,7 @@ int pwc_decompress(struct pwc_device *pdev)
 
                switch (pdev->type)
                 {
+#if 0           
                  case 675:
                  case 680:
                  case 690:
@@ -137,6 +136,7 @@ int pwc_decompress(struct pwc_device *pdev)
                  case 645:
                  case 646:
                    /* TODO & FIXME */
+#endif             
                    return -ENXIO; /* No such device or address: missing decompressor */
                    break;
                 }
index dd4580cb57e0d6624e530da5f20c06a2fd7dd704..7d06105763d4cca2b039bbdefcd8deaae2e0b181 100644 (file)
@@ -859,7 +859,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
                info ("udev is NULL.");
        }
 
-       /* allocate memory for our device state and intialize it */
+       /* allocate memory for our device state and initialize it */
 
        dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL);
 
index db64c908d4a73b31e3dacd67abf85573a4782256..b104430e2c6a696f808a6bae9160f15eb86db085 100644 (file)
@@ -219,17 +219,21 @@ config USB_EPSON2888
          by some sample firmware from Epson.
 
 config USB_ZAURUS
-       boolean "Sharp Zaurus (stock ROMs)"
+       boolean "Sharp Zaurus (stock ROMs) and compatible"
        depends on USB_USBNET
        select CRC32
        default y
        help
          Choose this option to support the usb networking links used by
          Zaurus models like the SL-5000D, SL-5500, SL-5600, A-300, B-500.
-
-         If you install an alternate ROM image, you may no longer need
-         to support this protocol.  Only the "eth-fd" driver really needs
-         this non-conformant variant of CDC Ethernet protocol.
+         This also supports some related device firmware, as used in some
+         PDAs from Olympus and some cell phones from Motorola.
+
+         If you install an alternate ROM image, such as the Linux 2.6 based
+         versions of OpenZaurus, you should no longer need to support this
+         protocol.  Only the "eth-fd" or "net_fd" drivers in these devices
+         really need this non-conformant variant of CDC Ethernet (or in
+         some cases CDC MDLM) protocol, not "g_ether".
 
 config USB_CDCETHER
        boolean "CDC Ethernet support (smart devices such as cable modems)"
index a45ea7c97356eed90b8d6595f639ae7c3c809811..4cbb408af72749b5f2f432c10bac69ebe4e2e1b7 100644 (file)
@@ -1517,6 +1517,26 @@ static void cdc_unbind (struct usbnet *dev, struct usb_interface *intf)
        }
 }
 
+#endif /* NEED_GENERIC_CDC */
+
+\f
+#ifdef CONFIG_USB_CDCETHER
+#define        HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * Communications Device Class, Ethernet Control model
+ *
+ * Takes two interfaces.  The DATA interface is inactive till an altsetting
+ * is selected.  Configuration data includes class descriptors.
+ *
+ * This should interop with whatever the 2.4 "CDCEther.c" driver
+ * (by Brad Hards) talked with.
+ *
+ *-------------------------------------------------------------------------*/
+
+#include <linux/ctype.h>
+
 
 static void dumpspeed (struct usbnet *dev, __le32 *speeds)
 {
@@ -1567,26 +1587,6 @@ static void cdc_status (struct usbnet *dev, struct urb *urb)
        }
 }
 
-#endif /* NEED_GENERIC_CDC */
-
-\f
-#ifdef CONFIG_USB_CDCETHER
-#define        HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Communications Device Class, Ethernet Control model
- * 
- * Takes two interfaces.  The DATA interface is inactive till an altsetting
- * is selected.  Configuration data includes class descriptors.
- *
- * This should interop with whatever the 2.4 "CDCEther.c" driver
- * (by Brad Hards) talked with.
- *
- *-------------------------------------------------------------------------*/
-
-#include <linux/ctype.h>
-
 static u8 nibble (unsigned char c)
 {
        if (likely (isdigit (c)))
@@ -2765,7 +2765,7 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf)
                        }
                        /* expect bcdVersion 1.0, ignore */
                        if (memcmp(&desc->bGUID, blan_guid, 16)
-                                   || memcmp(&desc->bGUID, blan_guid, 16) ) {
+                                   && memcmp(&desc->bGUID, safe_guid, 16) ) {
                                /* hey, this one might _really_ be MDLM! */
                                dev_dbg (&intf->dev, "MDLM guid\n");
                                goto bad_desc;
@@ -2797,11 +2797,13 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf)
                         *  - bPad (ignored, for PADAFTER -- BLAN-only)
                         * bits are:
                         *  - 0x01 -- Zaurus framing (add CRC)
-                        *  - 0x02 -- PADBEFORE
-                        *  - 0x04 -- PADAFTER
+                        *  - 0x02 -- PADBEFORE (CRC includes some padding)
+                        *  - 0x04 -- PADAFTER (some padding after CRC)
                         *  - 0x08 -- "fermat" packet mangling (for hw bugs)
+                        * the PADBEFORE appears not to matter; we interop
+                        * with devices that use it and those that don't.
                         */
-                       if (detail->bDetailData[1] != 0x01) {
+                       if ((detail->bDetailData[1] & ~02) != 0x01) {
                                /* bmDataCapabilites == 0 would be fine too,
                                 * but framing is minidriver-coupled for now.
                                 */
index f98cb2af024e1ac4bbbbc36a589752d261de3499..341ae5f732ddf3de18492c17342a97c4a3442360 100644 (file)
@@ -183,7 +183,7 @@ static void zd1201_usbtx(struct urb *urb, struct pt_regs *regs)
        return;
 }
 
-/* Incomming data */
+/* Incoming data */
 static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
 {
        struct zd1201 *zd = urb->context;
@@ -772,7 +772,7 @@ static int zd1201_net_stop(struct net_device *dev)
 /*
        RFC 1042 encapsulates Ethernet frames in 802.11 frames
        by prefixing them with 0xaa, 0xaa, 0x03) followed by a SNAP OID of 0
-       (0x00, 0x00, 0x00). Zd requires an additionnal padding, copy
+       (0x00, 0x00, 0x00). Zd requires an additional padding, copy
        of ethernet addresses, length of the standard RFC 1042 packet
        and a command byte (which is nul for tx).
        
@@ -1098,7 +1098,7 @@ static int zd1201_get_range(struct net_device *dev,
 
 /*     Little bit of magic here: we only get the quality if we poll
  *     for it, and we never get an actual request to trigger such
- *     a poll. Therefore we 'asume' that the user will soon ask for
+ *     a poll. Therefore we 'assume' that the user will soon ask for
  *     the stats after asking the bssid.
  */
 static int zd1201_get_wap(struct net_device *dev,
@@ -1108,7 +1108,7 @@ static int zd1201_get_wap(struct net_device *dev,
        unsigned char buffer[6];
 
        if (!zd1201_getconfig(zd, ZD1201_RID_COMMSQUALITY, buffer, 6)) {
-               /* Unfortunatly the quality and noise reported is useless.
+               /* Unfortunately the quality and noise reported is useless.
                   they seem to be accumulators that increase until you
                   read them, unless we poll on a fixed interval we can't
                   use them
index 0c4aa00bb39d3dea51a7b9f393ddc9b9bb147780..9438909e87a52bbd7c4ef625ce2f678403648341 100644 (file)
@@ -53,6 +53,15 @@ config USB_SERIAL_GENERIC
          support" be compiled as a module for this driver to be used
          properly.
 
+config USB_SERIAL_AIRPRIME
+       tristate "USB AirPrime CDMA Wireless Driver"
+       depends on USB_SERIAL
+       help
+         Say Y here if you want to use a AirPrime CDMA Wireless PC card.
+
+         To compile this driver as a module, choose M here: the
+         module will be called airprime.
+
 config USB_SERIAL_BELKIN
        tristate "USB Belkin and Peracom Single Port Serial Driver"
        depends on USB_SERIAL
@@ -446,6 +455,17 @@ config USB_SERIAL_XIRCOM
          To compile this driver as a module, choose M here: the
          module will be called keyspan_pda.
 
+config USB_SERIAL_OPTION
+       tristate "USB Option PCMCIA serial driver"
+       depends on USB_SERIAL && USB_OHCI_HCD && PCCARD
+       help
+         Say Y here if you want to use an Option card. This is a
+         GSM card, controlled by three serial ports which are connected
+         via an OHCI adapter located on a PC card.
+
+         To compile this driver as a module, choose M here: the
+         module will be called option.
+
 config USB_SERIAL_OMNINET
        tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)"
        depends on USB_SERIAL && EXPERIMENTAL
index b0aac47d1959a1cead78236b611e0ee7c43f342f..6c7cdcc99a9e2da387a12a352947a22e7ef08d6b 100644 (file)
@@ -11,6 +11,7 @@ usbserial-obj-$(CONFIG_USB_EZUSB)             += ezusb.o
 
 usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y)
 
+obj-$(CONFIG_USB_SERIAL_AIRPRIME)              += airprime.o
 obj-$(CONFIG_USB_SERIAL_BELKIN)                        += belkin_sa.o
 obj-$(CONFIG_USB_SERIAL_CP2101)                        += cp2101.o
 obj-$(CONFIG_USB_SERIAL_CYBERJACK)             += cyberjack.o
@@ -31,6 +32,7 @@ obj-$(CONFIG_USB_SERIAL_KLSI)                 += kl5kusb105.o
 obj-$(CONFIG_USB_SERIAL_KOBIL_SCT)             += kobil_sct.o
 obj-$(CONFIG_USB_SERIAL_MCT_U232)              += mct_u232.o
 obj-$(CONFIG_USB_SERIAL_OMNINET)               += omninet.o
+obj-$(CONFIG_USB_SERIAL_OPTION)                        += option.o
 obj-$(CONFIG_USB_SERIAL_PL2303)                        += pl2303.o
 obj-$(CONFIG_USB_SERIAL_SAFE)                  += safe_serial.o
 obj-$(CONFIG_USB_SERIAL_TI)                    += ti_usb_3410_5052.o
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
new file mode 100644 (file)
index 0000000..a4ce000
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * AirPrime CDMA Wireless Serial USB driver
+ *
+ * Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License version
+ *     2 as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "usb-serial.h"
+
+static struct usb_device_id id_table [] = {
+       { USB_DEVICE(0xf3d, 0x0112) },
+       { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver airprime_driver = {
+       .owner =        THIS_MODULE,
+       .name =         "airprime",
+       .probe =        usb_serial_probe,
+       .disconnect =   usb_serial_disconnect,
+       .id_table =     id_table,
+};
+
+static struct usb_serial_device_type airprime_device = {
+       .owner =                THIS_MODULE,
+       .name =                 "airprime",
+       .id_table =             id_table,
+       .num_interrupt_in =     NUM_DONT_CARE,
+       .num_bulk_in =          NUM_DONT_CARE,
+       .num_bulk_out =         NUM_DONT_CARE,
+       .num_ports =            1,
+};
+
+static int __init airprime_init(void)
+{
+       int retval;
+
+       retval = usb_serial_register(&airprime_device);
+       if (retval)
+               return retval;
+       retval = usb_register(&airprime_driver);
+       if (retval)
+               usb_serial_deregister(&airprime_device);
+       return retval;
+}
+
+static void __exit airprime_exit(void)
+{
+       usb_deregister(&airprime_driver);
+       usb_serial_deregister(&airprime_device);
+}
+
+module_init(airprime_init);
+module_exit(airprime_exit);
+MODULE_LICENSE("GPL");
index 7e9bb63eb466d3e09e608b22b4073448845e6802..4ace9964fc6bd36a22c0a82da2fc432be4eef5f7 100644 (file)
@@ -7,6 +7,14 @@
  *     modify it under the terms of the GNU General Public License version
  *     2 as published by the Free Software Foundation.
  *
+ * Support to set flow control line levels using TIOCMGET and TIOCMSET
+ * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow
+ * control thanks to Munir Nassar nassarmu@real-time.com
+ *
+ * Outstanding Issues:
+ *  Buffers are not flushed when the port is opened.
+ *  Multiple calls to write() may fail with "Resource temporarily unavailable"
+ *
  */
 
 #include <linux/config.h>
@@ -24,7 +32,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.03"
+#define DRIVER_VERSION "v0.04"
 #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
 
 /*
@@ -35,6 +43,9 @@ static void cp2101_cleanup(struct usb_serial_port*);
 static void cp2101_close(struct usb_serial_port*, struct file*);
 static void cp2101_get_termios(struct usb_serial_port*);
 static void cp2101_set_termios(struct usb_serial_port*, struct termios*);
+static int cp2101_tiocmget (struct usb_serial_port *, struct file *);
+static int cp2101_tiocmset (struct usb_serial_port *, struct file *,
+               unsigned int, unsigned int);
 static void cp2101_break_ctl(struct usb_serial_port*, int);
 static int cp2101_startup (struct usb_serial *);
 static void cp2101_shutdown(struct usb_serial*);
@@ -43,9 +54,10 @@ static void cp2101_shutdown(struct usb_serial*);
 static int debug;
 
 static struct usb_device_id id_table [] = {
-       {USB_DEVICE(0x10c4, 0xea60) },  /*Silicon labs factory default*/
-       {USB_DEVICE(0x10ab, 0x10c5) },  /*Siemens MC60 Cable*/
-       { } /* Terminating Entry*/
+       { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
+       { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
+       { } /* Terminating Entry */
 };
 
 MODULE_DEVICE_TABLE (usb, id_table);
@@ -70,32 +82,35 @@ static struct usb_serial_device_type cp2101_device = {
        .close                  = cp2101_close,
        .break_ctl              = cp2101_break_ctl,
        .set_termios            = cp2101_set_termios,
+       .tiocmget               = cp2101_tiocmget,
+       .tiocmset               = cp2101_tiocmset,
        .attach                 = cp2101_startup,
        .shutdown               = cp2101_shutdown,
 };
 
-/*Config request types*/
+/* Config request types */
 #define REQTYPE_HOST_TO_DEVICE 0x41
 #define REQTYPE_DEVICE_TO_HOST 0xc1
 
-/*Config SET requests. To GET, add 1 to the request number*/
-#define CP2101_UART            0x00    /*Enable / Disable*/
-#define CP2101_BAUDRATE                0x01    /*(BAUD_RATE_GEN_FREQ / baudrate)*/
-#define CP2101_BITS            0x03    /*0x(0)(data bits)(parity)(stop bits)*/
-#define CP2101_BREAK           0x05    /*On / Off*/
-#define CP2101_DTRRTS          0x07    /*101 / 202  ???*/
-#define CP2101_CONFIG_16       0x13    /*16 bytes of config data ???*/
-#define CP2101_CONFIG_6                0x19    /*6 bytes of config data ???*/
+/* Config SET requests. To GET, add 1 to the request number */
+#define CP2101_UART            0x00    /* Enable / Disable */
+#define CP2101_BAUDRATE                0x01    /* (BAUD_RATE_GEN_FREQ / baudrate) */
+#define CP2101_BITS            0x03    /* 0x(0)(databits)(parity)(stopbits) */
+#define CP2101_BREAK           0x05    /* On / Off */
+#define CP2101_CONTROL         0x07    /* Flow control line states */
+#define CP2101_MODEMCTL                0x13    /* Modem controls */
+#define CP2101_CONFIG_6                0x19    /* 6 bytes of config data ??? */
 
-/*CP2101_UART*/
+/* CP2101_UART */
 #define UART_ENABLE            0x0001
 #define UART_DISABLE           0x0000
 
-/*CP2101_BAUDRATE*/
+/* CP2101_BAUDRATE */
 #define BAUD_RATE_GEN_FREQ     0x384000
 
-/*CP2101_BITS*/
+/* CP2101_BITS */
 #define BITS_DATA_MASK         0X0f00
+#define BITS_DATA_5            0X0500
 #define BITS_DATA_6            0X0600
 #define BITS_DATA_7            0X0700
 #define BITS_DATA_8            0X0800
@@ -112,64 +127,137 @@ static struct usb_serial_device_type cp2101_device = {
 #define BITS_STOP_1            0x0000
 #define BITS_STOP_1_5          0x0001
 #define BITS_STOP_2            0x0002
+
+/* CP2101_BREAK */
 #define BREAK_ON               0x0000
 #define BREAK_OFF              0x0001
 
+/* CP2101_CONTROL */
+#define CONTROL_DTR            0x0001
+#define CONTROL_RTS            0x0002
+#define CONTROL_CTS            0x0010
+#define CONTROL_DSR            0x0020
+#define CONTROL_RING           0x0040
+#define CONTROL_DCD            0x0080
+#define CONTROL_WRITE_DTR      0x0100
+#define CONTROL_WRITE_RTS      0x0200
 
-static int cp2101_get_config(struct usb_serial_port* port, u8 request)
+/*
+ * cp2101_get_config
+ * Reads from the CP2101 configuration registers
+ * 'size' is specified in bytes.
+ * 'data' is a pointer to a pre-allocated array of integers large
+ * enough to hold 'size' bytes (with 4 bytes to each integer)
+ */
+static int cp2101_get_config(struct usb_serial_port* port, u8 request,
+               unsigned int *data, int size)
 {
        struct usb_serial *serial = port->serial;
-       unsigned char buf[4];
-       unsigned int value;
-       int result, i;
+       u32 *buf;
+       int result, i, length;
+
+       /* Number of integers required to contain the array */
+       length = (((size - 1) | 3) + 1)/4;
+
+       buf = kmalloc (length * sizeof(u32), GFP_KERNEL);
+       memset(buf, 0, length * sizeof(u32));
+
+       if (!buf) {
+               dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__);
+               return -ENOMEM;
+       }
 
-       /*For get requests, the request number must be incremented*/
+       /* For get requests, the request number must be incremented */
        request++;
 
-       /*Issue the request, attempting to read 4 bytes*/
+       /* Issue the request, attempting to read 'size' bytes */
        result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0),
                                request, REQTYPE_DEVICE_TO_HOST, 0x0000,
-                               0, buf, 4, 300);
+                               0, buf, size, 300);
 
-       if (result < 0) {
-               dev_err(&port->dev, "%s - Unable to send config request, "
-                               "request=0x%x result=%d\n",
-                               __FUNCTION__, request, result);
-               return result;
-       }
+       /* Convert data into an array of integers */
+       for (i=0; i<length; i++)
+               data[i] = le32_to_cpu(buf[i]);
 
-       /*Assemble each byte read into an integer value*/
-       value = 0;
-       for (i=0; i<4 && i<result; i++)
-               value |= (buf[i] << (i * 8));
+       kfree(buf);
 
-       dbg( " %s - request=0x%x result=%d value=0x%x",
-                       __FUNCTION__, request, result, value);
+       if (result != size) {
+               dev_err(&port->dev, "%s - Unable to send config request, "
+                               "request=0x%x size=%d result=%d\n",
+                               __FUNCTION__, request, size, result);
+               return -EPROTO;
+       }
 
-       return value;
+       return 0;
 }
 
-static int cp2101_set_config(struct usb_serial_port* port, u8 request, u16 value)
+/*
+ * cp2101_set_config
+ * Writes to the CP2101 configuration registers
+ * Values less than 16 bits wide are sent directly
+ * 'size' is specified in bytes.
+ */
+static int cp2101_set_config(struct usb_serial_port* port, u8 request,
+               unsigned int *data, int size)
 {
        struct usb_serial *serial = port->serial;
-       int result;
-       result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                       request, REQTYPE_HOST_TO_DEVICE, value,
-                       0, NULL, 0, 300);
+       u32 *buf;
+       int result, i, length;
 
-       if (result <0) {
-               dev_err(&port->dev, "%s - Unable to send config request, "
-                               "request=0x%x value=0x%x result=%d\n",
-                               __FUNCTION__, request, value, result);
-               return result;
+       /* Number of integers required to contain the array */
+       length = (((size - 1) | 3) + 1)/4;
+
+       buf = kmalloc(length * sizeof(u32), GFP_KERNEL);
+       if (!buf) {
+               dev_err(&port->dev, "%s - out of memory.\n",
+                               __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       /* Array of integers into bytes */
+       for (i = 0; i < length; i++)
+               buf[i] = cpu_to_le32(data[i]);
+
+       if (size > 2) {
+               result = usb_control_msg (serial->dev,
+                               usb_sndctrlpipe(serial->dev, 0),
+                               request, REQTYPE_HOST_TO_DEVICE, 0x0000,
+                               0, buf, size, 300);
+       } else {
+               result = usb_control_msg (serial->dev,
+                               usb_sndctrlpipe(serial->dev, 0),
+                               request, REQTYPE_HOST_TO_DEVICE, data[0],
+                               0, NULL, 0, 300);
        }
 
-       dbg(" %s - request=0x%x value=0x%x result=%d",
-                       __FUNCTION__, request, value, result);
+       kfree(buf);
+
+       if ((size > 2 && result != size) || result < 0) {
+               dev_err(&port->dev, "%s - Unable to send request, "
+                               "request=0x%x size=%d result=%d\n",
+                               __FUNCTION__, request, size, result);
+               return -EPROTO;
+       }
 
+       /* Single data value */
+       result = usb_control_msg (serial->dev,
+                       usb_sndctrlpipe(serial->dev, 0),
+                       request, REQTYPE_HOST_TO_DEVICE, data[0],
+                       0, NULL, 0, 300);
        return 0;
 }
 
+/*
+ * cp2101_set_config_single
+ * Convenience function for calling cp2101_set_config on single data values
+ * without requiring an integer pointer
+ */
+static inline int cp2101_set_config_single(struct usb_serial_port* port,
+               u8 request, unsigned int data)
+{
+       return cp2101_set_config(port, request, &data, 2);
+}
+
 static int cp2101_open (struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
@@ -177,7 +265,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp)
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (cp2101_set_config(port, CP2101_UART, UART_ENABLE)) {
+       if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) {
                dev_err(&port->dev, "%s - Unable to enable UART\n",
                                __FUNCTION__);
                return -EPROTO;
@@ -198,9 +286,12 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp)
                return result;
        }
 
-       /*Configure the termios structure*/
+       /* Configure the termios structure */
        cp2101_get_termios(port);
 
+       /* Set the DTR and RTS pins low */
+       cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0);
+
        return 0;
 }
 
@@ -228,16 +319,18 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp)
        usb_kill_urb(port->write_urb);
        usb_kill_urb(port->read_urb);
 
-       cp2101_set_config(port, CP2101_UART, UART_DISABLE);
+       cp2101_set_config_single(port, CP2101_UART, UART_DISABLE);
 }
 
-/* cp2101_get_termios*/
-/* Reads the baud rate, data bits, parity and stop bits from the device*/
-/* Corrects any unsupported values*/
-/* Configures the termios structure to reflect the state of the device*/
+/*
+ * cp2101_get_termios
+ * Reads the baud rate, data bits, parity, stop bits and flow control mode
+ * from the device, corrects any unsupported values, and configures the
+ * termios structure to reflect the state of the device
+ */
 static void cp2101_get_termios (struct usb_serial_port *port)
 {
-       unsigned int cflag;
+       unsigned int cflag, modem_ctl[4];
        int baud;
        int bits;
 
@@ -249,15 +342,16 @@ static void cp2101_get_termios (struct usb_serial_port *port)
        }
        cflag = port->tty->termios->c_cflag;
 
-       baud = cp2101_get_config(port, CP2101_BAUDRATE);
-       /*Convert to baudrate*/
+       cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
+       /* Convert to baudrate */
        if (baud)
                baud = BAUD_RATE_GEN_FREQ / baud;
 
        dbg("%s - baud rate = %d", __FUNCTION__, baud);
        cflag &= ~CBAUD;
        switch (baud) {
-               /* The baud rates which are commented out below
+               /*
+                * The baud rates which are commented out below
                 * appear to be supported by the device
                 * but are non-standard
                 */
@@ -284,14 +378,18 @@ static void cp2101_get_termios (struct usb_serial_port *port)
                        dbg("%s - Baud rate is not supported, "
                                        "using 9600 baud", __FUNCTION__);
                        cflag |= B9600;
-                       cp2101_set_config(port, CP2101_BAUDRATE,
+                       cp2101_set_config_single(port, CP2101_BAUDRATE,
                                        (BAUD_RATE_GEN_FREQ/9600));
                        break;
        }
 
-       bits = cp2101_get_config(port, CP2101_BITS);
+       cp2101_get_config(port, CP2101_BITS, &bits, 2);
        cflag &= ~CSIZE;
        switch(bits & BITS_DATA_MASK) {
+               case BITS_DATA_5:
+                       dbg("%s - data bits = 5", __FUNCTION__);
+                       cflag |= CS5;
+                       break;
                case BITS_DATA_6:
                        dbg("%s - data bits = 6", __FUNCTION__);
                        cflag |= CS6;
@@ -310,7 +408,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
                        cflag |= CS8;
                        bits &= ~BITS_DATA_MASK;
                        bits |= BITS_DATA_8;
-                       cp2101_set_config(port, CP2101_BITS, bits);
+                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
                        break;
                default:
                        dbg("%s - Unknown number of data bits, "
@@ -318,7 +416,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
                        cflag |= CS8;
                        bits &= ~BITS_DATA_MASK;
                        bits |= BITS_DATA_8;
-                       cp2101_set_config(port, CP2101_BITS, bits);
+                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
                        break;
        }
 
@@ -341,21 +439,21 @@ static void cp2101_get_termios (struct usb_serial_port *port)
                                        "disabling parity)", __FUNCTION__);
                        cflag &= ~PARENB;
                        bits &= ~BITS_PARITY_MASK;
-                       cp2101_set_config(port, CP2101_BITS, bits);
+                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
                        break;
                case BITS_PARITY_SPACE:
                        dbg("%s - parity = SPACE (not supported, "
                                        "disabling parity)", __FUNCTION__);
                        cflag &= ~PARENB;
                        bits &= ~BITS_PARITY_MASK;
-                       cp2101_set_config(port, CP2101_BITS, bits);
+                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
                        break;
                default:
                        dbg("%s - Unknown parity mode, "
                                        "disabling parity", __FUNCTION__);
                        cflag &= ~PARENB;
                        bits &= ~BITS_PARITY_MASK;
-                       cp2101_set_config(port, CP2101_BITS, bits);
+                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
                        break;
        }
 
@@ -366,9 +464,9 @@ static void cp2101_get_termios (struct usb_serial_port *port)
                        break;
                case BITS_STOP_1_5:
                        dbg("%s - stop bits = 1.5 (not supported, "
-                                       "using 1 stop bit", __FUNCTION__);
+                                       "using 1 stop bit)", __FUNCTION__);
                        bits &= ~BITS_STOP_MASK;
-                       cp2101_set_config(port, CP2101_BITS, bits);
+                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
                        break;
                case BITS_STOP_2:
                        dbg("%s - stop bits = 2", __FUNCTION__);
@@ -378,10 +476,19 @@ static void cp2101_get_termios (struct usb_serial_port *port)
                        dbg("%s - Unknown number of stop bits, "
                                        "using 1 stop bit", __FUNCTION__);
                        bits &= ~BITS_STOP_MASK;
-                       cp2101_set_config(port, CP2101_BITS, bits);
+                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
                        break;
        }
 
+       cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
+       if (modem_ctl[0] & 0x0008) {
+               dbg("%s - flow control = CRTSCTS", __FUNCTION__);
+               cflag |= CRTSCTS;
+       } else {
+               dbg("%s - flow control = NONE", __FUNCTION__);
+               cflag &= ~CRTSCTS;
+       }
+
        port->tty->termios->c_cflag = cflag;
 }
 
@@ -389,8 +496,8 @@ static void cp2101_set_termios (struct usb_serial_port *port,
                struct termios *old_termios)
 {
        unsigned int cflag, old_cflag=0;
-       int baud=0;
-       int bits;
+       int baud=0, bits;
+       unsigned int modem_ctl[4];
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -400,7 +507,7 @@ static void cp2101_set_termios (struct usb_serial_port *port,
        }
        cflag = port->tty->termios->c_cflag;
 
-       /* check that they really want us to change something */
+       /* 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)
@@ -415,7 +522,8 @@ static void cp2101_set_termios (struct usb_serial_port *port,
        /* If the baud rate is to be updated*/
        if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
                switch (cflag & CBAUD) {
-                       /* The baud rates which are commented out below
+                       /*
+                        * The baud rates which are commented out below
                         * appear to be supported by the device
                         * but are non-standard
                         */
@@ -448,18 +556,22 @@ static void cp2101_set_termios (struct usb_serial_port *port,
                if (baud) {
                        dbg("%s - Setting baud rate to %d baud", __FUNCTION__,
                                        baud);
-                       if (cp2101_set_config(port, CP2101_BAUDRATE,
+                       if (cp2101_set_config_single(port, CP2101_BAUDRATE,
                                                (BAUD_RATE_GEN_FREQ / baud)))
                                dev_err(&port->dev, "Baud rate requested not "
                                                "supported by device\n");
                }
        }
 
-       /*If the number of data bits is to be updated*/
+       /* If the number of data bits is to be updated */
        if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
-               bits = cp2101_get_config(port, CP2101_BITS);
+               cp2101_get_config(port, CP2101_BITS, &bits, 2);
                bits &= ~BITS_DATA_MASK;
                switch (cflag & CSIZE) {
+                       case CS5:
+                               bits |= BITS_DATA_5;
+                               dbg("%s - data bits = 5", __FUNCTION__);
+                               break;
                        case CS6:
                                bits |= BITS_DATA_6;
                                dbg("%s - data bits = 6", __FUNCTION__);
@@ -483,13 +595,13 @@ static void cp2101_set_termios (struct usb_serial_port *port,
                                bits |= BITS_DATA_8;
                                break;
                }
-               if (cp2101_set_config(port, CP2101_BITS, bits))
+               if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
                        dev_err(&port->dev, "Number of data bits requested "
                                        "not supported by device\n");
        }
 
        if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) {
-               bits = cp2101_get_config(port, CP2101_BITS);
+               cp2101_get_config(port, CP2101_BITS, &bits, 2);
                bits &= ~BITS_PARITY_MASK;
                if (cflag & PARENB) {
                        if (cflag & PARODD) {
@@ -500,13 +612,13 @@ static void cp2101_set_termios (struct usb_serial_port *port,
                                dbg("%s - parity = EVEN", __FUNCTION__);
                        }
                }
-               if (cp2101_set_config(port, CP2101_BITS, bits))
+               if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
                        dev_err(&port->dev, "Parity mode not supported "
                                        "by device\n");
        }
 
        if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
-               bits = cp2101_get_config(port, CP2101_BITS);
+               cp2101_get_config(port, CP2101_BITS, &bits, 2);
                bits &= ~BITS_STOP_MASK;
                if (cflag & CSTOPB) {
                        bits |= BITS_STOP_2;
@@ -515,15 +627,90 @@ static void cp2101_set_termios (struct usb_serial_port *port,
                        bits |= BITS_STOP_1;
                        dbg("%s - stop bits = 1", __FUNCTION__);
                }
-               if (cp2101_set_config(port, CP2101_BITS, bits))
+               if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
                        dev_err(&port->dev, "Number of stop bits requested "
                                        "not supported by device\n");
        }
+
+       if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
+               cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
+               dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
+                               __FUNCTION__, modem_ctl[0], modem_ctl[1],
+                               modem_ctl[2], modem_ctl[3]);
+
+               if (cflag & CRTSCTS) {
+                       modem_ctl[0] &= ~0x7B;
+                       modem_ctl[0] |= 0x09;
+                       modem_ctl[1] = 0x80;
+                       dbg("%s - flow control = CRTSCTS", __FUNCTION__);
+               } else {
+                       modem_ctl[0] &= ~0x7B;
+                       modem_ctl[0] |= 0x01;
+                       modem_ctl[1] |= 0x40;
+                       dbg("%s - flow control = NONE", __FUNCTION__);
+               }
+
+               dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
+                               __FUNCTION__, modem_ctl[0], modem_ctl[1],
+                               modem_ctl[2], modem_ctl[3]);
+               cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16);
+       }
+
+}
+
+static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file,
+               unsigned int set, unsigned int clear)
+{
+       int control = 0;
+
+       dbg("%s - port %d", __FUNCTION__, port->number);
+
+       if (set & TIOCM_RTS) {
+               control |= CONTROL_RTS;
+               control |= CONTROL_WRITE_RTS;
+       }
+       if (set & TIOCM_DTR) {
+               control |= CONTROL_DTR;
+               control |= CONTROL_WRITE_DTR;
+       }
+       if (clear & TIOCM_RTS) {
+               control &= ~CONTROL_RTS;
+               control |= CONTROL_WRITE_RTS;
+       }
+       if (clear & TIOCM_DTR) {
+               control &= ~CONTROL_DTR;
+               control |= CONTROL_WRITE_DTR;
+       }
+
+       dbg("%s - control = 0x%.4x", __FUNCTION__, control);
+
+       return cp2101_set_config(port, CP2101_CONTROL, &control, 2);
+
+}
+
+static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file)
+{
+       int control, result;
+
+       dbg("%s - port %d", __FUNCTION__, port->number);
+
+       cp2101_get_config(port, CP2101_CONTROL, &control, 1);
+
+       result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
+               |((control & CONTROL_RTS) ? TIOCM_RTS : 0)
+               |((control & CONTROL_CTS) ? TIOCM_CTS : 0)
+               |((control & CONTROL_DSR) ? TIOCM_DSR : 0)
+               |((control & CONTROL_RING)? TIOCM_RI  : 0)
+               |((control & CONTROL_DCD) ? TIOCM_CD  : 0);
+
+       dbg("%s - control = 0x%.2x", __FUNCTION__, control);
+
+       return result;
 }
 
 static void cp2101_break_ctl (struct usb_serial_port *port, int break_state)
 {
-       u16 state;
+       int state;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
        if (break_state == 0)
@@ -532,12 +719,12 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state)
                state = BREAK_ON;
        dbg("%s - turning break %s", __FUNCTION__,
                        state==BREAK_OFF ? "off" : "on");
-       cp2101_set_config(port, CP2101_BREAK, state);
+       cp2101_set_config(port, CP2101_BREAK, &state, 2);
 }
 
 static int cp2101_startup (struct usb_serial *serial)
 {
-       /*CP2101 buffers behave strangely unless device is reset*/
+       /* CP2101 buffers behave strangely unless device is reset */
        usb_reset_device(serial->dev);
        return 0;
 }
@@ -548,7 +735,7 @@ static void cp2101_shutdown (struct usb_serial *serial)
 
        dbg("%s", __FUNCTION__);
 
-       /* stop reads and writes on all ports */
+       /* Stop reads and writes on all ports */
        for (i=0; i < serial->num_ports; ++i) {
                cp2101_cleanup(serial->port[i]);
        }
@@ -560,16 +747,16 @@ static int __init cp2101_init (void)
 
        retval = usb_serial_register(&cp2101_device);
        if (retval)
-               return retval; /*Failed to register*/
+               return retval; /* Failed to register */
 
        retval = usb_register(&cp2101_driver);
        if (retval) {
-               /*Failed to register*/
+               /* Failed to register */
                usb_serial_deregister(&cp2101_device);
                return retval;
        }
 
-       /*Success*/
+       /* Success */
        info(DRIVER_DESC " " DRIVER_VERSION);
        return 0;
 }
index d165f42d560d6282751c6f81075eced95994341c..012e63e05806076b06a42dc1d3d592fa45fc0fce 100644 (file)
  * See http://geocities.com/i0xox0i for information on this driver and the
  * earthmate usb device.
  *
+ *  Lonnie Mendez <dignome@gmail.com>
+ *  4-29-2005
+ *     Fixed problem where setting or retreiving the serial config would fail with
+ *     EPIPE.  Removed CRTS toggling so the driver behaves more like other usbserial
+ *     adapters.  Issued new interval of 1ms instead of the default 10ms.  As a
+ *     result, transfer speed has been substantially increased.  From avg. 850bps to
+ *     avg. 3300bps.  initial termios has also been modified.  Cleaned up code and
+ *     formatting issues so it is more readable.  Replaced the C++ style comments.
  *
  *  Lonnie Mendez <dignome@gmail.com>
  *  12-15-2004
  *  10-2003
  *     Driver first released.
  *
- *
- * Long Term TODO:
- *     Improve transfer speeds - both read/write are somewhat slow
- *   at this point.
- *      Improve debugging.  Show modem line status with debug output and
- *   implement filtering for certain data as a module parameter.
  */
 
 /* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */
        static int debug;
 #endif
 static int stats;
+static int interval;
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.08"
+#define DRIVER_VERSION "v1.09"
 #define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
 #define DRIVER_DESC "Cypress USB to Serial Driver"
 
@@ -86,6 +89,7 @@ static int stats;
 
 static struct usb_device_id id_table_earthmate [] = {
        { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
+       { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
        { }                                             /* Terminating entry */
 };
 
@@ -96,6 +100,7 @@ static struct usb_device_id id_table_cyphidcomrs232 [] = {
 
 static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
+       { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
        { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
        { }                                             /* Terminating entry */
 };
@@ -130,7 +135,6 @@ struct cypress_private {
        char prev_status, diff_status;     /* used for TIOCMIWAIT */
        /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
        struct termios tmp_termios;        /* stores the old termios settings */
-       char calledfromopen;               /* used when issuing lines on open - fixes rts drop bug */
 };
 
 /* write buffer structure */
@@ -168,10 +172,8 @@ static void                  cypress_buf_free(struct cypress_buf *cb);
 static void              cypress_buf_clear(struct cypress_buf *cb);
 static unsigned int      cypress_buf_data_avail(struct cypress_buf *cb);
 static unsigned int      cypress_buf_space_avail(struct cypress_buf *cb);
-static unsigned int      cypress_buf_put(struct cypress_buf *cb, const char *buf,
-                                         unsigned int count);
-static unsigned int      cypress_buf_get(struct cypress_buf *cb, char *buf,
-                                         unsigned int count);
+static unsigned int      cypress_buf_put(struct cypress_buf *cb, const char *buf, unsigned int count);
+static unsigned int      cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count);
 
 
 static struct usb_serial_device_type cypress_earthmate_device = {
@@ -234,14 +236,13 @@ static struct usb_serial_device_type cypress_hidcom_device = {
  *****************************************************************************/
 
 
-/* This function can either set or retreive the current serial line settings */
+/* This function can either set or retrieve the current serial line settings */
 static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_mask, int data_bits, int stop_bits,
                                   int parity_enable, int parity_type, int reset, int cypress_request_type)
 {
-       int i, n_baud_rate = 0, retval = 0;
+       int new_baudrate = 0, retval = 0, tries = 0;
        struct cypress_private *priv;
-       __u8 feature_buffer[5];
-       __u8 config;
+       __u8 feature_buffer[8];
        unsigned long flags;
 
        dbg("%s", __FUNCTION__);
@@ -256,7 +257,8 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m
                         * of 57600bps (I have no idea whether DeLorme chose to use the general purpose
                         * firmware or not), if you need to modify this speed setting for your own
                         * project please add your own chiptype and modify the code likewise.  The
-                        * Cypress HID->COM device will work successfully up to 115200bps.
+                        * Cypress HID->COM device will work successfully up to 115200bps (but the
+                        * actual throughput is around 3kBps).
                         */
                        if (baud_mask != priv->cbr_mask) {
                                dbg("%s - baud rate is changing", __FUNCTION__);
@@ -265,109 +267,114 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m
                                         * but are not used with NMEA and SiRF protocols */
                                        
                                        if ( (baud_mask == B300) || (baud_mask == B600) ) {
-                                               err("%s - failed setting baud rate, unsupported speed (default to 4800)",
+                                               err("%s - failed setting baud rate, unsupported speed",
                                                    __FUNCTION__);
-                                               n_baud_rate = 4800;
-                                       } else if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) {
-                                               err("%s - failed setting baud rate, unsupported speed (default to 4800)",
+                                               new_baudrate = priv->baud_rate;
+                                       } else if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
+                                               err("%s - failed setting baud rate, unsupported speed",
                                                    __FUNCTION__);
-                                               n_baud_rate = 4800;
+                                               new_baudrate = priv->baud_rate;
                                        }
                                } else if (priv->chiptype == CT_CYPHIDCOM) {
-                                       if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) {
-                                               err("%s - failed setting baud rate, unsupported speed (default to 4800)",
+                                       if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
+                                               err("%s - failed setting baud rate, unsupported speed",
                                                    __FUNCTION__);
-                                               n_baud_rate = 4800;
+                                               new_baudrate = priv->baud_rate;
                                        }
                                } else if (priv->chiptype == CT_GENERIC) {
-                                       if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) {
-                                               err("%s - failed setting baud rate, unsupported speed (default to 4800)",
+                                       if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
+                                               err("%s - failed setting baud rate, unsupported speed",
                                                    __FUNCTION__);
-                                               n_baud_rate = 4800;
+                                               new_baudrate = priv->baud_rate;
                                        }
                                } else {
-                                       info("%s - please define your chiptype, using 4800bps default", __FUNCTION__);
-                                       n_baud_rate = 4800;
+                                       info("%s - please define your chiptype", __FUNCTION__);
+                                       new_baudrate = priv->baud_rate;
                                }
                        } else {  /* baud rate not changing, keep the old */
-                               n_baud_rate = priv->baud_rate;
+                               new_baudrate = priv->baud_rate;
                        }
-                       dbg("%s - baud rate is being sent as %d", __FUNCTION__, n_baud_rate);
-
+                       dbg("%s - baud rate is being sent as %d", __FUNCTION__, new_baudrate);
                        
-                       /*
-                        * This algorithm accredited to Jiang Jay Zhang... thanks for all the help!
-                        */
-                       for (i = 0; i < 4; ++i) {
-                               feature_buffer[i] = ( n_baud_rate >> (i*8) & 0xFF );
-                       }
+                       memset(feature_buffer, 0, 8);
+                       /* fill the feature_buffer with new configuration */
+                       *((u_int32_t *)feature_buffer) = new_baudrate;
 
-                       config = 0;                      // reset config byte
-                       config |= data_bits;             // assign data bits in 2 bit space ( max 3 )
+                       feature_buffer[4] |= data_bits;   /* assign data bits in 2 bit space ( max 3 ) */
                        /* 1 bit gap */
-                       config |= (stop_bits << 3);      // assign stop bits in 1 bit space
-                       config |= (parity_enable << 4);  // assign parity flag in 1 bit space
-                       config |= (parity_type << 5);    // assign parity type in 1 bit space
+                       feature_buffer[4] |= (stop_bits << 3);   /* assign stop bits in 1 bit space */
+                       feature_buffer[4] |= (parity_enable << 4);   /* assign parity flag in 1 bit space */
+                       feature_buffer[4] |= (parity_type << 5);   /* assign parity type in 1 bit space */
                        /* 1 bit gap */
-                       config |= (reset << 7);          // assign reset at end of byte, 1 bit space
-
-                       feature_buffer[4] = config;
+                       feature_buffer[4] |= (reset << 7);   /* assign reset at end of byte, 1 bit space */
                                
                        dbg("%s - device is being sent this feature report:", __FUNCTION__);
                        dbg("%s - %02X - %02X - %02X - %02X - %02X", __FUNCTION__, feature_buffer[0], feature_buffer[1],
                            feature_buffer[2], feature_buffer[3], feature_buffer[4]);
                        
+                       do {
                        retval = usb_control_msg (port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
                                                  HID_REQ_SET_REPORT, USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
-                                                 0x0300, 0, feature_buffer, 5, 500);
+                                                         0x0300, 0, feature_buffer, 8, 500);
+
+                               if (tries++ >= 3)
+                                       break;
 
-                       if (retval != 5)
+                               if (retval == EPIPE)
+                                       usb_clear_halt(port->serial->dev, 0x00);
+                       } while (retval != 8 && retval != ENODEV);
+
+                       if (retval != 8)
                                err("%s - failed sending serial line settings - %d", __FUNCTION__, retval);
                        else {
                                spin_lock_irqsave(&priv->lock, flags);
-                               priv->baud_rate = n_baud_rate;
+                               priv->baud_rate = new_baudrate;
                                priv->cbr_mask = baud_mask;
-                               priv->current_config = config;
-                               ++priv->cmd_count;
+                               priv->current_config = feature_buffer[4];
                                spin_unlock_irqrestore(&priv->lock, flags);
                        }
                break;
                case CYPRESS_GET_CONFIG:
                        dbg("%s - retreiving serial line settings", __FUNCTION__);
-                       /* reset values in feature buffer */
-                       memset(feature_buffer, 0, 5);
+                       /* set initial values in feature buffer */
+                       memset(feature_buffer, 0, 8);
 
+                       do {
                        retval = usb_control_msg (port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
                                                  HID_REQ_GET_REPORT, USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
-                                                 0x0300, 0, feature_buffer, 5, 500);
+                                                         0x0300, 0, feature_buffer, 8, 500);
+                               
+                               if (tries++ >= 3)
+                                       break;
+
+                               if (retval == EPIPE)
+                                       usb_clear_halt(port->serial->dev, 0x00);
+                       } while (retval != 5 && retval != ENODEV);
+
                        if (retval != 5) {
                                err("%s - failed to retreive serial line settings - %d", __FUNCTION__, retval);
                                return retval;
                        } else {
                                spin_lock_irqsave(&priv->lock, flags);
+
                                /* store the config in one byte, and later use bit masks to check values */
                                priv->current_config = feature_buffer[4];
-                               /* reverse the process above to get the baud_mask value */
-                               n_baud_rate = 0; // reset bits
-                               for (i = 0; i < 4; ++i) {
-                                       n_baud_rate |= ( feature_buffer[i] << (i*8) );
-                               }
+                               priv->baud_rate = *((u_int32_t *)feature_buffer);
                                
-                               priv->baud_rate = n_baud_rate;
-                               if ( (priv->cbr_mask = rate_to_mask(n_baud_rate)) == 0x40)
+                               if ( (priv->cbr_mask = rate_to_mask(priv->baud_rate)) == 0x40)
                                        dbg("%s - failed setting the baud mask (not defined)", __FUNCTION__);
-                               ++priv->cmd_count;
                                spin_unlock_irqrestore(&priv->lock, flags);
                        }
-                       break;
-               default:
-                       err("%s - unsupported serial control command issued", __FUNCTION__);
        }
+       spin_lock_irqsave(&priv->lock, flags);
+       ++priv->cmd_count;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
        return retval;
 } /* cypress_serial_control */
 
 
-/* given a baud mask, it will return speed on success */
+/* given a baud mask, it will return integer baud on success */
 static int mask_to_rate (unsigned mask)
 {
        int rate;
@@ -438,11 +445,12 @@ static int generic_startup (struct usb_serial *serial)
        
        usb_reset_configuration (serial->dev);
        
+       interval = 1;
        priv->cmd_ctrl = 0;
        priv->line_control = 0;
        priv->termios_initialized = 0;
-       priv->calledfromopen = 0;
        priv->rx_flags = 0;
+       priv->cbr_mask = B300;
        usb_set_serial_port_data(serial->port[0], priv);
        
        return (0);     
@@ -513,7 +521,6 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        /* clear halts before open */
-       usb_clear_halt(serial->dev, 0x00);
        usb_clear_halt(serial->dev, 0x81);
        usb_clear_halt(serial->dev, 0x02);
 
@@ -531,7 +538,6 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
        /* raise both lines and set termios */
        spin_lock_irqsave(&priv->lock, flags);
        priv->line_control = CONTROL_DTR | CONTROL_RTS;
-       priv->calledfromopen = 1;
        priv->cmd_ctrl = 1;
        spin_unlock_irqrestore(&priv->lock, flags);
        result = cypress_write(port, NULL, 0);
@@ -553,7 +559,7 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
        usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
                usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
                port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length,
-               cypress_read_int_callback, port, port->interrupt_in_urb->interval);
+               cypress_read_int_callback, port, interval);
        result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 
        if (result){
@@ -680,12 +686,12 @@ static void cypress_send(struct usb_serial_port *port)
        spin_lock_irqsave(&priv->lock, flags);
        switch (port->interrupt_out_size) {
                case 32:
-                       // this is for the CY7C64013...
+                       /* this is for the CY7C64013... */
                        offset = 2;
                        port->interrupt_out_buffer[0] = priv->line_control;
                        break;
                case 8:
-                       // this is for the CY7C63743...
+                       /* this is for the CY7C63743... */
                        offset = 1;
                        port->interrupt_out_buffer[0] = priv->line_control;
                        break;
@@ -738,6 +744,7 @@ send:
 
        port->interrupt_out_urb->transfer_buffer_length = actual_size;
        port->interrupt_out_urb->dev = port->serial->dev;
+       port->interrupt_out_urb->interval = interval;
        result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
        if (result) {
                dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__,
@@ -910,7 +917,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
        unsigned cflag, iflag, baud_mask;
        unsigned long flags;
        __u8 oldlines;
-       int linechange;
+       int linechange = 0;
        
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -996,15 +1003,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
                        case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break;
                        default: dbg("%s - unknown masked baud rate", __FUNCTION__);
                }
-               priv->line_control |= CONTROL_DTR;
-               
-               /* toggle CRTSCTS? - don't do this if being called from cypress_open */
-               if (!priv->calledfromopen) {
-                       if (cflag & CRTSCTS)
-                               priv->line_control |= CONTROL_RTS;
-                       else
-                               priv->line_control &= ~CONTROL_RTS;
-               }
+               priv->line_control = (CONTROL_DTR | CONTROL_RTS);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
        
@@ -1014,8 +1013,6 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
        cypress_serial_control(port, baud_mask, data_bits, stop_bits, parity_enable,
                               parity_type, 0, CYPRESS_SET_CONFIG);
 
-       msleep(50);                     /* give some time between change and read (50ms) */
-
        /* we perform a CYPRESS_GET_CONFIG so that the current settings are filled into the private structure
          * this should confirm that all is working if it returns what we just set */
        cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
@@ -1031,7 +1028,6 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
                dbg("Using custom termios settings for a baud rate of 4800bps.");
                /* define custom termios settings for NMEA protocol */
 
-               
                tty->termios->c_iflag /* input modes - */
                        &= ~(IGNBRK             /* disable ignore break */
                        | BRKINT                /* disable break causes interrupt */
@@ -1052,23 +1048,16 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
                        | ISIG                  /* disable interrupt, quit, and suspend special characters */
                        | IEXTEN);              /* disable non-POSIX special characters */
 
-       } else if (priv->chiptype == CT_CYPHIDCOM) {
-
-               // Software app handling it for device...       
+       } /* CT_CYPHIDCOM: Application should handle this for device */
 
-       }
        linechange = (priv->line_control != oldlines);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* if necessary, set lines */
-       if (!priv->calledfromopen && linechange) {
+       if (linechange) {
                priv->cmd_ctrl = 1;
                cypress_write(port, NULL, 0);
        }
-
-       if (priv->calledfromopen)
-               priv->calledfromopen = 0;
-       
 } /* cypress_set_termios */
 
  
@@ -1164,7 +1153,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
        spin_lock_irqsave(&priv->lock, flags);
        switch(urb->actual_length) {
                case 32:
-                       // This is for the CY7C64013...
+                       /* This is for the CY7C64013... */
                        priv->current_status = data[0] & 0xF8;
                        bytes = data[1]+2;
                        i=2;
@@ -1172,7 +1161,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
                                havedata = 1;
                        break;
                case 8:
-                       // This is for the CY7C63743...
+                       /* This is for the CY7C63743... */
                        priv->current_status = data[0] & 0xF8;
                        bytes = (data[0] & 0x07)+1;
                        i=1;
@@ -1245,7 +1234,7 @@ continue_read:
                port->interrupt_in_urb->transfer_buffer,
                port->interrupt_in_urb->transfer_buffer_length,
                cypress_read_int_callback, port,
-               port->interrupt_in_urb->interval);
+               interval);
        result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
        if (result)
                dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
@@ -1274,6 +1263,8 @@ static void cypress_write_int_callback(struct urb *urb, struct pt_regs *regs)
                        dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
                        priv->write_urb_in_use = 0;
                        return;
+               case -EPIPE: /* no break needed */
+                       usb_clear_halt(port->serial->dev, 0x02);
                default:
                        /* error in the urb, so we have to resubmit it */
                        dbg("%s - Overflow in write", __FUNCTION__);
@@ -1535,3 +1526,5 @@ module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
 module_param(stats, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(stats, "Enable statistics or not");
+module_param(interval, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(interval, "Overrides interrupt interval");
index 1012ee6b19ce6dbbbeeb3c7672e7b2dc8d371558..1fa119efe41a0276c412a9a5ed8f5ff6ce1ecaf8 100644 (file)
@@ -13,6 +13,7 @@
 /* DeLorme Earthmate USB - a GPS device */
 #define        VENDOR_ID_DELORME                0x1163
 #define PRODUCT_ID_EARTHMATEUSB                 0x0100
+#define PRODUCT_ID_EARTHMATEUSB_LT20    0x0200
 
 /* Cypress HID->COM RS232 Adapter */
 #define VENDOR_ID_CYPRESS               0x04b4
index 4c788c767a97f890df4f24741f4d47518bc1a6ee..3bfcc7b9f861c898924451cb6680066214cd4504 100644 (file)
@@ -76,7 +76,7 @@
  *      Defererence pointers after any paranoid checks, not before.
  *
  * (21/Jun/2003) Erik Nygren
- *      Added support for Home Electronics Tira-1 IR tranceiver using FT232BM chip.
+ *      Added support for Home Electronics Tira-1 IR transceiver using FT232BM chip.
  *      See <http://www.home-electro.com/tira1.htm>.  Only operates properly 
  *      at 100000 and RTS-CTS, so set custom divisor mode on startup.
  *      Also force the Tira-1 and USB-UIRT to only use their custom baud rates.
@@ -91,7 +91,7 @@
  *      Minor whitespace and comment changes.
  *
  * (12/Jun/2003) David Norwood
- *      Added support for USB-UIRT IR tranceiver using 8U232AM chip.
+ *      Added support for USB-UIRT IR transceiver using 8U232AM chip.
  *      See <http://home.earthlink.net/~jrhees/USBUIRT/index.htm>.  Only
  *      operates properly at 312500, so set custom divisor mode on startup.
  *
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.4.1"
+#define DRIVER_VERSION "v1.4.2"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>"
 #define DRIVER_DESC "USB FTDI Serial Converters Driver"
 
@@ -272,6 +272,7 @@ static int debug;
 
 static struct usb_device_id id_table_sio [] = {
        { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
+       { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
        { }                                             /* Terminating entry */
 };
 
@@ -296,7 +297,6 @@ static struct usb_device_id id_table_8U232AM [] = {
        { USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0, 0x3ff) },
-       { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_ALT_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0, 0x3ff) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
@@ -364,16 +364,20 @@ static struct usb_device_id id_table_8U232AM [] = {
        { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) },
        { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0, 0x3ff) },
-       { USB_DEVICE_VER(FTDI_RM_VID, FTDI_RMCANVIEW_PID, 0, 0x3ff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0, 0x3ff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0, 0x3ff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0, 0x3ff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0, 0x3ff) },
        { }                                             /* Terminating entry */
 };
 
@@ -382,7 +386,6 @@ static struct usb_device_id id_table_FT232BM [] = {
        { USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0x400, 0xffff) },
-       { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_ALT_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) },
@@ -473,6 +476,7 @@ static struct usb_device_id id_table_FT232BM [] = {
        { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) },
@@ -485,11 +489,15 @@ static struct usb_device_id id_table_FT232BM [] = {
        { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0x400, 0xffff) },
-       { USB_DEVICE_VER(FTDI_RM_VID, FTDI_RMCANVIEW_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) },
        { }                                             /* Terminating entry */
 };
 
@@ -517,7 +525,6 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
-       { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_ALT_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
@@ -596,7 +603,24 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, PROTEGO_R2X0) },
        { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) },
        { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E808_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E809_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80A_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80B_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80C_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80D_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80E_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80F_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E888_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E889_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88A_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88B_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88C_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88D_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) },
        { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
        { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) },
@@ -609,11 +633,16 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
        { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
-       { USB_DEVICE(FTDI_RM_VID, FTDI_RMCANVIEW_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
        { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) },
+       { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
+       { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) },
        { }                                             /* Terminating entry */
 };
 
@@ -658,6 +687,8 @@ struct ftdi_private {
        char prev_status, diff_status;        /* Used for TIOCMIWAIT */
        __u8 rx_flags;          /* receive state flags (throttling) */
        spinlock_t rx_lock;     /* spinlock for receive state */
+       struct work_struct rx_work;
+       int rx_processed;
 
        __u16 interface;        /* FT2232C port interface (0 for FT232/245) */
 
@@ -688,7 +719,7 @@ static int  ftdi_write_room         (struct usb_serial_port *port);
 static int  ftdi_chars_in_buffer       (struct usb_serial_port *port);
 static void ftdi_write_bulk_callback   (struct urb *urb, struct pt_regs *regs);
 static void ftdi_read_bulk_callback    (struct urb *urb, struct pt_regs *regs);
-static void ftdi_process_read          (struct usb_serial_port *port);
+static void ftdi_process_read          (void *param);
 static void ftdi_set_termios           (struct usb_serial_port *port, struct termios * old);
 static int  ftdi_tiocmget               (struct usb_serial_port *port, struct file *file);
 static int  ftdi_tiocmset              (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear);
@@ -1358,6 +1389,8 @@ static int ftdi_common_startup (struct usb_serial *serial)
                port->read_urb->transfer_buffer_length = BUFSZ;
        }
 
+       INIT_WORK(&priv->rx_work, ftdi_process_read, port);
+
        /* Free port's existing write urb and transfer buffer. */
        if (port->write_urb) {
                usb_free_urb (port->write_urb);
@@ -1457,10 +1490,10 @@ static int ftdi_FT2232C_startup (struct usb_serial *serial)
        inter = serial->interface->altsetting->desc.bInterfaceNumber;
 
        if (inter) {
-               priv->interface = INTERFACE_B;
+               priv->interface = PIT_SIOB;
        }
        else  {
-               priv->interface = INTERFACE_A;
+               priv->interface = PIT_SIOA;
        }
        priv->baud_base = 48000000 / 2; /* Would be / 16, but FT2232C supports multiple of 0.125 divisor fractions! */
        
@@ -1588,6 +1621,7 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
        spin_unlock_irqrestore(&priv->rx_lock, flags);
 
        /* Start reading from the device */
+       priv->rx_processed = 0;
        usb_fill_bulk_urb(port->read_urb, dev,
                      usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
                      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
@@ -1638,6 +1672,10 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
                        err("Error from RTS LOW urb");
                }
        } /* Note change no line if hupcl is off */
+
+       /* cancel any scheduled reading */
+       cancel_delayed_work(&priv->rx_work);
+       flush_scheduled_work();
        
        /* shutdown our bulk read */
        if (port->read_urb)
@@ -1833,23 +1871,14 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
                return;
        }
 
-       /* If throttled, delay receive processing until unthrottled. */
-       spin_lock(&priv->rx_lock);
-       if (priv->rx_flags & THROTTLED) {
-               dbg("Deferring read urb processing until unthrottled");
-               priv->rx_flags |= ACTUALLY_THROTTLED;
-               spin_unlock(&priv->rx_lock);
-               return;
-       }
-       spin_unlock(&priv->rx_lock);
-
        ftdi_process_read(port);
 
 } /* ftdi_read_bulk_callback */
 
 
-static void ftdi_process_read (struct usb_serial_port *port)
+static void ftdi_process_read (void *param)
 { /* ftdi_process_read */
+       struct usb_serial_port *port = (struct usb_serial_port*)param;
        struct urb *urb;
        struct tty_struct *tty;
        struct ftdi_private *priv;
@@ -1860,6 +1889,7 @@ static void ftdi_process_read (struct usb_serial_port *port)
        int result;
        int need_flip;
        int packet_offset;
+       unsigned long flags;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -1886,12 +1916,18 @@ static void ftdi_process_read (struct usb_serial_port *port)
 
        data = urb->transfer_buffer;
 
-        /* The first two bytes of every read packet are status */
-       if (urb->actual_length > 2) {
-               usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+       if (priv->rx_processed) {
+               dbg("%s - already processed: %d bytes, %d remain", __FUNCTION__,
+                               priv->rx_processed,
+                               urb->actual_length - priv->rx_processed);
        } else {
-                dbg("Status only: %03oo %03oo",data[0],data[1]);
-        }
+               /* The first two bytes of every read packet are status */
+               if (urb->actual_length > 2) {
+                       usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+               } else {
+                       dbg("Status only: %03oo %03oo",data[0],data[1]);
+               }
+       }
 
 
        /* TO DO -- check for hung up line and handle appropriately: */
@@ -1900,8 +1936,12 @@ static void ftdi_process_read (struct usb_serial_port *port)
        /* if CD is dropped and the line is not CLOCAL then we should hangup */
 
        need_flip = 0;
-       for (packet_offset=0; packet_offset < urb->actual_length; packet_offset += PKTSZ) {
+       for (packet_offset = priv->rx_processed; packet_offset < urb->actual_length; packet_offset += PKTSZ) {
+               int length;
+
                /* Compare new line status to the old one, signal if different */
+               /* N.B. packet may be processed more than once, but differences
+                * are only processed once.  */
                if (priv != NULL) {
                        char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK;
                        if (new_status != priv->prev_status) {
@@ -1911,6 +1951,35 @@ static void ftdi_process_read (struct usb_serial_port *port)
                        }
                }
 
+               length = min(PKTSZ, urb->actual_length-packet_offset)-2;
+               if (length < 0) {
+                       err("%s - bad packet length: %d", __FUNCTION__, length+2);
+                       length = 0;
+               }
+
+               /* have to make sure we don't overflow the buffer
+                  with tty_insert_flip_char's */
+               if (tty->flip.count+length > TTY_FLIPBUF_SIZE) {
+                       tty_flip_buffer_push(tty);
+                       need_flip = 0;
+
+                       if (tty->flip.count != 0) {
+                               /* flip didn't work, this happens when ftdi_process_read() is
+                                * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */
+                               dbg("%s - flip buffer push failed", __FUNCTION__);
+                               break;
+                       }
+               }
+               if (priv->rx_flags & THROTTLED) {
+                       dbg("%s - throttled", __FUNCTION__);
+                       break;
+               }
+               if (tty->ldisc.receive_room(tty)-tty->flip.count < length) {
+                       /* break out & wait for throttling/unthrottling to happen */
+                       dbg("%s - receive room low", __FUNCTION__);
+                       break;
+               }
+
                /* Handle errors and break */
                error_flag = TTY_NORMAL;
                /* Although the device uses a bitmask and hence can have multiple */
@@ -1933,13 +2002,8 @@ static void ftdi_process_read (struct usb_serial_port *port)
                        error_flag = TTY_FRAME;
                        dbg("FRAMING error");
                }
-               if (urb->actual_length > packet_offset + 2) {
-                       for (i = 2; (i < PKTSZ) && ((i+packet_offset) < urb->actual_length); ++i) {
-                               /* have to make sure we don't overflow the buffer
-                                 with tty_insert_flip_char's */
-                               if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                                       tty_flip_buffer_push(tty);
-                               }
+               if (length > 0) {
+                       for (i = 2; i < length+2; i++) {
                                /* Note that the error flag is duplicated for 
                                   every character received since we don't know
                                   which character it applied to */
@@ -1976,6 +2040,35 @@ static void ftdi_process_read (struct usb_serial_port *port)
                tty_flip_buffer_push(tty);
        }
 
+       if (packet_offset < urb->actual_length) {
+               /* not completely processed - record progress */
+               priv->rx_processed = packet_offset;
+               dbg("%s - incomplete, %d bytes processed, %d remain",
+                               __FUNCTION__, packet_offset,
+                               urb->actual_length - packet_offset);
+               /* check if we were throttled while processing */
+               spin_lock_irqsave(&priv->rx_lock, flags);
+               if (priv->rx_flags & THROTTLED) {
+                       priv->rx_flags |= ACTUALLY_THROTTLED;
+                       spin_unlock_irqrestore(&priv->rx_lock, flags);
+                       dbg("%s - deferring remainder until unthrottled",
+                                       __FUNCTION__);
+                       return;
+               }
+               spin_unlock_irqrestore(&priv->rx_lock, flags);
+               /* if the port is closed stop trying to read */
+               if (port->open_count > 0){
+                       /* delay processing of remainder */
+                       schedule_delayed_work(&priv->rx_work, 1);
+               } else {
+                       dbg("%s - port is closed", __FUNCTION__);
+               }
+               return;
+       }
+
+       /* urb is completely processed */
+       priv->rx_processed = 0;
+
        /* if the port is closed stop trying to read */
        if (port->open_count > 0){
                /* Continue trying to always read  */
@@ -2415,7 +2508,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port)
        spin_unlock_irqrestore(&priv->rx_lock, flags);
 
        if (actually_throttled)
-               ftdi_process_read(port);
+               schedule_work(&priv->rx_work);
 }
 
 static int __init ftdi_init (void)
index be5d60bf90b903b1d1a16f25a23c9e37d8317017..8866376823a5fd90eca435e80d0062b83e5de5ff 100644 (file)
@@ -26,7 +26,6 @@
 #define FTDI_SIO_PID   0x8372  /* Product Id SIO application of 8U100AX  */
 #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
 #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
-#define FTDI_8U232AM_ALT_ALT_PID 0xf3c0 /* FTDI's second alternate PID for above */
 #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
 #define FTDI_RELAIS_PID        0xFA10  /* Relais device from Rudolf Gugler */
 #define FTDI_NF_RIC_VID        0x0DCD  /* Vendor Id */
 /*
  * Home Electronics (www.home-electro.com) USB gadgets
  */
-#define FTDI_HE_TIRA1_PID      0xFA78  /* Tira-1 IR tranceiver */
+#define FTDI_HE_TIRA1_PID      0xFA78  /* Tira-1 IR transceiver */
 
 /* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */
 /* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
 
 /* ELV USB Module UO100 (PID sent by Stefan Frings) */
 #define FTDI_ELV_UO100_PID     0xFB58  /* Product Id */
+/* ELV USB Module UM100 (PID sent by Arnim Laeuger) */
+#define FTDI_ELV_UM100_PID     0xFB5A  /* Product Id */
 
 /*
  * Definitions for ID TECH (www.idt-net.com) devices
  */
 #define OCT_VID                        0x0B39  /* OCT vendor ID */
 /* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */
-/* Also rebadged as SIIG Inc. model US2308 */
+/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */
+/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */
 #define OCT_US101_PID          0x0421  /* OCT US101 USB to RS-232 */
 
 /* an infrared receiver for user access control with IR tags */
 
 /*
  * RM Michaelides CANview USB (http://www.rmcan.com)
- * CAN filedbus interface adapter, addad by port GmbH www.port.de)
+ * CAN fieldbus interface adapter, added by port GmbH www.port.de)
+ * Ian Abbott changed the macro names for consistency.
  */
-#define FTDI_RM_VID            0x0403  /* Vendor  Id */
-#define FTDI_RMCANVIEW_PID     0xfd60  /* Product Id */
+#define FTDI_RM_CANVIEW_PID    0xfd60  /* Product Id */
 
 /*
  * EVER Eco Pro UPS (http://www.ever.com.pl/)
 
 #define        EVER_ECO_PRO_CDS        0xe520  /* RS-232 converter */
 
+/*
+ * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485,
+ * USB-TTY activ, USB-TTY passiv.  Some PIDs are used by several devices
+ * and I'm not entirely sure which are used by which.
+ */
+#define FTDI_4N_GALAXY_DE_0_PID        0x8372
+#define FTDI_4N_GALAXY_DE_1_PID        0xF3C0
+#define FTDI_4N_GALAXY_DE_2_PID        0xF3C1
+
+/*
+ * Mobility Electronics products.
+ */
+#define MOBILITY_VID                   0x1342
+#define MOBILITY_USB_SERIAL_PID                0x0202  /* EasiDock USB 200 serial */
+
+/*
+ * Active Robots product ids.
+ */
+#define FTDI_ACTIVE_ROBOTS_PID 0xE548  /* USB comms board */
+
 /* Commands */
 #define FTDI_SIO_RESET                 0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL    1 /* Set the modem control register */
 #define FTDI_SIO_SET_LATENCY_TIMER     9 /* Set the latency timer */
 #define FTDI_SIO_GET_LATENCY_TIMER     10 /* Get the latency timer */
 
-/* Port interface code for FT2232C */
-#define INTERFACE_A            1
-#define INTERFACE_B            2
-
 
 /*
  *   BmRequestType:  1100 0000b
index 8c1fa5e722b1a86785b6e537cd50bb45d62e4651..f1804fd5a3ddcada93cfd65b2c6a3f52525330b3 100644 (file)
 //
 
 //
-// Edgeport Compatiblity Descriptor
+// Edgeport Compatibility Descriptor
 //
 // This descriptor is only returned by Edgeport-compatible devices
 // supporting the EPiC spec. True ION devices do not return this
index dd935b62c1a82e072628250fa958fd780f952ddf..86708ecd87357095629d6f670938b2da30e456ac 100644 (file)
@@ -19,7 +19,7 @@
 
                This file is available under a BSD-style copyright
 
-       2. The name of InnoSys Incorprated may not be used to endorse or promote
+       2. The name of InnoSys Incorporated may not be used to endorse or promote
        products derived from this software without specific prior written
        permission.
 
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
new file mode 100644 (file)
index 0000000..b722175
--- /dev/null
@@ -0,0 +1,729 @@
+/*
+  Option Card (PCMCIA to) USB to Serial Driver
+
+  Copyright (C) 2005  Matthias Urlichs <smurf@smurf.noris.de>
+
+  This driver is free software; you can redistribute it and/or modify
+  it under the terms of Version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
+
+  History:
+
+  2005-05-19  v0.1   Initial version, based on incomplete docs
+                     and analysis of misbehavior of the standard driver
+  2005-05-20  v0.2   Extended the input buffer to avoid losing
+                     random 64-byte chunks of data
+  2005-05-21  v0.3   implemented chars_in_buffer()
+                     turned on low_latency
+                     simplified the code somewhat
+*/
+#define DRIVER_VERSION "v0.3"
+#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
+#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver"
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "usb-serial.h"
+
+/* Function prototypes */
+static int  option_open (struct usb_serial_port *port, struct file *filp);
+static void option_close (struct usb_serial_port *port, struct file *filp);
+static int  option_startup (struct usb_serial *serial);
+static void option_shutdown (struct usb_serial *serial);
+static void option_rx_throttle (struct usb_serial_port *port);
+static void option_rx_unthrottle (struct usb_serial_port *port);
+static int  option_write_room (struct usb_serial_port *port);
+
+static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
+
+
+static int  option_write (struct usb_serial_port *port,
+                          const unsigned char *buf, int count);
+
+static int  option_chars_in_buffer (struct usb_serial_port *port);
+static int  option_ioctl (struct usb_serial_port *port, struct file *file,
+                          unsigned int cmd, unsigned long arg);
+static void option_set_termios (struct usb_serial_port *port,
+                                struct termios *old);
+static void option_break_ctl (struct usb_serial_port *port, int break_state);
+static int  option_tiocmget (struct usb_serial_port *port, struct file *file);
+static int  option_tiocmset (struct usb_serial_port *port, struct file *file,
+                             unsigned int set, unsigned int clear);
+static int  option_send_setup (struct usb_serial_port *port);
+
+/* Vendor and product IDs */
+#define OPTION_VENDOR_ID               0x0AF0
+
+#define        OPTION_PRODUCT_OLD              0x5000
+#define        OPTION_PRODUCT_WLAN             0x6000
+
+static struct usb_device_id option_ids[] = {
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) },
+       { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, option_ids);
+
+static struct usb_driver option_driver = {
+       .owner      = THIS_MODULE,
+       .name       = "option",
+       .probe      = usb_serial_probe,
+       .disconnect = usb_serial_disconnect,
+       .id_table   = option_ids,
+};
+
+/* The card has three separate interfaces, wich the serial driver
+ * recognizes separately, thus num_port=1.
+ */
+static struct usb_serial_device_type option_3port_device = {
+       .owner                  = THIS_MODULE,
+       .name                   = "Option 3-port card",
+       .short_name             = "option",
+       .id_table               = option_ids,
+       .num_interrupt_in       = NUM_DONT_CARE,
+       .num_bulk_in            = NUM_DONT_CARE,
+       .num_bulk_out           = NUM_DONT_CARE,
+       .num_ports              = 1, /* 3 */
+       .open                   = option_open,
+       .close                  = option_close,
+       .write                  = option_write,
+       .write_room             = option_write_room,
+       .chars_in_buffer        = option_chars_in_buffer,
+       .throttle               = option_rx_throttle,
+       .unthrottle             = option_rx_unthrottle,
+       .ioctl                  = option_ioctl,
+       .set_termios            = option_set_termios,
+       .break_ctl              = option_break_ctl,
+       .tiocmget               = option_tiocmget,
+       .tiocmset               = option_tiocmset,
+       .attach                 = option_startup,
+       .shutdown               = option_shutdown,
+       .read_int_callback      = option_instat_callback,
+};
+
+static int debug;
+
+/* per port private data */
+
+#define N_IN_URB       4
+#define N_OUT_URB      1
+#define IN_BUFLEN      1024
+#define OUT_BUFLEN     1024
+
+struct option_port_private {
+       /* 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) */
+       int             dtr_state;
+       int             cts_state;      /* Handshaking pins (inputs) */
+       int             dsr_state;
+       int             dcd_state;
+       int             ri_state;
+       // int          break_on;
+
+       unsigned long   tx_start_time[N_OUT_URB];
+};
+
+
+/* Functions used by new usb-serial code. */
+static int __init
+option_init (void)
+{
+       int retval;
+       retval = usb_serial_register(&option_3port_device);
+       if (retval)
+               goto failed_3port_device_register;
+       retval = usb_register(&option_driver);
+       if (retval)
+               goto failed_driver_register;
+
+       info(DRIVER_DESC ": " DRIVER_VERSION);
+
+       return 0;
+
+failed_driver_register:
+       usb_serial_deregister (&option_3port_device);
+failed_3port_device_register:
+       return retval;
+}
+
+static void __exit
+option_exit (void)
+{
+       usb_deregister (&option_driver);
+       usb_serial_deregister (&option_3port_device);
+}
+
+module_init(option_init);
+module_exit(option_exit);
+
+static void
+option_rx_throttle (struct usb_serial_port *port)
+{
+       dbg("%s", __FUNCTION__);
+}
+
+
+static void
+option_rx_unthrottle (struct usb_serial_port *port)
+{
+       dbg("%s", __FUNCTION__);
+}
+
+
+static void
+option_break_ctl (struct usb_serial_port *port, int break_state)
+{
+       /* Unfortunately, I don't know how to send a break */
+       dbg("%s", __FUNCTION__);
+}
+
+
+static void
+option_set_termios (struct usb_serial_port *port,
+                                    struct termios *old_termios)
+{
+       dbg("%s", __FUNCTION__);
+
+       option_send_setup(port);
+}
+
+static int
+option_tiocmget(struct usb_serial_port *port, struct file *file)
+{
+       unsigned int                    value;
+       struct option_port_private      *portdata;
+
+       portdata = usb_get_serial_port_data(port);
+
+       value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
+               ((portdata->dtr_state) ? TIOCM_DTR : 0) |
+               ((portdata->cts_state) ? TIOCM_CTS : 0) |
+               ((portdata->dsr_state) ? TIOCM_DSR : 0) |
+               ((portdata->dcd_state) ? TIOCM_CAR : 0) |
+               ((portdata->ri_state) ? TIOCM_RNG : 0);
+
+       return value;
+}
+
+static int
+option_tiocmset (struct usb_serial_port *port, struct file *file,
+                 unsigned int set, unsigned int clear)
+{
+       struct option_port_private      *portdata;
+
+       portdata = usb_get_serial_port_data(port);
+
+       if (set & TIOCM_RTS)
+               portdata->rts_state = 1;
+       if (set & TIOCM_DTR)
+               portdata->dtr_state = 1;
+
+       if (clear & TIOCM_RTS)
+               portdata->rts_state = 0;
+       if (clear & TIOCM_DTR)
+               portdata->dtr_state = 0;
+       return option_send_setup(port);
+}
+
+static int
+option_ioctl (struct usb_serial_port *port, struct file *file,
+              unsigned int cmd, unsigned long arg)
+{
+       return -ENOIOCTLCMD;
+}
+
+/* Write */
+static int
+option_write(struct usb_serial_port *port,
+                        const unsigned char *buf, int count)
+{
+       struct option_port_private      *portdata;
+       int                             i;
+       int                             left, todo;
+       struct urb                      *this_urb = NULL; /* spurious */
+       int                             err;
+
+       portdata = usb_get_serial_port_data(port);
+
+       dbg("%s: write (%d chars)", __FUNCTION__, count);
+
+#if 0
+       spin_lock(&port->lock);
+       if (port->write_urb_busy) {
+               spin_unlock(&port->lock);
+               dbg("%s: already writing", __FUNCTION__);
+               return 0;
+       }
+       port->write_urb_busy = 1;
+       spin_unlock(&port->lock);
+#endif
+
+       i = 0;
+       left = count;
+       while (left>0) {
+               todo = left;
+               if (todo > OUT_BUFLEN)
+                       todo = OUT_BUFLEN;
+
+               for (;i < N_OUT_URB; i++) {
+                       /* Check we have a valid urb/endpoint before we use it... */
+                       this_urb = portdata->out_urbs[i];
+                       if (this_urb->status != -EINPROGRESS)
+                               break;
+                       if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
+                               continue;
+                       if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
+                               continue;
+                       this_urb->transfer_flags |= URB_ASYNC_UNLINK;
+                       usb_unlink_urb(this_urb);
+               }
+
+               if (i == N_OUT_URB) {
+                       /* no bulk out free! */
+                       dbg("%s: no output urb -- left %d", __FUNCTION__,count-left);
+#if 0
+                       port->write_urb_busy = 0;
+#endif
+                       return count-left;
+               }
+
+               dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
+
+               memcpy (this_urb->transfer_buffer, buf, todo);
+
+               /* send the data out the bulk port */
+               this_urb->transfer_buffer_length = todo;
+
+               this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
+               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;
+       }
+
+       count -= left;
+#if 0
+       port->write_urb_busy = 0;
+#endif
+       dbg("%s: wrote (did %d)", __FUNCTION__, count);
+       return count;
+}
+
+static void
+option_indat_callback (struct urb *urb, struct pt_regs *regs)
+{
+       int     i, err;
+       int endpoint;
+       struct usb_serial_port *port;
+       struct tty_struct *tty;
+       unsigned char *data = urb->transfer_buffer;
+
+       dbg("%s: %p", __FUNCTION__, urb);
+
+       endpoint = usb_pipeendpoint(urb->pipe);
+       port = (struct usb_serial_port *) urb->context;
+
+       if (urb->status) {
+               dbg("%s: nonzero status: %d on endpoint %02x.",
+                   __FUNCTION__, urb->status, endpoint);
+       } else {
+               tty = port->tty;
+               if (urb->actual_length) {
+                       for (i = 0; i < urb->actual_length ; ++i) {
+                               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+                                       tty_flip_buffer_push(tty);
+                               tty_insert_flip_char(tty, data[i], 0);
+                       }
+                       tty_flip_buffer_push(tty);
+               } else {
+                       dbg("%s: empty read urb received", __FUNCTION__);
+               }
+
+               /* Resubmit urb so we continue receiving */
+               if (port->open_count && urb->status != -ESHUTDOWN) {
+                       err = usb_submit_urb(urb, GFP_ATOMIC);
+                       if (err)
+                               printk(KERN_ERR "%s: resubmit read urb failed. (%d)", __FUNCTION__, err);
+               }
+       }
+       return;
+}
+
+static void
+option_outdat_callback (struct urb *urb, struct pt_regs *regs)
+{
+       struct usb_serial_port *port;
+
+       dbg("%s", __FUNCTION__);
+
+       port = (struct usb_serial_port *) urb->context;
+
+       if (port->open_count)
+               schedule_work(&port->work);
+}
+
+static void
+option_instat_callback (struct urb *urb, struct pt_regs *regs)
+{
+       int err;
+       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;
+
+       dbg("%s", __FUNCTION__);
+       dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);
+
+       if (urb->status == 0) {
+               struct usb_ctrlrequest *req_pkt =
+                               (struct usb_ctrlrequest *)urb->transfer_buffer;
+
+               if (!req_pkt) {
+                       dbg("%s: NULL req_pkt\n", __FUNCTION__);
+                       return;
+               }
+               if ((req_pkt->bRequestType == 0xA1) && (req_pkt->bRequest == 0x20)) {
+                       int old_dcd_state;
+                       unsigned char signals = *((unsigned char *)
+                                       urb->transfer_buffer + sizeof(struct usb_ctrlrequest));
+
+                       dbg("%s: signal x%x", __FUNCTION__, signals);
+
+                       old_dcd_state = portdata->dcd_state;
+                       portdata->cts_state = 1;
+                       portdata->dcd_state = ((signals & 0x01) ? 1 : 0);
+                       portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
+                       portdata->ri_state = ((signals & 0x08) ? 1 : 0);
+
+                       if (port->tty && !C_CLOCAL(port->tty)
+                                       && old_dcd_state && !portdata->dcd_state) {
+                               tty_hangup(port->tty);
+                       }
+               } else
+                       dbg("%s: type %x req %x", __FUNCTION__, req_pkt->bRequestType,req_pkt->bRequest);
+       } else
+               dbg("%s: error %d", __FUNCTION__, urb->status);
+
+       /* Resubmit urb so we continue receiving IRQ data */
+       if (urb->status != -ESHUTDOWN) {
+               urb->dev = serial->dev;
+               err = usb_submit_urb(urb, GFP_ATOMIC);
+               if (err)
+                       dbg("%s: resubmit intr urb failed. (%d)", __FUNCTION__, err);
+       }
+}
+
+
+static int
+option_write_room (struct usb_serial_port *port)
+{
+       struct option_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 += OUT_BUFLEN;
+
+       dbg("%s: %d", __FUNCTION__, data_len);
+       return data_len;
+}
+
+
+static int
+option_chars_in_buffer (struct usb_serial_port *port)
+{
+       struct option_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;
+}
+
+
+static int
+option_open (struct usb_serial_port *port, struct file *filp)
+{
+       struct option_port_private      *portdata;
+       struct usb_serial               *serial = port->serial;
+       int                             i, err;
+       struct urb                      *urb;
+
+       portdata = usb_get_serial_port_data(port);
+
+       dbg("%s", __FUNCTION__);
+
+       /* Set some sane defaults */
+       portdata->rts_state = 1;
+       portdata->dtr_state = 1;
+
+       /* 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)
+                       continue;
+               if (urb->dev != serial->dev) {
+                       dbg("%s: dev %p != %p", __FUNCTION__, urb->dev, serial->dev);
+                       continue;
+               }
+
+               /* make sure endpoint data toggle is synchronized with the device */
+
+               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);
+               }
+       }
+
+       /* 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;
+
+       option_send_setup(port);
+
+       return (0);
+}
+
+static inline void
+stop_urb(struct urb *urb)
+{
+       if (urb && urb->status == -EINPROGRESS) {
+               urb->transfer_flags &= ~URB_ASYNC_UNLINK;
+               usb_kill_urb(urb);
+       }
+}
+
+static void
+option_close(struct usb_serial_port *port, struct file *filp)
+{
+       int                     i;
+       struct usb_serial       *serial = port->serial;
+       struct option_port_private      *portdata;
+
+       dbg("%s", __FUNCTION__);
+       portdata = usb_get_serial_port_data(port);
+
+       portdata->rts_state = 0;
+       portdata->dtr_state = 0;
+
+       if (serial->dev) {
+               option_send_setup(port);
+
+               /* Stop reading/writing urbs */
+               for (i = 0; i < N_IN_URB; i++)
+                       stop_urb(portdata->in_urbs[i]);
+               for (i = 0; i < N_OUT_URB; i++)
+                       stop_urb(portdata->out_urbs[i]);
+       }
+       port->tty = NULL;
+}
+
+
+/* Helper functions used by option_setup_urbs */
+static struct urb *
+option_setup_urb (struct usb_serial *serial, int endpoint,
+                  int dir, void *ctx, char *buf, int len,
+                  void (*callback)(struct urb *, struct pt_regs *regs))
+{
+       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
+option_setup_urbs(struct usb_serial *serial)
+{
+       int                             j;
+       struct usb_serial_port          *port;
+       struct option_port_private      *portdata;
+
+       dbg("%s", __FUNCTION__);
+
+       port = serial->port[0];
+       portdata = usb_get_serial_port_data(port);
+
+       /* Do indat endpoints first */
+       for (j = 0; j <= N_IN_URB; ++j) {
+               portdata->in_urbs[j] = option_setup_urb (serial,
+                  port->bulk_in_endpointAddress, USB_DIR_IN, port,
+                  portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
+       }
+
+       /* outdat endpoints */
+       for (j = 0; j <= N_OUT_URB; ++j) {
+               portdata->out_urbs[j] = option_setup_urb (serial,
+                  port->bulk_out_endpointAddress, USB_DIR_OUT, port,
+                  portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
+       }
+}
+
+
+static int
+option_send_setup(struct usb_serial_port *port)
+{
+       struct usb_serial *serial = port->serial;
+       struct option_port_private *portdata;
+
+       dbg("%s", __FUNCTION__);
+
+       portdata = usb_get_serial_port_data(port);
+
+       if (port->tty) {
+               int val = 0;
+               if (portdata->dtr_state)
+                       val |= 0x01;
+               if (portdata->rts_state)
+                       val |= 0x02;
+
+               return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                                       0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+       }
+
+       return 0;
+}
+
+
+static int
+option_startup (struct usb_serial *serial)
+{
+       int                             i, err;
+       struct usb_serial_port          *port;
+       struct option_port_private      *portdata;
+
+       dbg("%s", __FUNCTION__);
+
+       /* Now setup per port private data */
+       for (i = 0; i < serial->num_ports; i++) {
+               port = serial->port[i];
+               portdata = kmalloc(sizeof(struct option_port_private), GFP_KERNEL);
+               if (!portdata) {
+                       dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i);
+                       return (1);
+               }
+               memset(portdata, 0, sizeof(struct option_port_private));
+
+               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);
+       }
+
+       option_setup_urbs(serial);
+
+       return (0);
+}
+
+static void
+option_shutdown (struct usb_serial *serial)
+{
+       int                             i, j;
+       struct usb_serial_port          *port;
+       struct option_port_private      *portdata;
+
+       dbg("%s", __FUNCTION__);
+
+       /* Stop reading/writing urbs */
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               portdata = usb_get_serial_port_data(port);
+               for (j = 0; j < N_IN_URB; j++)
+                       stop_urb(portdata->in_urbs[j]);
+               for (j = 0; j < N_OUT_URB; j++)
+                       stop_urb(portdata->out_urbs[j]);
+       }
+
+       /* Now free them */
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               portdata = usb_get_serial_port_data(port);
+
+               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;
+                       }
+               }
+               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];
+               kfree(usb_get_serial_port_data(port));
+       }
+}
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug messages");
+
index 4536f63faaeaa299ffd6c719e23660d401f87f0f..5da76dd8fb285681d4f5774b2468dc14794ec910 100644 (file)
@@ -1297,13 +1297,6 @@ static int __init usb_serial_init(void)
                goto exit_bus;
        }
 
-       /* register the generic driver, if we should */
-       result = usb_serial_generic_register(debug);
-       if (result < 0) {
-               err("%s - registering generic driver failed", __FUNCTION__);
-               goto exit_generic;
-       }
-
        usb_serial_tty_driver->owner = THIS_MODULE;
        usb_serial_tty_driver->driver_name = "usbserial";
        usb_serial_tty_driver->devfs_name = "usb/tts/";
@@ -1329,17 +1322,24 @@ static int __init usb_serial_init(void)
                goto exit_tty;
        }
 
+       /* register the generic driver, if we should */
+       result = usb_serial_generic_register(debug);
+       if (result < 0) {
+               err("%s - registering generic driver failed", __FUNCTION__);
+               goto exit_generic;
+       }
+
        info(DRIVER_DESC " " DRIVER_VERSION);
 
        return result;
 
+exit_generic:
+       usb_deregister(&usb_serial_driver);
+
 exit_tty:
        tty_unregister_driver(usb_serial_tty_driver);
 
 exit_reg_driver:
-       usb_serial_generic_deregister();
-
-exit_generic:
        bus_unregister(&usb_serial_bus_type);
 
 exit_bus:
index d76483706bc955e9f1c86f36a69749d7c46af319..5a9321705a7426000e1197813c35b54123c85f70 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/cdrom.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
 
 #include "debug.h"
 #include "scsi.h"
index 7eff03d9b041c0de75a5161912acc1649e28a1b6..f3b60288696cfbc1162418368892773959562dbe 100644 (file)
@@ -786,7 +786,7 @@ static int usbat_flash_check_media(struct us_data *us,
        if (rc != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
-       // Check for media existance
+       // Check for media existence
        rc = usbat_flash_check_media_present(uio);
        if (rc == USBAT_FLASH_MEDIA_NONE) {
                info->sense_key = 0x02;
index bbda63c24c4d686d27723db866f0c439a5542246..9fcc7bd1fbe427f2f55dd1dd4a774cccc617e93b 100644 (file)
@@ -1,5 +1,5 @@
 /* Driver for USB Mass Storage compliant devices
- * Ununsual Devices File
+ * Unusual Devices File
  *
  * $Id: unusual_devs.h,v 1.32 2002/02/25 02:41:24 mdharm Exp $
  *
  * USB development list <linux-usb-devel@lists.sourceforge.net>.
  */
 
+/* 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),
+
 UNUSUAL_DEV(  0x03ee, 0x6901, 0x0000, 0x0100,
                "Mitsumi",
                "USB FDD",
@@ -854,6 +862,15 @@ UNUSUAL_DEV(  0x090a, 0x1001, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_BULK, NULL,
                US_FL_NEED_OVERRIDE ),
 
+/* Reported by Filippo Bardelli <filibard@libero.it>
+ * The device reports a subclass of RBC, which is wrong.
+ */
+UNUSUAL_DEV(  0x090a, 0x1050, 0x0100, 0x0100,
+               "Trumpion Microelectronics, Inc.",
+               "33520 USB Digital Voice Recorder",
+               US_SC_UFI, US_PR_DEVICE, NULL,
+               0),
+
 /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */
 UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999,
                "Trumpion",
@@ -994,6 +1011,13 @@ UNUSUAL_DEV(  0x1019, 0x0c55, 0x0000, 0x9999,
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
                0 ),
 
+/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
+UNUSUAL_DEV(  0x132b, 0x000b, 0x0001, 0x0001,
+               "Minolta",
+               "Dimage Z10",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               0 ),
+
 /* Reported by Kotrla Vitezslav <kotrla@ceb.cz> */
 UNUSUAL_DEV(  0x1370, 0x6828, 0x0110, 0x0110,
                "SWISSBIT",
index ee25b9e8db60992fd8a6e6d041dc12fb49775a44..47a6b12bc9685af76cb8f844da52b49803f6293a 100644 (file)
@@ -2374,10 +2374,9 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
        } while (   rinfo->fb_base == 0 &&
                  ((rinfo->mapped_vram /=2) >= MIN_MAPPED_VRAM) );
 
-       if (rinfo->fb_base)
-               memset_io(rinfo->fb_base, 0, rinfo->mapped_vram);
-       else {
-               printk (KERN_ERR "radeonfb (%s): cannot map FB\n", pci_name(rinfo->pdev));
+       if (rinfo->fb_base == NULL) {
+               printk (KERN_ERR "radeonfb (%s): cannot map FB\n",
+                       pci_name(rinfo->pdev));
                ret = -EIO;
                goto err_unmap_rom;
        }
index 208a68ceb63bc267f88288feab815be80c786c60..7705070191d94077373ead5b2176598780d360a3 100644 (file)
@@ -1312,7 +1312,7 @@ int fb_get_options(char *name, char **option)
  *     Returns zero.
  *
  */
-int __init video_setup(char *options)
+static int __init video_setup(char *options)
 {
        int i, global = 0;
 
index 2bdda4010b81dd92ea0fb704c3fd1a698f6c72a5..277d733c6d00a4150436c42b234aec4edc572b15 100644 (file)
@@ -241,7 +241,7 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf)
        struct fb_info *fb_info =
                (struct fb_info *)class_get_devdata(class_device);
        return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual,
-                       fb_info->var.xres_virtual);
+                       fb_info->var.yres_virtual);
 }
 
 static ssize_t store_cmap(struct class_device *class_device, const char * buf,
@@ -354,7 +354,7 @@ static ssize_t show_pan(struct class_device *class_device, char *buf)
                        fb_info->var.xoffset);
 }
 
-struct class_device_attribute class_device_attrs[] = {
+static struct class_device_attribute class_device_attrs[] = {
        __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
        __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
        __ATTR(color_map, S_IRUGO|S_IWUSR, show_cmap, store_cmap),
index e04d3e8b254967084683b949d2bf1abbac2492db..a9a618f2aa6a25316522c16f8649d13ba52eec34 100644 (file)
@@ -1000,8 +1000,10 @@ static int i810_check_params(struct fb_var_screeninfo *var,
 
        if (fb_validate_mode(var, info)) {
                if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) {
-                       int default_sync = (hsync1-HFMIN)|(hsync2-HFMAX)
-                                           |(vsync1-VFMIN)|(vsync2-VFMAX);
+                       int default_sync = (info->monspecs.hfmin-HFMIN)
+                                               |(info->monspecs.hfmax-HFMAX)
+                                               |(info->monspecs.vfmin-VFMIN)
+                                               |(info->monspecs.vfmax-VFMAX);
                        printk("i810fb: invalid video mode%s\n",
                            default_sync ? "" :
                            ". Specifying vsyncN/hsyncN parameters may help");
index 549e229392604359f46ed629d916b4ea89674226..25f9a9a65c24938c23ebd3e0fb9ad164022baacd 100644 (file)
@@ -228,17 +228,17 @@ MODULE_DESCRIPTION(
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_DEVICE_TABLE(pci, intelfb_pci_table);
 
-static int accel        __initdata = 1;
-static int vram         __initdata = 4;
-static int hwcursor     __initdata = 1;
-static int mtrr         __initdata = 1;
-static int fixed        __initdata = 0;
-static int noinit       __initdata = 0;
-static int noregister   __initdata = 0;
-static int probeonly    __initdata = 0;
-static int idonly       __initdata = 0;
-static int bailearly    __initdata = 0;
-static char *mode       __initdata = NULL;
+static int accel        = 1;
+static int vram         = 4;
+static int hwcursor     = 1;
+static int mtrr         = 1;
+static int fixed        = 0;
+static int noinit       = 0;
+static int noregister   = 0;
+static int probeonly    = 0;
+static int idonly       = 0;
+static int bailearly    = 0;
+static char *mode       = NULL;
 
 module_param(accel, bool, S_IRUGO);
 MODULE_PARM_DESC(accel, "Enable console acceleration");
index de5a0f383600832ec8f216764827376b0e2f66d9..2fc71081f7e7077749ff659ec9176d0c7f75f6c1 100644 (file)
@@ -387,3 +387,4 @@ int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
 }
 EXPORT_SYMBOL(mac_find_mode);
 
+MODULE_LICENSE("GPL");
index 1994054d45ff2ad6e0bb53a3205124abfeed7a16..ecfd72178dbb3fce2cc0d8b9d9b8b338b9dbcc3e 100644 (file)
@@ -1384,7 +1384,7 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 /*             HELPER: SetLVDSetc            */
 /*********************************************/
 
-void
+static void
 SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
    USHORT temp;
@@ -1625,7 +1625,7 @@ SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
 /*             HELPER: GetVBType             */
 /*********************************************/
 
-void
+static void
 SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27;
index 35030d300431b5adec70303581ebcd757dd0c2df..7e36b7ac1470570b4fc43e9b4168bd36b0a98e94 100644 (file)
@@ -2394,11 +2394,9 @@ void     SiS_SetRegOR(SISIOADDRESS Port,USHORT Index, USHORT DataOR);
 void   SiS_DisplayOn(SiS_Private *SiS_Pr);
 void   SiS_DisplayOff(SiS_Private *SiS_Pr);
 void   SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
-void   SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void   SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
 void   SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
-void   SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 BOOLEAN        SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex);
 UCHAR  SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
 USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
@@ -2444,7 +2442,6 @@ extern void     SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT Mod
 extern void     SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 extern void    SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
 extern void     SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-extern void     SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 extern void     SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO);
 extern BOOLEAN  SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT);
 extern USHORT   SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
index 2bc5b80979103c93fe0cf16bc31c283ac5debaa1..274dacd54bb82d269f982333ad1c2bdf79e1d5fc 100644 (file)
@@ -86,6 +86,7 @@
 #define SiS_I2CDELAYSHORT  150
 
 static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
+static void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx);
 
 /*********************************************/
 /*         HELPER: Lock/Unlock CRT2          */
@@ -100,7 +101,7 @@ SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
 }
 
-void
+static void
 SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
    if(HwInfo->jChipType >= SIS_315H)
@@ -4236,7 +4237,7 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
  * from outside the context of a mode switch!
  * MUST call getVBType before calling this
  */
-void
+static void
 SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT temp=0,tempah;
@@ -9219,7 +9220,7 @@ SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
   SiS_SetChReg(SiS_Pr, tempbx, 0);
 }
 
-void
+static void
 SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
@@ -9323,7 +9324,7 @@ SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 
 /* Read from Chrontel 70xx */
 /* Parameter is [Register no (S7-S0)] */
-USHORT
+static USHORT
 SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
index f05aebc994b4fcc6f596c3a93006fdd42b4095d4..f84eb54164a5d8fe4069231ebe77fe5b25012be1 100644 (file)
@@ -293,7 +293,6 @@ static UCHAR SiS300_TrumpionData[7][80] = {
 #endif
 
 void   SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void   SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void   SiS_EnableCRT2(SiS_Private *SiS_Pr);
 USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
 void   SiS_WaitRetrace1(SiS_Private *SiS_Pr);
@@ -310,7 +309,6 @@ USHORT      SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
 USHORT SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
 void   SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void   SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 BOOLEAN        SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo);
 void   SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void   SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
@@ -319,8 +317,6 @@ void        SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
 USHORT         SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
 void           SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
 USHORT         SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-void           SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT         SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
 void           SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
 #ifdef SIS315H
 static void    SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
index b773c98f6513d1fdb68639290e93a16f0336c9d8..6982660368193735cc2034c9f68dee1627b028b5 100644 (file)
@@ -4762,7 +4762,8 @@ static void __devinit sisfb_post_sis315330(struct pci_dev *pdev)
 #endif
 
 
-int __devinit sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit sisfb_probe(struct pci_dev *pdev,
+                                const struct pci_device_id *ent)
 {
        struct sisfb_chip_info  *chipinfo = &sisfb_chip_info[ent->driver_data];
        struct sis_video_info   *ivideo = NULL;
@@ -5940,7 +5941,7 @@ MODULE_PARM_DESC(videoram,
 #endif
 #endif
 
-int __devinit sisfb_init_module(void)
+static int __devinit sisfb_init_module(void)
 {
        sisfb_setdefaultparms();
 
index 672a31924f3cd107a8bdd97155dd58f2451ebf24..e172180a1d8c3f0173adae9101175c1454111ce3 100644 (file)
@@ -47,7 +47,7 @@ static struct file_operations bad_file_ops =
        .get_unmapped_area = EIO_ERROR,
 };
 
-struct inode_operations bad_inode_ops =
+static struct inode_operations bad_inode_ops =
 {
        .create         = EIO_ERROR,
        .lookup         = EIO_ERROR,
index ce9423bb2de319d095a3ac5d8e762dcd6d8b3913..c374be51b041a698341ddbda6b9fc5fe1329df46 100644 (file)
@@ -251,7 +251,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
        }
 
        /* Populate argv and envp */
-       p = current->mm->arg_start;
+       p = current->mm->arg_end = current->mm->arg_start;
        while (argc-- > 0) {
                size_t len;
                __put_user((elf_addr_t)p, argv++);
@@ -1301,7 +1301,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
 static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
                       struct mm_struct *mm)
 {
-       int i, len;
+       unsigned int i, len;
        
        /* first copy the parameters from user space */
        memset(psinfo, 0, sizeof(struct elf_prpsinfo));
index f0cd67d9d31b96393d4f33680dee26393fc9797c..c8998dc668824df41ef382e65af0b76124d41536 100644 (file)
@@ -520,7 +520,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
 
                down_write(&current->mm->mmap_sem);
-               textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0);
+               textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 0);
                up_write(&current->mm->mmap_sem);
                if (!textpos  || textpos >= (unsigned long) -4096) {
                        if (!textpos)
@@ -532,7 +532,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                down_write(&current->mm->mmap_sem);
                realdatastart = do_mmap(0, 0, data_len + extra +
                                MAX_SHARED_LIBS * sizeof(unsigned long),
-                               PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0);
+                               PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
                up_write(&current->mm->mmap_sem);
 
                if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -574,7 +574,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                down_write(&current->mm->mmap_sem);
                textpos = do_mmap(0, 0, text_len + data_len + extra +
                                        MAX_SHARED_LIBS * sizeof(unsigned long),
-                               PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0);
+                               PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
                up_write(&current->mm->mmap_sem);
                if (!textpos  || textpos >= (unsigned long) -4096) {
                        if (!textpos)
index d19d07c49ad319a3375b983933e8725029f3a973..c0cbd1bc1a02106dbaea65cb22d20bf22543f84a 100644 (file)
@@ -530,7 +530,7 @@ int check_disk_change(struct block_device *bdev)
        if (!bdops->media_changed(bdev->bd_disk))
                return 0;
 
-       if (__invalidate_device(bdev, 0))
+       if (__invalidate_device(bdev))
                printk("VFS: busy inodes on changed media.\n");
 
        if (bdops->revalidate_disk)
index 5f525b3c6d9f04d520d117295f3d880d29e7e9ec..7e9e409feaa744d13e471c1209318a0a9ef138d3 100644 (file)
@@ -1210,7 +1210,7 @@ grow_buffers(struct block_device *bdev, sector_t block, int size)
        return 1;
 }
 
-struct buffer_head *
+static struct buffer_head *
 __getblk_slow(struct block_device *bdev, sector_t block, int size)
 {
        /* Size must be multiple of hard sectorsize */
@@ -1809,7 +1809,6 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
        } while (bh != head);
 
        do {
-               get_bh(bh);
                if (!buffer_mapped(bh))
                        continue;
                /*
@@ -1838,7 +1837,6 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
         */
        BUG_ON(PageWriteback(page));
        set_page_writeback(page);
-       unlock_page(page);
 
        do {
                struct buffer_head *next = bh->b_this_page;
@@ -1846,9 +1844,9 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
                        submit_bh(WRITE, bh);
                        nr_underway++;
                }
-               put_bh(bh);
                bh = next;
        } while (bh != head);
+       unlock_page(page);
 
        err = 0;
 done:
@@ -1887,7 +1885,6 @@ recover:
        bh = head;
        /* Recovery: lock and submit the mapped buffers */
        do {
-               get_bh(bh);
                if (buffer_mapped(bh) && buffer_dirty(bh)) {
                        lock_buffer(bh);
                        mark_buffer_async_write(bh);
@@ -1910,7 +1907,6 @@ recover:
                        submit_bh(WRITE, bh);
                        nr_underway++;
                }
-               put_bh(bh);
                bh = next;
        } while (bh != head);
        goto done;
@@ -1953,7 +1949,7 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
                if (!buffer_mapped(bh)) {
                        err = get_block(inode, block, bh, 1);
                        if (err)
-                               goto out;
+                               break;
                        if (buffer_new(bh)) {
                                clear_buffer_new(bh);
                                unmap_underlying_metadata(bh->b_bdev,
@@ -1995,10 +1991,12 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
        while(wait_bh > wait) {
                wait_on_buffer(*--wait_bh);
                if (!buffer_uptodate(*wait_bh))
-                       return -EIO;
+                       err = -EIO;
        }
-       return 0;
-out:
+       if (!err)
+               return err;
+
+       /* Error case: */
        /*
         * Zero out any newly allocated blocks to avoid exposing stale
         * data.  If BH_New is set, we know that the block was newly
@@ -2096,9 +2094,12 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
                        continue;
 
                if (!buffer_mapped(bh)) {
+                       int err = 0;
+
                        fully_mapped = 0;
                        if (iblock < lblock) {
-                               if (get_block(inode, iblock, bh, 0))
+                               err = get_block(inode, iblock, bh, 0);
+                               if (err)
                                        SetPageError(page);
                        }
                        if (!buffer_mapped(bh)) {
@@ -2106,7 +2107,8 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
                                memset(kaddr + i * blocksize, 0, blocksize);
                                flush_dcache_page(page);
                                kunmap_atomic(kaddr, KM_USER0);
-                               set_buffer_uptodate(bh);
+                               if (!err)
+                                       set_buffer_uptodate(bh);
                                continue;
                        }
                        /*
@@ -3115,7 +3117,7 @@ void __init buffer_init(void)
 
        bh_cachep = kmem_cache_create("buffer_head",
                        sizeof(struct buffer_head), 0,
-                       SLAB_PANIC, init_buffer_head, NULL);
+                       SLAB_RECLAIM_ACCOUNT|SLAB_PANIC, init_buffer_head, NULL);
 
        /*
         * Limit the bh occupancy to 10% of ZONE_NORMAL
index a745b1d9e5458684205c38da349d7e850ff66d81..c1e3537909fc1ae78f829220700810b78f371480 100644 (file)
@@ -328,7 +328,7 @@ void cd_forget(struct inode *inode)
        spin_unlock(&cdev_lock);
 }
 
-void cdev_purge(struct cdev *cdev)
+static void cdev_purge(struct cdev *cdev)
 {
        spin_lock(&cdev_lock);
        while (!list_empty(&cdev->list)) {
index 95483baab706baa9921eb14757c08da90970fdb5..dab4774ee7bbb6c7d9a92655a4a600d80c0da896 100644 (file)
@@ -6,7 +6,8 @@ kills the cifsd thread (NB: killing the cifs kernel threads is not
 recommended, unmount and rmmod cifs will kill them when they are
 no longer needed).  Fix readdir to ASCII servers (ie older servers
 which do not support Unicode) and also require asterik.
-
+Fix out of memory case in which data could be written one page
+off in the page cache.
 
 Version 1.33
 ------------
index 7b4ac096cd114d34e623bafaed91b85ba4a95e62..34b0cf7111f384aff0ea2afc9504b95fd67cd564 100644 (file)
@@ -32,9 +32,9 @@ the cifs download to your kernel build directory e.g.
 6) make modules (or "make" if CIFS VFS not to be built as a module)
 
 For Linux 2.6:
-1) Download the kernel (e.g. from http://www.kernel.org or from bitkeeper
-at bk://linux.bkbits.net/linux-2.5) and change directory into the top
-of the kernel directory tree (e.g. /usr/src/linux-2.5.73)
+1) Download the kernel (e.g. from http://www.kernel.org)
+and change directory into the top of the kernel directory tree
+(e.g. /usr/src/linux-2.5.73)
 2) make menuconfig (or make xconfig)
 3) select cifs from within the network filesystem choices
 4) save and exit
@@ -371,7 +371,7 @@ A partial list of the supported mount options follows:
                on newly created files, directories, and devices (create, 
                mkdir, mknod) which will result in the server setting the
                uid and gid to the default (usually the server uid of the
-               usern who mounted the share).  Letting the server (rather than
+               user who mounted the share).  Letting the server (rather than
                the client) set the uid and gid is the default. This
                parameter has no effect if the CIFS Unix Extensions are not
                negotiated.
@@ -384,7 +384,7 @@ A partial list of the supported mount options follows:
                client (e.g. when the application is doing large sequential
                reads bigger than page size without rereading the same data) 
                this can provide better performance than the default
-               behavior which caches reads (reaadahead) and writes 
+               behavior which caches reads (readahead) and writes 
                (writebehind) through the local Linux client pagecache 
                if oplock (caching token) is granted and held. Note that
                direct allows write operations larger than page size
index d00b3bfe1a5213830c6aec6c39f56d0910be390a..78af5850c558127bde1a5c929e72f90cf7470403 100644 (file)
@@ -96,5 +96,5 @@ extern ssize_t        cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
 extern int cifs_ioctl (struct inode * inode, struct file * filep,
                       unsigned int command, unsigned long arg);
-#define CIFS_VERSION   "1.34"
+#define CIFS_VERSION   "1.35"
 #endif                         /* _CIFSFS_H */
index 0010511083fce44618d4e8c522d588a9a983a668..ea239dea571e1f0a02374079ca0e918bf072cb01 100644 (file)
@@ -228,7 +228,7 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
                        const struct nls_table *nls_codepage, 
                        int remap_special_chars);
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
-extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen,
+extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
                        const struct nls_table * codepage);
 extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
                        const struct nls_table * cp, int mapChars);
index 741ff0c69f37f44154247020649b4104afff0cda..3c628bf667a5f010ff17c14d2ffc04f499d80c7d 100644 (file)
@@ -567,7 +567,7 @@ DelFileRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->fileName, fileName, 
+                   cifsConvertToUCS((__le16 *) pSMB->fileName, fileName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -665,7 +665,7 @@ MkDirRetry:
                return rc;
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-               name_len = cifsConvertToUCS((__u16 *) pSMB->DirName, name, 
+               name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name, 
                                            PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -719,7 +719,7 @@ openRetry:
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                count = 1;      /* account for one byte pad to word boundary */
                name_len =
-                   cifsConvertToUCS((__u16 *) (pSMB->fileName + 1),
+                   cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
                                     fileName, PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -1141,7 +1141,7 @@ renameRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, 
+                   cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -1149,7 +1149,7 @@ renameRetry:
        /* protocol requires ASCII signature byte on Unicode string */
                pSMB->OldFileName[name_len + 1] = 0x00;
                name_len2 =
-                   cifsConvertToUCS((__u16 *) &pSMB->OldFileName[name_len + 2],
+                   cifsConvertToUCS((__le16 *) &pSMB->OldFileName[name_len + 2],
                                     toName, PATH_MAX, nls_codepage, remap);
                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
                name_len2 *= 2; /* convert to bytes */
@@ -1236,10 +1236,10 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
        /* unicode only call */
        if(target_name == NULL) {
                sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid);
-               len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name,
+               len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
                                        dummy_string, 24, nls_codepage, remap);
        } else {
-               len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name,
+               len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
                                        target_name, PATH_MAX, nls_codepage, remap);
        }
        rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
@@ -1296,7 +1296,7 @@ copyRetry:
        pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-               name_len = cifsConvertToUCS((__u16 *) pSMB->OldFileName, 
+               name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName, 
                                            fromName, PATH_MAX, nls_codepage,
                                            remap);
                name_len++;     /* trailing null */
@@ -1304,7 +1304,7 @@ copyRetry:
                pSMB->OldFileName[name_len] = 0x04;     /* pad */
                /* protocol requires ASCII signature byte on Unicode string */
                pSMB->OldFileName[name_len + 1] = 0x00;
-               name_len2 = cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], 
+               name_len2 = cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], 
                                toName, PATH_MAX, nls_codepage, remap);
                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
                name_len2 *= 2; /* convert to bytes */
@@ -1453,7 +1453,7 @@ createHardLinkRetry:
                return rc;
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-               name_len = cifsConvertToUCS((__u16 *) pSMB->FileName, toName,
+               name_len = cifsConvertToUCS((__le16 *) pSMB->FileName, toName,
                                            PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -1476,7 +1476,7 @@ createHardLinkRetry:
        data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len_target =
-                   cifsConvertToUCS((__u16 *) data_offset, fromName, PATH_MAX,
+                   cifsConvertToUCS((__le16 *) data_offset, fromName, PATH_MAX,
                                     nls_codepage, remap);
                name_len_target++;      /* trailing null */
                name_len_target *= 2;
@@ -1546,14 +1546,14 @@ winCreateHardLinkRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName,
+                   cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
                pSMB->OldFileName[name_len] = 0;        /* pad */
                pSMB->OldFileName[name_len + 1] = 0x04; 
                name_len2 =
-                   cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], 
+                   cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], 
                                     toName, PATH_MAX, nls_codepage, remap);
                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
                name_len2 *= 2; /* convert to bytes */
@@ -1939,7 +1939,7 @@ queryAclRetry:
                                                                                                                                              
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                       cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 
+                       cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 
                                         PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2024,7 +2024,7 @@ setAclRetry:
                return rc;
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                       cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 
+                       cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 
                                      PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2188,7 +2188,7 @@ QPathInfoRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2269,7 +2269,7 @@ UnixQPathInfoRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, searchName,
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
                                  PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2350,7 +2350,7 @@ findUniqueRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX
                                  /* find define for this maxpathcomponent */
                                  , nls_codepage);
                name_len++;     /* trailing null */
@@ -2435,7 +2435,7 @@ findFirstRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName,searchName,
+                   cifsConvertToUCS((__le16 *) pSMB->FileName,searchName,
                                 PATH_MAX, nls_codepage, remap);
                /* We can not add the asterik earlier in case
                it got remapped to 0xF03A as if it were part of the
@@ -2726,7 +2726,7 @@ GetInodeNumberRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                       cifsConvertToUCS((__u16 *) pSMB->FileName, searchName,
+                       cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
                                PATH_MAX,nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2837,7 +2837,7 @@ getDFSRetry:
        if (ses->capabilities & CAP_UNICODE) {
                pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->RequestFileName,
+                   cifsConvertToUCS((__le16 *) pSMB->RequestFileName,
                                     searchName, PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3369,7 +3369,7 @@ SetEOFRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, fileName,
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3627,7 +3627,7 @@ SetTimesRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, fileName,
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3708,7 +3708,7 @@ SetAttrLgcyRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                       ConvertToUCS((wchar_t *) pSMB->fileName, fileName, 
+                       ConvertToUCS((__le16 *) pSMB->fileName, fileName, 
                                PATH_MAX, nls_codepage);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3759,7 +3759,7 @@ setPermsRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3904,7 +3904,7 @@ QAllEAsRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -4047,7 +4047,7 @@ QEARetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -4194,7 +4194,7 @@ SetEARetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
index e3137aa48cdd6a4f4dbc5df53f03deab774f84ee..3f3538d4a1fad105c0a776ef5f6d6e18fef0ff6c 100644 (file)
@@ -392,7 +392,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
                rc = 0;
                d_add(direntry, NULL);
        } else {
-               cERROR(1,("Error 0x%x or on cifs_get_inode_info in lookup",rc));
+               cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
+                          rc,full_path));
                /* BB special case check for Access Denied - watch security 
                exposure of returning dir info implicitly via different rc 
                if file exists or not but no access BB */
index dde2d251fc3d6b0d387559bf5c590ede89bcf80a..30ab70ce554716df92739f0b1643ce79053497e7 100644 (file)
@@ -1352,6 +1352,8 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
                                      GFP_KERNEL)) {
                        page_cache_release(page);
                        cFYI(1, ("Add page cache failed"));
+                       data += PAGE_CACHE_SIZE;
+                       bytes_read -= PAGE_CACHE_SIZE;
                        continue;
                }
 
index 670947288262c099a0f32ecffd3e4ca110ad9eb4..8d336a90025584a6fb524001ef71c123b6d881ec 100644 (file)
@@ -82,12 +82,12 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                /* get new inode */
                if (*pinode == NULL) {
                        *pinode = new_inode(sb);
-                       if(*pinode == NULL) 
+                       if (*pinode == NULL) 
                                return -ENOMEM;
                        /* Is an i_ino of zero legal? */
                        /* Are there sanity checks we can use to ensure that
                           the server is really filling in that field? */
-                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
+                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
                                (*pinode)->i_ino =
                                        (unsigned long)findData.UniqueId;
                        } /* note ino incremented to unique num in new_inode */
@@ -134,7 +134,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                inode->i_gid = le64_to_cpu(findData.Gid);
                inode->i_nlink = le64_to_cpu(findData.Nlinks);
 
-               if(is_size_safe_to_change(cifsInfo)) {
+               if (is_size_safe_to_change(cifsInfo)) {
                /* can not safely change the file size here if the
                   client is writing to it due to potential races */
 
@@ -162,7 +162,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                if (S_ISREG(inode->i_mode)) {
                        cFYI(1, (" File inode "));
                        inode->i_op = &cifs_file_inode_ops;
-                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
+                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
                                inode->i_fop = &cifs_file_direct_ops;
                        else
                                inode->i_fop = &cifs_file_ops;
@@ -198,17 +198,17 @@ int cifs_get_inode_info(struct inode **pinode,
        pTcon = cifs_sb->tcon;
        cFYI(1,("Getting info on %s ", search_path));
 
-       if((pfindData == NULL) && (*pinode != NULL)) {
-               if(CIFS_I(*pinode)->clientCanCacheRead) {
+       if ((pfindData == NULL) && (*pinode != NULL)) {
+               if (CIFS_I(*pinode)->clientCanCacheRead) {
                        cFYI(1,("No need to revalidate cached inode sizes"));
                        return rc;
                }
        }
 
        /* if file info not passed in then get it from server */
-       if(pfindData == NULL) {
+       if (pfindData == NULL) {
                buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
-               if(buf == NULL)
+               if (buf == NULL)
                        return -ENOMEM;
                pfindData = (FILE_ALL_INFO *)buf;
                /* could do find first instead but this returns more info */
@@ -268,7 +268,7 @@ int cifs_get_inode_info(struct inode **pinode,
                           IndexNumber field is not guaranteed unique? */
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL                
-                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){
+                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){
                                int rc1 = 0;
                                __u64 inode_num;
 
@@ -277,7 +277,7 @@ int cifs_get_inode_info(struct inode **pinode,
                                        cifs_sb->local_nls,
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
-                               if(rc1) {
+                               if (rc1) {
                                        cFYI(1,("GetSrvInodeNum rc %d", rc1));
                                        /* BB EOPNOSUPP disable SERVER_INUM? */
                                } else /* do we need cast or hash to ino? */
@@ -355,7 +355,7 @@ int cifs_get_inode_info(struct inode **pinode,
                if (S_ISREG(inode->i_mode)) {
                        cFYI(1, (" File inode "));
                        inode->i_op = &cifs_file_inode_ops;
-                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
+                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
                                inode->i_fop = &cifs_file_direct_ops;
                        else
                                inode->i_fop = &cifs_file_ops;
@@ -422,7 +422,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 
        if (!rc) {
-               direntry->d_inode->i_nlink--;
+               if (direntry->d_inode)
+                       direntry->d_inode->i_nlink--;
        } else if (rc == -ENOENT) {
                d_drop(direntry);
        } else if (rc == -ETXTBSY) {
@@ -440,7 +441,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                                              cifs_sb->mnt_cifs_flags & 
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        CIFSSMBClose(xid, pTcon, netfid);
-                       direntry->d_inode->i_nlink--;
+                       if (direntry->d_inode)
+                               direntry->d_inode->i_nlink--;
                }
        } else if (rc == -EACCES) {
                /* try only if r/o attribute set in local lookup data? */
@@ -494,7 +496,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                                            cifs_sb->mnt_cifs_flags & 
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        if (!rc) {
-                               direntry->d_inode->i_nlink--;
+                               if (direntry->d_inode)
+                                       direntry->d_inode->i_nlink--;
                        } else if (rc == -ETXTBSY) {
                                int oplock = FALSE;
                                __u16 netfid;
@@ -514,17 +517,20 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                                                cifs_sb->mnt_cifs_flags &
                                                    CIFS_MOUNT_MAP_SPECIAL_CHR);
                                        CIFSSMBClose(xid, pTcon, netfid);
-                                       direntry->d_inode->i_nlink--;
+                                       if (direntry->d_inode)
+                                               direntry->d_inode->i_nlink--;
                                }
                        /* BB if rc = -ETXTBUSY goto the rename logic BB */
                        }
                }
        }
-       cifsInode = CIFS_I(direntry->d_inode);
-       cifsInode->time = 0;    /* will force revalidate to get info when
-                                  needed */
-       direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
-               current_fs_time(inode->i_sb);
+       if (direntry->d_inode) {
+               cifsInode = CIFS_I(direntry->d_inode);
+               cifsInode->time = 0;    /* will force revalidate to get info
+                                          when needed */
+               direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
+       }
+       inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
        cifsInode = CIFS_I(inode);
        cifsInode->time = 0;    /* force revalidate of dir as well */
 
@@ -576,7 +582,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                if (direntry->d_inode)
                        direntry->d_inode->i_nlink = 2;
                if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
-                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
                                CIFSSMBUnixSetPerms(xid, pTcon, full_path,
                                                    mode,
                                                    (__u64)current->euid,
index db14b503d89e596dfa2c4102fca9469a7e814ce2..072b4ee8c53e1a28c51002d8a331c497a0b8c05c 100644 (file)
@@ -571,6 +571,7 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
                                break;
                        case UNI_LESSTHAN:
                                target[j] = '<';
+                               break;
                        default: 
                                len = cp->uni2char(src_char, &target[j], 
                                                NLS_MAX_CHARSET_SIZE);
index 496a4e08369c4403cc1fe2931b887e20762ae129..3aa8a7e980d80877cff19138ce37b4a01fd2c09a 100644 (file)
@@ -39,7 +39,7 @@ int sysctl_vfs_cache_pressure = 100;
 EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
 
  __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
-seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED;
+static seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED;
 
 EXPORT_SYMBOL(dcache_lock);
 
index 05b966cd6f7696144268d5cac92e30bea3f89c34..9900e333655aca0e1bd8e29e3905dfcd94e05cc3 100644 (file)
@@ -320,7 +320,7 @@ static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
 /*
  * This semaphore is used to serialize ep_free() and eventpoll_release_file().
  */
-struct semaphore epsem;
+static struct semaphore epsem;
 
 /* Safe wake up implementation */
 static struct poll_safewake psw;
index a8394499926cd3a7ce87ada09875f6ca6fb1ea5e..e56ee24370255e2ab4df9a3933ec03f0d07a2de3 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -197,7 +197,8 @@ static int count(char __user * __user * argv, int max)
  * memory to free pages in kernel mem. These are in a format ready
  * to be put directly into the top of new user memory.
  */
-int copy_strings(int argc,char __user * __user * argv, struct linux_binprm *bprm)
+static int copy_strings(int argc, char __user * __user * argv,
+                       struct linux_binprm *bprm)
 {
        struct page *kmapped_page = NULL;
        char *kaddr = NULL;
@@ -868,9 +869,11 @@ int flush_old_exec(struct linux_binprm * bprm)
        if (current->euid == current->uid && current->egid == current->gid)
                current->mm->dumpable = 1;
        name = bprm->filename;
+
+       /* Copies the binary name from after last slash */
        for (i=0; (ch = *(name++)) != '\0';) {
                if (ch == '/')
-                       i = 0;
+                       i = 0; /* overwrite what we wrote */
                else
                        if (i < (sizeof(tcomm) - 1))
                                tcomm[i++] = ch;
index ea5888688f9471735395537eeab09c31472fc21f..0d5fa73b18dc1542700ddbf2285c0b2ffe3b9e18 100644 (file)
@@ -844,12 +844,6 @@ get_block:
        return ret;
 }
 
-static int ext3_writepages_get_block(struct inode *inode, sector_t iblock,
-                       struct buffer_head *bh, int create)
-{
-       return ext3_direct_io_get_blocks(inode, iblock, 1, bh, create);
-}
-
 /*
  * `handle' can be NULL if create is zero
  */
@@ -1323,45 +1317,6 @@ out_fail:
        return ret;
 }
 
-static int
-ext3_writeback_writepage_helper(struct page *page,
-                               struct writeback_control *wbc)
-{
-       return block_write_full_page(page, ext3_get_block, wbc);
-}
-
-static int
-ext3_writeback_writepages(struct address_space *mapping,
-                               struct writeback_control *wbc)
-{
-       struct inode *inode = mapping->host;
-       handle_t *handle = NULL;
-       int err, ret = 0;
-
-       if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
-               return ret;
-
-       handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
-       if (IS_ERR(handle)) {
-               ret = PTR_ERR(handle);
-               return ret;
-       }
-
-        ret = __mpage_writepages(mapping, wbc, ext3_writepages_get_block,
-                                       ext3_writeback_writepage_helper);
-
-       /*
-        * Need to reaquire the handle since ext3_writepages_get_block()
-        * can restart the handle
-        */
-       handle = journal_current_handle();
-
-       err = ext3_journal_stop(handle);
-       if (!ret)
-               ret = err;
-       return ret;
-}
-
 static int ext3_writeback_writepage(struct page *page,
                                struct writeback_control *wbc)
 {
@@ -1599,7 +1554,6 @@ static struct address_space_operations ext3_writeback_aops = {
        .readpage       = ext3_readpage,
        .readpages      = ext3_readpages,
        .writepage      = ext3_writeback_writepage,
-       .writepages     = ext3_writeback_writepages,
        .sync_page      = block_sync_page,
        .prepare_write  = ext3_prepare_write,
        .commit_write   = ext3_writeback_commit_write,
index 545b440a2d2fac2d2cd193c40938a440be24c953..981ccb233ef5e29949152a6dea0aeb55edc84b8c 100644 (file)
@@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function,
                       int errno)
 {
        char nbuf[16];
-       const char *errstr = ext3_decode_error(sb, errno, nbuf);
+       const char *errstr;
+
+       /* Special case: if the error is EROFS, and we're not already
+        * inside a transaction, then there's really no point in logging
+        * an error. */
+       if (errno == -EROFS && journal_current_handle() == NULL &&
+           (sb->s_flags & MS_RDONLY))
+               return;
 
+       errstr = ext3_decode_error(sb, errno, nbuf);
        printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n",
                sb->s_id, function, errstr);
 
index e6c63d9cac7bd473f8b7dd00734eea0682cf9658..4bf43ea87c4639ae8e0ce6f8cbd4592d7d70cccb 100644 (file)
@@ -23,7 +23,6 @@
 #include "kern_util.h"
 #include "kern.h"
 #include "user_util.h"
-#include "2_5compat.h"
 #include "init.h"
 
 struct hostfs_inode_info {
@@ -991,13 +990,17 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
                goto out_put;
 
        err = read_inode(root_inode);
-       if(err)
-               goto out_put;
+       if(err){
+                /* No iput in this case because the dput does that for us */
+                dput(sb->s_root);
+                sb->s_root = NULL;
+               goto out_free;
+        }
 
        return(0);
 
  out_put:
-       iput(root_inode);
+        iput(root_inode);
  out_free:
        kfree(name);
  out:
index af8fd78d2099a0852d7867a4b2691924c1ed3982..801fe7f362807b7d581f1ef06033184771e5129f 100644 (file)
@@ -26,7 +26,6 @@
  * This is needed for the following functions:
  *  - inode_has_buffers
  *  - invalidate_inode_buffers
- *  - fsync_bdev
  *  - invalidate_bdev
  *
  * FIXME: remove all knowledge of the buffer layer from this file
@@ -332,14 +331,6 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
        return busy;
 }
 
-/*
- * This is a two-stage process. First we collect all
- * offending inodes onto the throw-away list, and in
- * the second stage we actually dispose of them. This
- * is because we don't want to sleep while messing
- * with the global lists..
- */
 /**
  *     invalidate_inodes       - discard the inodes on a device
  *     @sb: superblock
@@ -366,16 +357,11 @@ int invalidate_inodes(struct super_block * sb)
 
 EXPORT_SYMBOL(invalidate_inodes);
  
-int __invalidate_device(struct block_device *bdev, int do_sync)
+int __invalidate_device(struct block_device *bdev)
 {
-       struct super_block *sb;
-       int res;
+       struct super_block *sb = get_super(bdev);
+       int res = 0;
 
-       if (do_sync)
-               fsync_bdev(bdev);
-
-       res = 0;
-       sb = get_super(bdev);
        if (sb) {
                /*
                 * no need to lock the super, get_super holds the
@@ -390,7 +376,6 @@ int __invalidate_device(struct block_device *bdev, int do_sync)
        invalidate_bdev(bdev, 0);
        return res;
 }
-
 EXPORT_SYMBOL(__invalidate_device);
 
 static int can_unuse(struct inode *inode)
@@ -1336,7 +1321,7 @@ void __init inode_init(unsigned long mempages)
 
        /* inode slab cache */
        inode_cachep = kmem_cache_create("inode_cache", sizeof(struct inode),
-                               0, SLAB_PANIC, init_once, NULL);
+                               0, SLAB_RECLAIM_ACCOUNT|SLAB_PANIC, init_once, NULL);
        set_shrinker(DEFAULT_SEEKS, shrink_icache_memory);
 
        /* Hash may have been set up in inode_init_early */
index 98d830401c56c7e50463e85acfe994f76171bb99..5a97e346bd95a247c12f0edcc5b33d1b065d6419 100644 (file)
@@ -188,7 +188,6 @@ static int __cleanup_transaction(journal_t *journal, transaction_t *transaction)
                } else {
                        jbd_unlock_bh_state(bh);
                }
-               jh = next_jh;
        } while (jh != last_jh);
 
        return ret;
@@ -339,8 +338,10 @@ int log_do_checkpoint(journal_t *journal)
                        }
                } while (jh != last_jh && !retry);
 
-               if (batch_count)
+               if (batch_count) {
                        __flush_batch(journal, bhs, &batch_count);
+                       retry = 1;
+               }
 
                /*
                 * If someone cleaned up this transaction while we slept, we're
index 450d6624181facbb230d3db23c5a651f55e902ab..09422388fb96716681b151871144eed992b72be7 100644 (file)
@@ -228,8 +228,10 @@ int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
        return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
 }
 #endif
-int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, 
-                  uint32_t *sourcelen, uint32_t *dstlen, void *model)
+static int jffs2_dynrubin_compress(unsigned char *data_in,
+                                  unsigned char *cpage_out,
+                                  uint32_t *sourcelen, uint32_t *dstlen,
+                                  void *model)
 {
        int bits[8];
        unsigned char histo[256];
@@ -306,15 +308,19 @@ static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata
 }                 
 
 
-int jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, 
-                  uint32_t sourcelen, uint32_t dstlen, void *model)
+static int jffs2_rubinmips_decompress(unsigned char *data_in,
+                                     unsigned char *cpage_out,
+                                     uint32_t sourcelen, uint32_t dstlen,
+                                     void *model)
 {
        rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
         return 0;
 }
 
-int jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, 
-                  uint32_t sourcelen, uint32_t dstlen, void *model)
+static int jffs2_dynrubin_decompress(unsigned char *data_in,
+                                    unsigned char *cpage_out,
+                                    uint32_t sourcelen, uint32_t dstlen,
+                                    void *model)
 {
        int bits[8];
        int c;
index 9f9932c22adbdd675c22b6545595d749797977c2..078a30e406b52668b4e9daa4fa5d5b1a4aced6db 100644 (file)
@@ -69,8 +69,10 @@ static void free_workspaces(void)
 #define free_workspaces() do { } while(0)
 #endif /* __KERNEL__ */
 
-int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, 
-                  uint32_t *sourcelen, uint32_t *dstlen, void *model)
+static int jffs2_zlib_compress(unsigned char *data_in,
+                              unsigned char *cpage_out,
+                              uint32_t *sourcelen, uint32_t *dstlen,
+                              void *model)
 {
        int ret;
 
@@ -135,8 +137,10 @@ int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
        return ret;
 }
 
-int jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
-                     uint32_t srclen, uint32_t destlen, void *model)
+static int jffs2_zlib_decompress(unsigned char *data_in,
+                                unsigned char *cpage_out,
+                                uint32_t srclen, uint32_t destlen,
+                                void *model)
 {
        int ret;
        int wbits = MAX_WBITS;
index 2c1f311914a101d9ee631327f0421956a8caa1a5..31b34db4519ec9cabc2668211177c3c2554d64e0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *   Copyright (C) International Business Machines Corp., 2000-2004
+ *   Copyright (C) International Business Machines Corp., 2000-2005
  *
  *   This program is free software;  you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -688,7 +688,7 @@ static int xtSearch(struct inode *ip, s64 xoff,     s64 *nextp,
                                /* search hit - internal page:
                                 * descend/search its child page
                                 */
-                               if (index < p->header.nextindex - 1)
+                               if (index < le16_to_cpu(p->header.nextindex)-1)
                                        next = offsetXAD(&p->xad[index + 1]);
                                goto next;
                        }
@@ -705,7 +705,7 @@ static int xtSearch(struct inode *ip, s64 xoff,     s64 *nextp,
                 * base is the smallest index with key (Kj) greater than
                 * search key (K) and may be zero or maxentry index.
                 */
-               if (base < p->header.nextindex)
+               if (base < le16_to_cpu(p->header.nextindex))
                        next = offsetXAD(&p->xad[base]);
                /*
                 * search miss - leaf page:
index 1792ce547af7b0b6517bd2779600f4dfe03514a5..3fa6a7ce57a7390a7faf6a23effbabe9013720f3 100644 (file)
@@ -406,12 +406,12 @@ static void lease_release_private_callback(struct file_lock *fl)
        fl->fl_file->f_owner.signum = 0;
 }
 
-int lease_mylease_callback(struct file_lock *fl, struct file_lock *try)
+static int lease_mylease_callback(struct file_lock *fl, struct file_lock *try)
 {
        return fl->fl_file == try->fl_file;
 }
 
-struct lock_manager_operations lease_manager_ops = {
+static struct lock_manager_operations lease_manager_ops = {
        .fl_break = lease_break_callback,
        .fl_release_private = lease_release_private_callback,
        .fl_mylease = lease_mylease_callback,
@@ -1274,7 +1274,7 @@ int fcntl_getlease(struct file *filp)
  *
  *     Called with kernel lock held.
  */
-int __setlease(struct file *filp, long arg, struct file_lock **flp)
+static int __setlease(struct file *filp, long arg, struct file_lock **flp)
 {
        struct file_lock *fl, **before, **my_before = NULL, *lease = *flp;
        struct dentry *dentry = filp->f_dentry;
index f9e4d2700cd8148d89e9975fda791377e859a98e..c7170b9221a306a0b024c29f7e2599957edc73ce 100644 (file)
@@ -57,7 +57,7 @@
 
 #define MB_CACHE_WRITER ((unsigned short)~0U >> 1)
 
-DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue);
+static DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue);
                
 MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
 MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
index 32c7c8fcfce78e02aa691d51308e66a958eee57c..bb9aebe93862d8c03a94990d4b28fc4832e93a1f 100644 (file)
@@ -79,15 +79,18 @@ static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err)
                if (--bvec >= bio->bi_io_vec)
                        prefetchw(&bvec->bv_page->flags);
 
-               if (!uptodate)
+               if (!uptodate){
                        SetPageError(page);
+                       if (page->mapping)
+                               set_bit(AS_EIO, &page->mapping->flags);
+               }
                end_page_writeback(page);
        } while (bvec >= bio->bi_io_vec);
        bio_put(bio);
        return 0;
 }
 
-struct bio *mpage_bio_submit(int rw, struct bio *bio)
+static struct bio *mpage_bio_submit(int rw, struct bio *bio)
 {
        bio->bi_end_io = mpage_end_io_read;
        if (rw == WRITE)
@@ -626,15 +629,6 @@ out:
 int
 mpage_writepages(struct address_space *mapping,
                struct writeback_control *wbc, get_block_t get_block)
-{
-       return __mpage_writepages(mapping, wbc, get_block,
-               mapping->a_ops->writepage);
-}
-
-int
-__mpage_writepages(struct address_space *mapping,
-               struct writeback_control *wbc, get_block_t get_block,
-               writepage_t writepage_fn)
 {
        struct backing_dev_info *bdi = mapping->backing_dev_info;
        struct bio *bio = NULL;
@@ -725,7 +719,7 @@ retry:
                        } else {
                                bio = __mpage_writepage(bio, page, get_block,
                                                &last_block_in_bio, &ret, wbc,
-                                               writepage_fn);
+                                               page->mapping->a_ops->writepage);
                        }
                        if (unlikely(ret == WRITEPAGE_ACTIVATE))
                                unlock_page(page);
@@ -755,7 +749,6 @@ retry:
        return ret;
 }
 EXPORT_SYMBOL(mpage_writepages);
-EXPORT_SYMBOL(__mpage_writepages);
 
 int mpage_writepage(struct page *page, get_block_t get_block,
        struct writeback_control *wbc)
index 9e4aef2a1a21d44a9ba54b00f5ac284dd590f331..a7f7f44119b3dda8e18a3de1e23990eb4f3ffb05 100644 (file)
@@ -493,12 +493,21 @@ fail:
        return PTR_ERR(link);
 }
 
-static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
+struct path {
+       struct vfsmount *mnt;
+       struct dentry *dentry;
+};
+
+static inline int __do_follow_link(struct path *path, struct nameidata *nd)
 {
        int error;
+       struct dentry *dentry = path->dentry;
 
-       touch_atime(nd->mnt, dentry);
+       touch_atime(path->mnt, dentry);
        nd_set_link(nd, NULL);
+
+       if (path->mnt == nd->mnt)
+               mntget(path->mnt);
        error = dentry->d_inode->i_op->follow_link(dentry, nd);
        if (!error) {
                char *s = nd_get_link(nd);
@@ -507,6 +516,8 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
                if (dentry->d_inode->i_op->put_link)
                        dentry->d_inode->i_op->put_link(dentry, nd);
        }
+       dput(dentry);
+       mntput(path->mnt);
 
        return error;
 }
@@ -518,7 +529,7 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
  * Without that kind of total limit, nasty chains of consecutive
  * symlinks can cause almost arbitrarily long lookups. 
  */
-static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
+static inline int do_follow_link(struct path *path, struct nameidata *nd)
 {
        int err = -ELOOP;
        if (current->link_count >= MAX_NESTED_LINKS)
@@ -527,17 +538,20 @@ static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
                goto loop;
        BUG_ON(nd->depth >= MAX_NESTED_LINKS);
        cond_resched();
-       err = security_inode_follow_link(dentry, nd);
+       err = security_inode_follow_link(path->dentry, nd);
        if (err)
                goto loop;
        current->link_count++;
        current->total_link_count++;
        nd->depth++;
-       err = __do_follow_link(dentry, nd);
+       err = __do_follow_link(path, nd);
        current->link_count--;
        nd->depth--;
        return err;
 loop:
+       dput(path->dentry);
+       if (path->mnt != nd->mnt)
+               mntput(path->mnt);
        path_release(nd);
        return err;
 }
@@ -565,87 +579,91 @@ int follow_up(struct vfsmount **mnt, struct dentry **dentry)
 /* no need for dcache_lock, as serialization is taken care in
  * namespace.c
  */
-static int follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+static int __follow_mount(struct path *path)
 {
        int res = 0;
+       while (d_mountpoint(path->dentry)) {
+               struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry);
+               if (!mounted)
+                       break;
+               dput(path->dentry);
+               if (res)
+                       mntput(path->mnt);
+               path->mnt = mounted;
+               path->dentry = dget(mounted->mnt_root);
+               res = 1;
+       }
+       return res;
+}
+
+static void follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+{
        while (d_mountpoint(*dentry)) {
                struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
                if (!mounted)
                        break;
+               dput(*dentry);
                mntput(*mnt);
                *mnt = mounted;
-               dput(*dentry);
                *dentry = dget(mounted->mnt_root);
-               res = 1;
        }
-       return res;
 }
 
 /* no need for dcache_lock, as serialization is taken care in
  * namespace.c
  */
-static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
+int follow_down(struct vfsmount **mnt, struct dentry **dentry)
 {
        struct vfsmount *mounted;
 
        mounted = lookup_mnt(*mnt, *dentry);
        if (mounted) {
+               dput(*dentry);
                mntput(*mnt);
                *mnt = mounted;
-               dput(*dentry);
                *dentry = dget(mounted->mnt_root);
                return 1;
        }
        return 0;
 }
 
-int follow_down(struct vfsmount **mnt, struct dentry **dentry)
-{
-       return __follow_down(mnt,dentry);
-}
-static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
+static inline void follow_dotdot(struct nameidata *nd)
 {
        while(1) {
                struct vfsmount *parent;
-               struct dentry *old = *dentry;
+               struct dentry *old = nd->dentry;
 
                 read_lock(&current->fs->lock);
-               if (*dentry == current->fs->root &&
-                   *mnt == current->fs->rootmnt) {
+               if (nd->dentry == current->fs->root &&
+                   nd->mnt == current->fs->rootmnt) {
                         read_unlock(&current->fs->lock);
                        break;
                }
                 read_unlock(&current->fs->lock);
                spin_lock(&dcache_lock);
-               if (*dentry != (*mnt)->mnt_root) {
-                       *dentry = dget((*dentry)->d_parent);
+               if (nd->dentry != nd->mnt->mnt_root) {
+                       nd->dentry = dget(nd->dentry->d_parent);
                        spin_unlock(&dcache_lock);
                        dput(old);
                        break;
                }
                spin_unlock(&dcache_lock);
                spin_lock(&vfsmount_lock);
-               parent = (*mnt)->mnt_parent;
-               if (parent == *mnt) {
+               parent = nd->mnt->mnt_parent;
+               if (parent == nd->mnt) {
                        spin_unlock(&vfsmount_lock);
                        break;
                }
                mntget(parent);
-               *dentry = dget((*mnt)->mnt_mountpoint);
+               nd->dentry = dget(nd->mnt->mnt_mountpoint);
                spin_unlock(&vfsmount_lock);
                dput(old);
-               mntput(*mnt);
-               *mnt = parent;
+               mntput(nd->mnt);
+               nd->mnt = parent;
        }
-       follow_mount(mnt, dentry);
+       follow_mount(&nd->mnt, &nd->dentry);
 }
 
-struct path {
-       struct vfsmount *mnt;
-       struct dentry *dentry;
-};
-
 /*
  *  It's more convoluted than I'd like it to be, but... it's still fairly
  *  small and for now I'd prefer to have fast path as straight as possible.
@@ -664,6 +682,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
 done:
        path->mnt = mnt;
        path->dentry = dentry;
+       __follow_mount(path);
        return 0;
 
 need_lookup:
@@ -686,11 +705,11 @@ fail:
 
 /*
  * Name resolution.
+ * This is the basic name resolution function, turning a pathname into
+ * the final dentry. We expect 'base' to be positive and a directory.
  *
- * This is the basic name resolution function, turning a pathname
- * into the final dentry.
- *
- * We expect 'base' to be positive and a directory.
+ * Returns 0 and nd will have valid dentry and mnt on success.
+ * Returns error and drops reference to input namei data on failure.
  */
 static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
 {
@@ -751,7 +770,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
                        case 2: 
                                if (this.name[1] != '.')
                                        break;
-                               follow_dotdot(&nd->mnt, &nd->dentry);
+                               follow_dotdot(nd);
                                inode = nd->dentry->d_inode;
                                /* fallthrough */
                        case 1:
@@ -771,8 +790,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
                err = do_lookup(nd, &this, &next);
                if (err)
                        break;
-               /* Check mountpoints.. */
-               follow_mount(&next.mnt, &next.dentry);
 
                err = -ENOENT;
                inode = next.dentry->d_inode;
@@ -783,10 +800,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
                        goto out_dput;
 
                if (inode->i_op->follow_link) {
-                       mntget(next.mnt);
-                       err = do_follow_link(next.dentry, nd);
-                       dput(next.dentry);
-                       mntput(next.mnt);
+                       err = do_follow_link(&next, nd);
                        if (err)
                                goto return_err;
                        err = -ENOENT;
@@ -798,6 +812,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
                                break;
                } else {
                        dput(nd->dentry);
+                       if (nd->mnt != next.mnt)
+                               mntput(nd->mnt);
                        nd->mnt = next.mnt;
                        nd->dentry = next.dentry;
                }
@@ -819,7 +835,7 @@ last_component:
                        case 2: 
                                if (this.name[1] != '.')
                                        break;
-                               follow_dotdot(&nd->mnt, &nd->dentry);
+                               follow_dotdot(nd);
                                inode = nd->dentry->d_inode;
                                /* fallthrough */
                        case 1:
@@ -833,19 +849,17 @@ last_component:
                err = do_lookup(nd, &this, &next);
                if (err)
                        break;
-               follow_mount(&next.mnt, &next.dentry);
                inode = next.dentry->d_inode;
                if ((lookup_flags & LOOKUP_FOLLOW)
                    && inode && inode->i_op && inode->i_op->follow_link) {
-                       mntget(next.mnt);
-                       err = do_follow_link(next.dentry, nd);
-                       dput(next.dentry);
-                       mntput(next.mnt);
+                       err = do_follow_link(&next, nd);
                        if (err)
                                goto return_err;
                        inode = nd->dentry->d_inode;
                } else {
                        dput(nd->dentry);
+                       if (nd->mnt != next.mnt)
+                               mntput(nd->mnt);
                        nd->mnt = next.mnt;
                        nd->dentry = next.dentry;
                }
@@ -885,6 +899,8 @@ return_base:
                return 0;
 out_dput:
                dput(next.dentry);
+               if (nd->mnt != next.mnt)
+                       mntput(next.mnt);
                break;
        }
        path_release(nd);
@@ -929,8 +945,10 @@ int fastcall path_walk(const char * name, struct nameidata *nd)
        return link_path_walk(name, nd);
 }
 
-/* SMP-safe */
-/* returns 1 if everything is done */
+/* 
+ * SMP-safe: Returns 1 and nd will have valid dentry and mnt, if
+ * everything is done. Returns 0 and drops input nd, if lookup failed;
+ */
 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
 {
        if (path_walk(name, nd))
@@ -994,9 +1012,10 @@ set_it:
        }
 }
 
+/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
 int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd)
 {
-       int retval;
+       int retval = 0;
 
        nd->last_type = LAST_ROOT; /* if there are only slashes... */
        nd->flags = flags;
@@ -1009,7 +1028,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
                        nd->dentry = dget(current->fs->altroot);
                        read_unlock(&current->fs->lock);
                        if (__emul_lookup_dentry(name,nd))
-                               return 0;
+                               goto out; /* found in altroot */
                        read_lock(&current->fs->lock);
                }
                nd->mnt = mntget(current->fs->rootmnt);
@@ -1021,6 +1040,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
        read_unlock(&current->fs->lock);
        current->total_link_count = 0;
        retval = link_path_walk(name, nd);
+out:
        if (unlikely(current->audit_context
                     && nd && nd->dentry && nd->dentry->d_inode))
                audit_inode(name, nd->dentry->d_inode);
@@ -1394,7 +1414,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
 int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
 {
        int acc_mode, error = 0;
-       struct dentry *dentry;
+       struct path path;
        struct dentry *dir;
        int count = 0;
 
@@ -1438,23 +1458,24 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
        dir = nd->dentry;
        nd->flags &= ~LOOKUP_PARENT;
        down(&dir->d_inode->i_sem);
-       dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+       path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+       path.mnt = nd->mnt;
 
 do_last:
-       error = PTR_ERR(dentry);
-       if (IS_ERR(dentry)) {
+       error = PTR_ERR(path.dentry);
+       if (IS_ERR(path.dentry)) {
                up(&dir->d_inode->i_sem);
                goto exit;
        }
 
        /* Negative dentry, just create the file */
-       if (!dentry->d_inode) {
+       if (!path.dentry->d_inode) {
                if (!IS_POSIXACL(dir->d_inode))
                        mode &= ~current->fs->umask;
-               error = vfs_create(dir->d_inode, dentry, mode, nd);
+               error = vfs_create(dir->d_inode, path.dentry, mode, nd);
                up(&dir->d_inode->i_sem);
                dput(nd->dentry);
-               nd->dentry = dentry;
+               nd->dentry = path.dentry;
                if (error)
                        goto exit;
                /* Don't check for write permission, don't truncate */
@@ -1472,22 +1493,24 @@ do_last:
        if (flag & O_EXCL)
                goto exit_dput;
 
-       if (d_mountpoint(dentry)) {
+       if (__follow_mount(&path)) {
                error = -ELOOP;
                if (flag & O_NOFOLLOW)
                        goto exit_dput;
-               while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
        }
        error = -ENOENT;
-       if (!dentry->d_inode)
+       if (!path.dentry->d_inode)
                goto exit_dput;
-       if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
+       if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link)
                goto do_link;
 
        dput(nd->dentry);
-       nd->dentry = dentry;
+       nd->dentry = path.dentry;
+       if (nd->mnt != path.mnt)
+               mntput(nd->mnt);
+       nd->mnt = path.mnt;
        error = -EISDIR;
-       if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
+       if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode))
                goto exit;
 ok:
        error = may_open(nd, acc_mode, flag);
@@ -1496,7 +1519,9 @@ ok:
        return 0;
 
 exit_dput:
-       dput(dentry);
+       dput(path.dentry);
+       if (nd->mnt != path.mnt)
+               mntput(path.mnt);
 exit:
        path_release(nd);
        return error;
@@ -1516,18 +1541,15 @@ do_link:
         * are done. Procfs-like symlinks just set LAST_BIND.
         */
        nd->flags |= LOOKUP_PARENT;
-       error = security_inode_follow_link(dentry, nd);
+       error = security_inode_follow_link(path.dentry, nd);
        if (error)
                goto exit_dput;
-       error = __do_follow_link(dentry, nd);
-       dput(dentry);
+       error = __do_follow_link(&path, nd);
        if (error)
                return error;
        nd->flags &= ~LOOKUP_PARENT;
-       if (nd->last_type == LAST_BIND) {
-               dentry = nd->dentry;
+       if (nd->last_type == LAST_BIND)
                goto ok;
-       }
        error = -EISDIR;
        if (nd->last_type != LAST_NORM)
                goto exit;
@@ -1542,7 +1564,8 @@ do_link:
        }
        dir = nd->dentry;
        down(&dir->d_inode->i_sem);
-       dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+       path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+       path.mnt = nd->mnt;
        putname(nd->last.name);
        goto do_last;
 }
@@ -1576,6 +1599,7 @@ enoent:
 fail:
        return dentry;
 }
+EXPORT_SYMBOL_GPL(lookup_create);
 
 int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
 {
@@ -2067,8 +2091,8 @@ exit:
  *        ->i_sem on parents, which works but leads to some truely excessive
  *        locking].
  */
-int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
-              struct inode *new_dir, struct dentry *new_dentry)
+static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
+                         struct inode *new_dir, struct dentry *new_dentry)
 {
        int error = 0;
        struct inode *target;
@@ -2112,8 +2136,8 @@ int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
        return error;
 }
 
-int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
-              struct inode *new_dir, struct dentry *new_dentry)
+static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
+                           struct inode *new_dir, struct dentry *new_dentry)
 {
        struct inode *target;
        int error;
index 73f96acd5d378b1b8e8aafd091b11c211f367afb..ff6155f5e8d9e3e30bbc5fa7422d67119426b1e0 100644 (file)
@@ -528,19 +528,39 @@ static inline void nfs_renew_times(struct dentry * dentry)
        dentry->d_time = jiffies;
 }
 
+/*
+ * Return the intent data that applies to this particular path component
+ *
+ * Note that the current set of intents only apply to the very last
+ * component of the path.
+ * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT.
+ */
+static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask)
+{
+       if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))
+               return 0;
+       return nd->flags & mask;
+}
+
+/*
+ * Inode and filehandle revalidation for lookups.
+ *
+ * We force revalidation in the cases where the VFS sets LOOKUP_REVAL,
+ * or if the intent information indicates that we're about to open this
+ * particular file and the "nocto" mount flag is not set.
+ *
+ */
 static inline
 int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
 {
        struct nfs_server *server = NFS_SERVER(inode);
 
        if (nd != NULL) {
-               int ndflags = nd->flags;
                /* VFS wants an on-the-wire revalidation */
-               if (ndflags & LOOKUP_REVAL)
+               if (nd->flags & LOOKUP_REVAL)
                        goto out_force;
                /* This is an open(2) */
-               if ((ndflags & LOOKUP_OPEN) &&
-                               !(ndflags & LOOKUP_CONTINUE) &&
+               if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 &&
                                !(server->flags & NFS_MOUNT_NOCTO))
                        goto out_force;
        }
@@ -560,12 +580,8 @@ static inline
 int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
                       struct nameidata *nd)
 {
-       int ndflags = 0;
-
-       if (nd)
-               ndflags = nd->flags;
        /* Don't revalidate a negative dentry if we're creating a new file */
-       if ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE))
+       if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0)
                return 0;
        return !nfs_check_verifier(dir, dentry);
 }
@@ -700,12 +716,16 @@ struct dentry_operations nfs_dentry_operations = {
        .d_iput         = nfs_dentry_iput,
 };
 
+/*
+ * Use intent information to check whether or not we're going to do
+ * an O_EXCL create using this path component.
+ */
 static inline
 int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
 {
        if (NFS_PROTO(dir)->version == 2)
                return 0;
-       if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE))
+       if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
                return 0;
        return (nd->intent.open.flags & O_EXCL) != 0;
 }
@@ -772,12 +792,13 @@ struct dentry_operations nfs4_dentry_operations = {
        .d_iput         = nfs_dentry_iput,
 };
 
+/*
+ * Use intent information to determine whether we need to substitute
+ * the NFSv4-style stateful OPEN for the LOOKUP call
+ */
 static int is_atomic_open(struct inode *dir, struct nameidata *nd)
 {
-       if (!nd)
-               return 0;
-       /* Check that we are indeed trying to open this file */
-       if ((nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_OPEN))
+       if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0)
                return 0;
        /* NFS does not (yet) have a stateful open for directories */
        if (nd->flags & LOOKUP_DIRECTORY)
index f06eee6dcff57e3d4d4d7f88fe71545fd5b2c6e6..55c907592490a7fa6357c2bc17018b378c25433f 100644 (file)
@@ -37,6 +37,7 @@
 
 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_read(struct kiocb *, char __user *, size_t, loff_t);
@@ -48,7 +49,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
 static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
 
 struct file_operations nfs_file_operations = {
-       .llseek         = remote_llseek,
+       .llseek         = nfs_file_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
        .aio_read               = nfs_file_read,
@@ -114,6 +115,45 @@ nfs_file_release(struct inode *inode, struct file *filp)
        return NFS_PROTO(inode)->file_release(inode, filp);
 }
 
+/**
+ * nfs_revalidate_size - Revalidate the file size
+ * @inode - pointer to inode struct
+ * @file - pointer to struct file
+ *
+ * Revalidates the file length. This is basically a wrapper around
+ * nfs_revalidate_inode() that takes into account the fact that we may
+ * have cached writes (in which case we don't care about the server's
+ * idea of what the file length is), or O_DIRECT (in which case we
+ * shouldn't trust the cache).
+ */
+static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct nfs_inode *nfsi = NFS_I(inode);
+
+       if (server->flags & NFS_MOUNT_NOAC)
+               goto force_reval;
+       if (filp->f_flags & O_DIRECT)
+               goto force_reval;
+       if (nfsi->npages != 0)
+               return 0;
+       return nfs_revalidate_inode(server, inode);
+force_reval:
+       return __nfs_revalidate_inode(server, inode);
+}
+
+static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
+{
+       /* origin == SEEK_END => we must revalidate the cached file length */
+       if (origin == 2) {
+               struct inode *inode = filp->f_mapping->host;
+               int retval = nfs_revalidate_file_size(inode, filp);
+               if (retval < 0)
+                       return (loff_t)retval;
+       }
+       return remote_llseek(filp, offset, origin);
+}
+
 /*
  * Flush all dirty pages, and check for write errors.
  *
index b74c4e3a64e2a435759ad2115f1af64f3a772b00..87f4f9aeac86b2c4a5f07c4d856fb5690b967cb2 100644 (file)
@@ -79,7 +79,7 @@ static ssize_t   idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *,
                     char __user *, size_t);
 static ssize_t   idmap_pipe_downcall(struct file *, const char __user *,
                     size_t);
-void             idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
+static void      idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
 
 static unsigned int fnvhash32(const void *, size_t);
 
@@ -434,7 +434,7 @@ out:
        return ret;
 }
 
-void
+static void
 idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg)
 {
        struct idmap_msg *im = msg->data;
index 6345f26e87ee944745a3369398c7b0dc070718e2..f2317f3e29f9d54b586b511128478212e8664348 100644 (file)
@@ -1904,7 +1904,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
        }
 }
  
-int nfs_init_inodecache(void)
+static int nfs_init_inodecache(void)
 {
        nfs_inode_cachep = kmem_cache_create("nfs_inode_cache",
                                             sizeof(struct nfs_inode),
@@ -1916,7 +1916,7 @@ int nfs_init_inodecache(void)
        return 0;
 }
 
-void nfs_destroy_inodecache(void)
+static void nfs_destroy_inodecache(void)
 {
        if (kmem_cache_destroy(nfs_inode_cachep))
                printk(KERN_INFO "nfs_inode_cache: not all structures were freed\n");
index 897512796edb4ae06b7574cfbb905c018562e9c2..a912debcd20b3c27850c4e5754e164888a0a9e9d 100644 (file)
@@ -243,7 +243,7 @@ void unload_nls(struct nls_table *nls)
        module_put(nls->owner);
 }
 
-wchar_t charset2uni[256] = {
+static wchar_t charset2uni[256] = {
        /* 0x00*/
        0x0000, 0x0001, 0x0002, 0x0003,
        0x0004, 0x0005, 0x0006, 0x0007,
index 17ee1b4ff087ee060a9e13a1a4bbe889c9623f22..584a27b2bbd5a5cfc4317356a28efb3b42ef427f 100644 (file)
@@ -114,9 +114,6 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev,
                 */
                for (i=0; i<4; i++, p++) {
                        u32 offs, size, next;
-
-                       if (SYS_IND(p) == 0)
-                               continue;
                        if (!NR_SECTS(p) || is_extended_partition(p))
                                continue;
 
@@ -433,8 +430,6 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
        for (slot = 1 ; slot <= 4 ; slot++, p++) {
                u32 start = START_SECT(p)*sector_size;
                u32 size = NR_SECTS(p)*sector_size;
-               if (SYS_IND(p) == 0)
-                       continue;
                if (!size)
                        continue;
                if (is_extended_partition(p)) {
index 07cafdf74ef2f343b4eef2e8f0356d69a7f8e6f4..e31903aadd96f6f3a4cc327c67f9163352da262f 100644 (file)
@@ -820,7 +820,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
                goto out_free_page;
 
        }
-       length = audit_set_loginuid(task->audit_context, loginuid);
+       length = audit_set_loginuid(task, loginuid);
        if (likely(length == 0))
                length = count;
 
index a7041038ad56108ef45f195bedf109dbbb7ddb24..25d2d9c6e329c6b0eb04524cd80d2538cb3f4118 100644 (file)
@@ -50,13 +50,23 @@ void get_vmalloc_info(struct vmalloc_info *vmi)
                read_lock(&vmlist_lock);
 
                for (vma = vmlist; vma; vma = vma->next) {
+                       unsigned long addr = (unsigned long) vma->addr;
+
+                       /*
+                        * Some archs keep another range for modules in vmlist
+                        */
+                       if (addr < VMALLOC_START)
+                               continue;
+                       if (addr >= VMALLOC_END)
+                               break;
+
                        vmi->used += vma->size;
 
-                       free_area_size = (unsigned long) vma->addr - prev_end;
+                       free_area_size = addr - prev_end;
                        if (vmi->largest_chunk < free_area_size)
                                vmi->largest_chunk = free_area_size;
 
-                       prev_end = vma->size + (unsigned long) vma->addr;
+                       prev_end = vma->size + addr;
                }
 
                if (VMALLOC_END - prev_end > vmi->largest_chunk)
index 67423c696c0a205afda4734b8bcaf8836fb2ce21..6fd57f1541972cfb182e325d39df30c02850690a 100644 (file)
 #include <asm/uaccess.h>
 
 #ifndef HAVE_ARCH_DEVTREE_FIXUPS
-static inline void set_node_proc_entry(struct device_node *np, struct proc_dir_entry *de)
-{
-}
-
-static void inline set_node_name_link(struct device_node *np, struct proc_dir_entry *de)
-{
-}
-
-static void inline set_node_addr_link(struct device_node *np, struct proc_dir_entry *de)
+static inline void set_node_proc_entry(struct device_node *np,
+                                      struct proc_dir_entry *de)
 {
 }
 #endif
@@ -58,89 +51,67 @@ static int property_read_proc(char *page, char **start, off_t off,
 /*
  * Process a node, adding entries for its children and its properties.
  */
-void proc_device_tree_add_node(struct device_node *np, struct proc_dir_entry *de)
+void proc_device_tree_add_node(struct device_node *np,
+                              struct proc_dir_entry *de)
 {
        struct property *pp;
        struct proc_dir_entry *ent;
-       struct device_node *child, *sib;
-       const char *p, *at;
-       int l;
-       struct proc_dir_entry *list, **lastp, *al;
+       struct device_node *child;
+       struct proc_dir_entry *list = NULL, **lastp;
+       const char *p;
 
        set_node_proc_entry(np, de);
        lastp = &list;
-       for (pp = np->properties; pp != 0; pp = pp->next) {
-               /*
-                * Unfortunately proc_register puts each new entry
-                * at the beginning of the list.  So we rearrange them.
-                */
-               ent = create_proc_read_entry(pp->name, strncmp(pp->name, "security-", 9) ?
-                                            S_IRUGO : S_IRUSR, de, property_read_proc, pp);
-               if (ent == 0)
-                       break;
-               if (!strncmp(pp->name, "security-", 9))
-                    ent->size = 0; /* don't leak number of password chars */
-               else
-                    ent->size = pp->length;
-               *lastp = ent;
-               lastp = &ent->next;
-       }
-       child = NULL;
-       while ((child = of_get_next_child(np, child))) {
+       for (child = NULL; (child = of_get_next_child(np, child));) {
                p = strrchr(child->full_name, '/');
                if (!p)
                        p = child->full_name;
                else
                        ++p;
-               /* chop off '@0' if the name ends with that */
-               l = strlen(p);
-               if (l > 2 && p[l-2] == '@' && p[l-1] == '0')
-                       l -= 2;
                ent = proc_mkdir(p, de);
                if (ent == 0)
                        break;
                *lastp = ent;
+               ent->next = NULL;
                lastp = &ent->next;
                proc_device_tree_add_node(child, ent);
-
-               /*
-                * If we left the address part on the name, consider
-                * adding symlinks from the name and address parts.
-                */
-               if (p[l] != 0 || (at = strchr(p, '@')) == 0)
-                       continue;
-
+       }
+       of_node_put(child);
+       for (pp = np->properties; pp != 0; pp = pp->next) {
                /*
-                * If this is the first node with a given name property,
-                * add a symlink with the name property as its name.
+                * Yet another Apple device-tree bogosity: on some machines,
+                * they have properties & nodes with the same name. Those
+                * properties are quite unimportant for us though, thus we
+                * simply "skip" them here, but we do have to check.
                 */
-               sib = NULL;
-               while ((sib = of_get_next_child(np, sib)) && sib != child)
-                       if (sib->name && strcmp(sib->name, child->name) == 0)
-                               break;
-               if (sib == child && strncmp(p, child->name, l) != 0) {
-                       al = proc_symlink(child->name, de, ent->name);
-                       if (al == 0) {
-                               of_node_put(sib);
+               for (ent = list; ent != NULL; ent = ent->next)
+                       if (!strcmp(ent->name, pp->name))
                                break;
-                       }
-                       set_node_name_link(child, al);
-                       *lastp = al;
-                       lastp = &al->next;
+               if (ent != NULL) {
+                       printk(KERN_WARNING "device-tree: property \"%s\" name"
+                              " conflicts with node in %s\n", pp->name,
+                              np->full_name);
+                       continue;
                }
-               of_node_put(sib);
+
                /*
-                * Add another directory with the @address part as its name.
+                * Unfortunately proc_register puts each new entry
+                * at the beginning of the list.  So we rearrange them.
                 */
-               al = proc_symlink(at, de, ent->name);
-               if (al == 0)
+               ent = create_proc_read_entry(pp->name,
+                                            strncmp(pp->name, "security-", 9)
+                                            ? S_IRUGO : S_IRUSR, de,
+                                            property_read_proc, pp);
+               if (ent == 0)
                        break;
-               set_node_addr_link(child, al);
-               *lastp = al;
-               lastp = &al->next;
+               if (!strncmp(pp->name, "security-", 9))
+                    ent->size = 0; /* don't leak number of password chars */
+               else
+                    ent->size = pp->length;
+               ent->next = NULL;
+               *lastp = ent;
+               lastp = &ent->next;
        }
-       of_node_put(child);
-       *lastp = NULL;
        de->subdir = list;
 }
 
index 80e92d9b81cbf2b2cb61142f4cd13989bc77684a..7d4dc5f5aa8b698e7e88c978cfd4978247e3dc38 100644 (file)
@@ -608,7 +608,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode,
         goto out_failed;
     }
 
-    retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
+    retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode);
     if (retval)
         goto out_failed;
        
index da23ba75f3d51006fe6b9486916e8dcd5e23497f..c47f8fd31a2d069e650b17866ab816b3a273b046 100644 (file)
@@ -230,7 +230,6 @@ const struct reiserfs_key  MAX_KEY = {
        __constant_cpu_to_le32(0xffffffff)},}
 };
 
-const struct in_core_key  MAX_IN_CORE_KEY = {~0U, ~0U, ~0ULL>>4, 15};
 
 /* Get delimiting key of the buffer by looking for it in the buffers in the path, starting from the bottom
    of the path, and going upwards.  We must check the path's validity at each step.  If the key is not in
index 31e75125f48bf355b2ad6866a1fcb67ca5965634..b35b87744983f413adab54e11b469c7a90a8e4ac 100644 (file)
@@ -164,7 +164,9 @@ static int finish_unfinished (struct super_block * s)
  
     /* compose key to look for "save" links */
     max_cpu_key.version = KEY_FORMAT_3_5;
-    max_cpu_key.on_disk_key = MAX_IN_CORE_KEY;
+    max_cpu_key.on_disk_key.k_dir_id = ~0U;
+    max_cpu_key.on_disk_key.k_objectid = ~0U;
+    set_cpu_key_k_offset (&max_cpu_key, ~0U);
     max_cpu_key.key_length = 3;
 
 #ifdef CONFIG_QUOTA
index 25b1ccac2f2cdcc73cbc42135837bfed752e7f9e..b80e7eb0ac0dac26325c8ac0d2b7d992c1d7da20 100644 (file)
@@ -55,7 +55,8 @@ struct poll_table_page {
  * as all select/poll functions have to call it to add an entry to the
  * poll table.
  */
-void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p);
+static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
+                      poll_table *p);
 
 void poll_initwait(struct poll_wqueues *pwq)
 {
@@ -87,7 +88,8 @@ void poll_freewait(struct poll_wqueues *pwq)
 
 EXPORT_SYMBOL(poll_freewait);
 
-void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *_p)
+static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
+                      poll_table *_p)
 {
        struct poll_wqueues *p = container_of(_p, struct poll_wqueues, pt);
        struct poll_table_page *table = p->table;
index c2634bda6b5030419d51b71e062b92e28addf8ee..85d8dbe843f1f12eee67836c1e94d006f52858f6 100644 (file)
@@ -46,7 +46,7 @@
 #endif
 
 /* How many days come before each month (0-12).  */
-const unsigned short int __mon_yday[2][13] =
+static const unsigned short int __mon_yday[2][13] =
 {
        /* Normal years.  */
        { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
@@ -103,7 +103,7 @@ udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src)
                offset = 0;
 
        if ((src.year < EPOCH_YEAR) ||
-               (src.year > EPOCH_YEAR+MAX_YEAR_SECONDS))
+               (src.year >= EPOCH_YEAR+MAX_YEAR_SECONDS))
        {
                *dest = -1;
                *dest_usec = -1;
index 554e4a18c152fff3481c0ae06a5a7a39c36ac845..d3ff78354638d671be016821323e4a3279f47446 100644 (file)
@@ -49,7 +49,7 @@ ifeq ($(CONFIG_XFS_TRACE),y)
        EXTRA_CFLAGS += -DXFS_LOG_TRACE
        EXTRA_CFLAGS += -DXFS_RW_TRACE
        EXTRA_CFLAGS += -DPAGEBUF_TRACE
-       EXTRA_CFLAGS += -DXFS_VNODE_TRACE
+       EXTRA_CFLAGS += -DXFS_VNODE_TRACE
 endif
 
 obj-$(CONFIG_XFS_FS)           += xfs.o
index 76a84758073a8eb429f933ac3b6c71b40b50c385..93ce257cd1495cbffdb8cebfda51cd6d9c6431c6 100644 (file)
@@ -558,7 +558,8 @@ xfs_submit_page(
        int                     i;
 
        BUG_ON(PageWriteback(page));
-       set_page_writeback(page);
+       if (bh_count)
+               set_page_writeback(page);
        if (clear_dirty)
                clear_page_dirty(page);
        unlock_page(page);
@@ -578,9 +579,6 @@ xfs_submit_page(
 
                if (probed_page && clear_dirty)
                        wbc->nr_to_write--;     /* Wrote an "extra" page */
-       } else {
-               end_page_writeback(page);
-               wbc->pages_skipped++;   /* We didn't write this page */
        }
 }
 
@@ -602,21 +600,26 @@ xfs_convert_page(
 {
        struct buffer_head      *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
        xfs_iomap_t             *mp = iomapp, *tmp;
-       unsigned long           end, offset;
-       pgoff_t                 end_index;
-       int                     i = 0, index = 0;
+       unsigned long           offset, end_offset;
+       int                     index = 0;
        int                     bbits = inode->i_blkbits;
+       int                     len, page_dirty;
 
-       end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT;
-       if (page->index < end_index) {
-               end = PAGE_CACHE_SIZE;
-       } else {
-               end = i_size_read(inode) & (PAGE_CACHE_SIZE-1);
-       }
+       end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1));
+
+       /*
+        * page_dirty is initially a count of buffers on the page before
+        * EOF and is decrememted as we move each into a cleanable state.
+        */
+       len = 1 << inode->i_blkbits;
+       end_offset = max(end_offset, PAGE_CACHE_SIZE);
+       end_offset = roundup(end_offset, len);
+       page_dirty = end_offset / len;
+
+       offset = 0;
        bh = head = page_buffers(page);
        do {
-               offset = i << bbits;
-               if (offset >= end)
+               if (offset >= end_offset)
                        break;
                if (!(PageUptodate(page) || buffer_uptodate(bh)))
                        continue;
@@ -625,6 +628,7 @@ xfs_convert_page(
                        if (startio) {
                                lock_buffer(bh);
                                bh_arr[index++] = bh;
+                               page_dirty--;
                        }
                        continue;
                }
@@ -657,10 +661,11 @@ xfs_convert_page(
                        unlock_buffer(bh);
                        mark_buffer_dirty(bh);
                }
-       } while (i++, (bh = bh->b_this_page) != head);
+               page_dirty--;
+       } while (offset += len, (bh = bh->b_this_page) != head);
 
-       if (startio) {
-               xfs_submit_page(page, wbc, bh_arr, index, 1, index == i);
+       if (startio && index) {
+               xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty);
        } else {
                unlock_page(page);
        }
@@ -725,8 +730,11 @@ xfs_page_state_convert(
        __uint64_t              end_offset;
        pgoff_t                 end_index, last_index, tlast;
        int                     len, err, i, cnt = 0, uptodate = 1;
-       int                     flags = startio ? 0 : BMAPI_TRYLOCK;
-       int                     page_dirty, delalloc = 0;
+       int                     flags;
+       int                     page_dirty;
+
+       /* wait for other IO threads? */
+       flags = (startio && wbc->sync_mode != WB_SYNC_NONE) ? 0 : BMAPI_TRYLOCK;
 
        /* Is this page beyond the end of the file? */
        offset = i_size_read(inode);
@@ -740,19 +748,22 @@ xfs_page_state_convert(
                }
        }
 
-       offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
        end_offset = min_t(unsigned long long,
-                       offset + PAGE_CACHE_SIZE, i_size_read(inode));
-
-       bh = head = page_buffers(page);
-       iomp = NULL;
+                       (loff_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset);
+       offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
 
        /*
-        * page_dirty is initially a count of buffers on the page and
-        * is decrememted as we move each into a cleanable state.
+        * page_dirty is initially a count of buffers on the page before
+        * EOF and is decrememted as we move each into a cleanable state.
         */
-       len = bh->b_size;
-       page_dirty = PAGE_CACHE_SIZE / len;
+       len = 1 << inode->i_blkbits;
+       p_offset = max(p_offset, PAGE_CACHE_SIZE);
+       p_offset = roundup(p_offset, len);
+       page_dirty = p_offset / len;
+
+       iomp = NULL;
+       p_offset = 0;
+       bh = head = page_buffers(page);
 
        do {
                if (offset >= end_offset)
@@ -804,7 +815,6 @@ xfs_page_state_convert(
                 */
                } else if (buffer_delay(bh)) {
                        if (!iomp) {
-                               delalloc = 1;
                                err = xfs_map_blocks(inode, offset, len, &iomap,
                                                BMAPI_ALLOCATE | flags);
                                if (err) {
@@ -875,14 +885,14 @@ xfs_page_state_convert(
        if (uptodate && bh == head)
                SetPageUptodate(page);
 
-       if (startio)
-               xfs_submit_page(page, wbc, bh_arr, cnt, 0, 1);
+       if (startio) {
+               xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty);
+       }
 
        if (iomp) {
-               tlast = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
+               offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
                                        PAGE_CACHE_SHIFT;
-               if (delalloc && (tlast > last_index))
-                       tlast = last_index;
+               tlast = min_t(pgoff_t, offset, last_index);
                xfs_cluster_write(inode, page->index + 1, iomp, wbc,
                                        startio, unmapped, tlast);
        }
index 23e0eb67fc25e012c291a6efd7fed62ec8b415bb..997963e5362234809dbd14b6a4a52eb1628a75d5 100644 (file)
@@ -1746,13 +1746,15 @@ STATIC DECLARE_COMPLETION(pagebuf_daemon_done);
 STATIC struct task_struct *pagebuf_daemon_task;
 STATIC int pagebuf_daemon_active;
 STATIC int force_flush;
-
+STATIC int force_sleep;
 
 STATIC int
 pagebuf_daemon_wakeup(
        int                     priority,
        unsigned int            mask)
 {
+       if (force_sleep)
+               return 0;
        force_flush = 1;
        barrier();
        wake_up_process(pagebuf_daemon_task);
@@ -1778,7 +1780,12 @@ pagebuf_daemon(
 
        INIT_LIST_HEAD(&tmp);
        do {
-               try_to_freeze(PF_FREEZE);
+               if (unlikely(current->flags & PF_FREEZE)) {
+                       force_sleep = 1;
+                       refrigerator(PF_FREEZE);
+               } else {
+                       force_sleep = 0;
+               }
 
                set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100);
index 9f057a4a5b06a7684db0b95cf8d87bcca61f5826..24fa3b101b93c89ea70cb068f3f256be1fd5e3e5 100644 (file)
@@ -515,10 +515,49 @@ open_exec_out:
 }
 #endif /* HAVE_FOP_OPEN_EXEC */
 
+/*
+ * Temporary workaround to the AIO direct IO write problem.
+ * This code can go and we can revert to do_sync_write once
+ * the writepage(s) rework is merged.
+ */
+STATIC ssize_t
+linvfs_write(
+       struct file     *filp,
+       const char      __user *buf,
+       size_t          len,
+       loff_t          *ppos)
+{
+       struct kiocb    kiocb;
+       ssize_t         ret;
+
+       init_sync_kiocb(&kiocb, filp);
+       kiocb.ki_pos = *ppos;
+       ret = __linvfs_write(&kiocb, buf, 0, len, kiocb.ki_pos);
+       *ppos = kiocb.ki_pos;
+       return ret;
+}
+STATIC ssize_t
+linvfs_write_invis(
+       struct file     *filp,
+       const char      __user *buf,
+       size_t          len,
+       loff_t          *ppos)
+{
+       struct kiocb    kiocb;
+       ssize_t         ret;
+
+       init_sync_kiocb(&kiocb, filp);
+       kiocb.ki_pos = *ppos;
+       ret = __linvfs_write(&kiocb, buf, IO_INVIS, len, kiocb.ki_pos);
+       *ppos = kiocb.ki_pos;
+       return ret;
+}
+
+
 struct file_operations linvfs_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
-       .write          = do_sync_write,
+       .write          = linvfs_write,
        .readv          = linvfs_readv,
        .writev         = linvfs_writev,
        .aio_read       = linvfs_aio_read,
@@ -526,7 +565,7 @@ struct file_operations linvfs_file_operations = {
        .sendfile       = linvfs_sendfile,
        .unlocked_ioctl = linvfs_ioctl,
 #ifdef CONFIG_COMPAT
-       .compat_ioctl   = xfs_compat_ioctl,
+       .compat_ioctl   = linvfs_compat_ioctl,
 #endif
        .mmap           = linvfs_file_mmap,
        .open           = linvfs_open,
@@ -540,7 +579,7 @@ struct file_operations linvfs_file_operations = {
 struct file_operations linvfs_invis_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
-       .write          = do_sync_write,
+       .write          = linvfs_write_invis,
        .readv          = linvfs_readv_invis,
        .writev         = linvfs_writev_invis,
        .aio_read       = linvfs_aio_read_invis,
@@ -548,7 +587,7 @@ struct file_operations linvfs_invis_file_operations = {
        .sendfile       = linvfs_sendfile,
        .unlocked_ioctl = linvfs_ioctl_invis,
 #ifdef CONFIG_COMPAT
-       .compat_ioctl   = xfs_compat_invis_ioctl,
+       .compat_ioctl   = linvfs_compat_invis_ioctl,
 #endif
        .mmap           = linvfs_file_mmap,
        .open           = linvfs_open,
@@ -561,6 +600,9 @@ struct file_operations linvfs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = linvfs_readdir,
        .unlocked_ioctl = linvfs_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = linvfs_compat_ioctl,
+#endif
        .fsync          = linvfs_fsync,
 };
 
index 7a12c83184f57a35093b301e84a0ae61233db38c..0f8f1384eb36a88a20e0e89e34f884436b8063b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -58,8 +58,9 @@ typedef struct xfs_fsop_bulkreq32 {
        __s32           ocount;         /* output count pointer         */
 } xfs_fsop_bulkreq32_t;
 
-static unsigned long
-xfs_ioctl32_bulkstat(unsigned long arg)
+STATIC unsigned long
+xfs_ioctl32_bulkstat(
+       unsigned long           arg)
 {
        xfs_fsop_bulkreq32_t    __user *p32 = (void __user *)arg;
        xfs_fsop_bulkreq_t      __user *p = compat_alloc_user_space(sizeof(*p));
@@ -78,11 +79,11 @@ xfs_ioctl32_bulkstat(unsigned long arg)
 }
 #endif
 
-static long
-__xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
+STATIC long
+__linvfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
 {
        int             error;
-       struct inode *inode = f->f_dentry->d_inode;
+       struct          inode *inode = f->f_dentry->d_inode;
        vnode_t         *vp = LINVFS_GET_VP(inode);
 
        switch (cmd) {
@@ -152,12 +153,20 @@ __xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
        return error;
 }
 
-long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg)
+long
+linvfs_compat_ioctl(
+       struct file             *f,
+       unsigned                cmd,
+       unsigned long           arg)
 {
-       return __xfs_compat_ioctl(0, f, cmd, arg);
+       return __linvfs_compat_ioctl(0, f, cmd, arg);
 }
 
-long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg)
+long
+linvfs_compat_invis_ioctl(
+       struct file             *f,
+       unsigned                cmd,
+       unsigned long           arg)
 {
-       return __xfs_compat_ioctl(IO_INVIS, f, cmd, arg);
+       return __linvfs_compat_ioctl(IO_INVIS, f, cmd, arg);
 }
index 779f69a4811656a0f34b85a01192573ff0f8d4ed..c874793a1dc9567a6f5237bc4126bdfbbe36f1fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -30,5 +30,5 @@
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
-long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
-long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg);
+long linvfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
+long linvfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg);
index ff145fd0d1a42e3771a0f4fd4691565864fce7b6..aa9daaea6c34b2d98697b899e73ee10e4222e1bb 100644 (file)
@@ -683,6 +683,9 @@ xfs_write(
                        (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
                                mp->m_rtdev_targp : mp->m_ddev_targp;
 
+               if (ioflags & IO_ISAIO)
+                       return XFS_ERROR(-ENOSYS);
+
                if ((pos & target->pbr_smask) || (count & target->pbr_smask))
                        return XFS_ERROR(-EINVAL);
 
index 53dc658cafa638976c4398f240aa035663fb7d67..455e2b2fb9640dbf598e48ca77d9bb415edeb134 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -66,7 +66,6 @@
 #include "xfs_buf_item.h"
 #include "xfs_utils.h"
 #include "xfs_version.h"
-#include "xfs_ioctl32.h"
 
 #include <linux/namei.h>
 #include <linux/init.h>
index 849c61c74f3cfbb19a4b29696380ec33b27dce3d..a832d165f24ff6d7e84fded59529439f1a16cfb0 100644 (file)
@@ -156,7 +156,6 @@ vn_initialize(
 
 #ifdef XFS_VNODE_TRACE
        vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
-       printk("Allocated VNODE_TRACE at 0x%p\n", vp->v_trace);
 #endif /* XFS_VNODE_TRACE */
 
        vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address);
@@ -424,13 +423,13 @@ vn_remove(
  * Vnode tracing code.
  */
 void
-vn_trace_entry(vnode_t *vp, char *func, inst_t *ra)
+vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra)
 {
        KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
 }
 
 void
-vn_trace_exit(vnode_t *vp, char *func, inst_t *ra)
+vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra)
 {
        KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
 }
index da76c1f1e11ca8db8c0f45ecaefbd2948a80e686..00466c3194acc29f194adba50c1eb0e7b2ebebc0 100644 (file)
@@ -86,10 +86,11 @@ typedef struct vnode {
        vnumber_t       v_number;               /* in-core vnode number */
        vn_bhv_head_t   v_bh;                   /* behavior head */
        spinlock_t      v_lock;                 /* VN_LOCK/VN_UNLOCK */
-       struct inode    v_inode;                /* Linux inode */
 #ifdef XFS_VNODE_TRACE
        struct ktrace   *v_trace;               /* trace header structure    */
 #endif
+       struct inode    v_inode;                /* Linux inode */
+       /* inode MUST be last */
 } vnode_t;
 
 #define v_fbhv                 v_bh.bh_first          /* first behavior */
@@ -409,7 +410,7 @@ typedef struct vattr {
        int             va_mask;        /* bit-mask of attributes present */
        enum vtype      va_type;        /* vnode type (for create) */
        mode_t          va_mode;        /* file access mode and type */
-       nlink_t         va_nlink;       /* number of references to file */
+       xfs_nlink_t     va_nlink;       /* number of references to file */
        uid_t           va_uid;         /* owner user id */
        gid_t           va_gid;         /* owner group id */
        xfs_ino_t       va_nodeid;      /* file id */
@@ -625,6 +626,7 @@ static inline int VN_BAD(struct vnode *vp)
 #define        ATTR_DMI        0x08    /* invocation from a DMI function */
 #define        ATTR_LAZY       0x80    /* set/get attributes lazily */
 #define        ATTR_NONBLOCK   0x100   /* return EAGAIN if operation would block */
+#define ATTR_NOLOCK    0x200   /* Don't grab any conflicting locks */
 
 /*
  * Flags to VOP_FSYNC and VOP_RECLAIM.
@@ -646,8 +648,8 @@ static inline int VN_BAD(struct vnode *vp)
 #define        VNODE_KTRACE_REF        4
 #define        VNODE_KTRACE_RELE       5
 
-extern void vn_trace_entry(struct vnode *, char *, inst_t *);
-extern void vn_trace_exit(struct vnode *, char *, inst_t *);
+extern void vn_trace_entry(struct vnode *, const char *, inst_t *);
+extern void vn_trace_exit(struct vnode *, const char *, inst_t *);
 extern void vn_trace_hold(struct vnode *, char *, int, inst_t *);
 extern void vn_trace_ref(struct vnode *, char *, int, inst_t *);
 extern void vn_trace_rele(struct vnode *, char *, int, inst_t *);
index 08d551a173478da6dd21b37238b2f5fb1ec88ee6..63abdc2ac7f4ba0da434c45e32f08a8e6be5209a 100644 (file)
@@ -182,7 +182,7 @@ xfs_swapext(
 
        if (VN_CACHED(tvp) != 0)
                xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore),
-                                               (loff_t)0, 0, 0);
+                                               (xfs_off_t)0, 0, 0);
 
        /* Verify O_DIRECT for ftmp */
        if (VN_CACHED(tvp) != 0) {
index 3a0ba1dfd0e87cd6fda3224acbe02adb466265ba..d3da00045f260074fca466319a23bfdc34ed14c3 100644 (file)
@@ -135,6 +135,40 @@ xfs_chash_free(xfs_mount_t *mp)
        mp->m_chash = NULL;
 }
 
+/*
+ * Try to move an inode to the front of its hash list if possible
+ * (and if its not there already).  Called right after obtaining
+ * the list version number and then dropping the read_lock on the
+ * hash list in question (which is done right after looking up the
+ * inode in question...).
+ */
+STATIC void
+xfs_ihash_promote(
+       xfs_ihash_t     *ih,
+       xfs_inode_t     *ip,
+       ulong           version)
+{
+       xfs_inode_t     *iq;
+
+       if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) {
+               if (likely(version == ih->ih_version)) {
+                       /* remove from list */
+                       if ((iq = ip->i_next)) {
+                               iq->i_prevp = ip->i_prevp;
+                       }
+                       *ip->i_prevp = iq;
+
+                       /* insert at list head */
+                       iq = ih->ih_next;
+                       iq->i_prevp = &ip->i_next;
+                       ip->i_next = iq;
+                       ip->i_prevp = &ih->ih_next;
+                       ih->ih_next = ip;
+               }
+               write_unlock(&ih->ih_lock);
+       }
+}
+
 /*
  * Look up an inode by number in the given file system.
  * The inode is looked up in the hash table for the file system
@@ -229,7 +263,9 @@ again:
                                XFS_STATS_INC(xs_ig_found);
 
                                ip->i_flags &= ~XFS_IRECLAIMABLE;
+                               version = ih->ih_version;
                                read_unlock(&ih->ih_lock);
+                               xfs_ihash_promote(ih, ip, version);
 
                                XFS_MOUNT_ILOCK(mp);
                                list_del_init(&ip->i_reclaim);
@@ -259,8 +295,15 @@ again:
                                                inode_vp, vp);
                        }
 
+                       /*
+                        * Inode cache hit: if ip is not at the front of
+                        * its hash chain, move it there now.
+                        * Do this with the lock held for update, but
+                        * do statistics after releasing the lock.
+                        */
+                       version = ih->ih_version;
                        read_unlock(&ih->ih_lock);
-
+                       xfs_ihash_promote(ih, ip, version);
                        XFS_STATS_INC(xs_ig_found);
 
 finish_inode:
@@ -547,6 +590,7 @@ xfs_inode_incore(xfs_mount_t        *mp,
 {
        xfs_ihash_t     *ih;
        xfs_inode_t     *ip;
+       ulong           version;
 
        ih = XFS_IHASH(mp, ino);
        read_lock(&ih->ih_lock);
@@ -554,11 +598,15 @@ xfs_inode_incore(xfs_mount_t      *mp,
                if (ip->i_ino == ino) {
                        /*
                         * If we find it and tp matches, return it.
+                        * Also move it to the front of the hash list
+                        * if we find it and it is not already there.
                         * Otherwise break from the loop and return
                         * NULL.
                         */
                        if (ip->i_transp == tp) {
+                               version = ih->ih_version;
                                read_unlock(&ih->ih_lock);
+                               xfs_ihash_promote(ih, ip, version);
                                return (ip);
                        }
                        break;
@@ -685,6 +733,7 @@ xfs_iextract(
                iq->i_prevp = ip->i_prevp;
        }
        *ip->i_prevp = iq;
+       ih->ih_version++;
        write_unlock(&ih->ih_lock);
 
        /*
index 43c632ab86adc45783fec2066eb8db2ff4afb8a2..bc8c8c7f9039d507978d727a25c446b661af4d56 100644 (file)
@@ -1130,7 +1130,7 @@ xfs_ialloc(
        xfs_trans_t     *tp,
        xfs_inode_t     *pip,
        mode_t          mode,
-       nlink_t         nlink,
+       xfs_nlink_t     nlink,
        xfs_dev_t       rdev,
        cred_t          *cr,
        xfs_prid_t      prid,
index a53b1ccf60700c21f5a4cb12593e9450a520d045..37e1c316f3b6bd520c37d4bea1a86aeaf0375a6e 100644 (file)
@@ -495,9 +495,9 @@ int         xfs_itobp(struct xfs_mount *, struct xfs_trans *,
 int            xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
                          xfs_inode_t **, xfs_daddr_t);
 int            xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
-int            xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, nlink_t,
-                          xfs_dev_t, struct cred *, xfs_prid_t, int,
-                          struct xfs_buf **, boolean_t *, xfs_inode_t **);
+int            xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
+                          xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
+                          int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
 void           xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *,
                                        int);
 uint           xfs_ip2xflags(struct xfs_inode *);
index 3826e8f0e28a6d5eaa8c65e407d7d465ac3df881..469e1a7939d44fbbe4dfbdbe8c9b2e90f0d4f7f2 100644 (file)
@@ -278,7 +278,9 @@ phase2:
        switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) {
        case BMAPI_WRITE:
                /* If we found an extent, return it */
-               if (nimaps && (imap.br_startblock != HOLESTARTBLOCK)) {
+               if (nimaps &&
+                   (imap.br_startblock != HOLESTARTBLOCK) && 
+                   (imap.br_startblock != DELAYSTARTBLOCK)) {
                        xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,
                                        offset, count, iomapp, &imap, flags);
                        break;
@@ -308,7 +310,8 @@ phase2:
                        break;
                }
 
-               error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps);
+               error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count,
+                                                &imap, &nimaps);
                break;
        case BMAPI_UNWRITTEN:
                lockmode = 0;
@@ -365,7 +368,7 @@ xfs_flush_space(
 int
 xfs_iomap_write_direct(
        xfs_inode_t     *ip,
-       loff_t          offset,
+       xfs_off_t       offset,
        size_t          count,
        int             flags,
        xfs_bmbt_irec_t *ret_imap,
@@ -541,7 +544,7 @@ error_out:
 int
 xfs_iomap_write_delay(
        xfs_inode_t     *ip,
-       loff_t          offset,
+       xfs_off_t       offset,
        size_t          count,
        int             ioflag,
        xfs_bmbt_irec_t *ret_imap,
@@ -746,6 +749,8 @@ write_map:
 int
 xfs_iomap_write_allocate(
        xfs_inode_t     *ip,
+       xfs_off_t       offset,
+       size_t          count,
        xfs_bmbt_irec_t *map,
        int             *retmap)
 {
@@ -770,9 +775,9 @@ xfs_iomap_write_allocate(
        if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
                return XFS_ERROR(error);
 
-       offset_fsb = map->br_startoff;
+       offset_fsb = XFS_B_TO_FSBT(mp, offset);
        count_fsb = map->br_blockcount;
-       map_start_fsb = offset_fsb;
+       map_start_fsb = map->br_startoff;
 
        XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
 
@@ -868,9 +873,9 @@ xfs_iomap_write_allocate(
                                        imap[i].br_startoff,
                                        imap[i].br_blockcount,imap[i].br_state);
                         }
-                       if ((map->br_startoff >= imap[i].br_startoff) &&
-                           (map->br_startoff < (imap[i].br_startoff +
-                                                imap[i].br_blockcount))) {
+                       if ((offset_fsb >= imap[i].br_startoff) &&
+                           (offset_fsb < (imap[i].br_startoff +
+                                          imap[i].br_blockcount))) {
                                *map = imap[i];
                                *retmap = 1;
                                XFS_STATS_INC(xs_xstrat_quick);
@@ -883,9 +888,8 @@ xfs_iomap_write_allocate(
                 * file, just surrounding data, try again.
                 */
                nimaps--;
-               offset_fsb = imap[nimaps].br_startoff +
-                            imap[nimaps].br_blockcount;
-               map_start_fsb = offset_fsb;
+               map_start_fsb = imap[nimaps].br_startoff +
+                               imap[nimaps].br_blockcount;
        }
 
 trans_cancel:
@@ -899,7 +903,7 @@ error0:
 int
 xfs_iomap_write_unwritten(
        xfs_inode_t     *ip,
-       loff_t          offset,
+       xfs_off_t       offset,
        size_t          count)
 {
        xfs_mount_t     *mp = ip->i_mount;
index 31c91087cb3343f2e6d536072db654a80478056b..4daaa5212102a5fcb763309c4f2a4cfb360506f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003,2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2003-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -29,9 +29,6 @@
  *
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
-
-
-
 #ifndef __XFS_IOMAP_H__
 #define __XFS_IOMAP_H__
 
@@ -56,7 +53,7 @@ typedef enum {
        BMAPI_UNWRITTEN  = (1 << 3),    /* unwritten extents to real extents */
        /* modifiers */
        BMAPI_IGNSTATE = (1 << 4),      /* ignore unwritten state on read */
-       BMAPI_DIRECT = (1 << 5),                /* direct instead of buffered write */
+       BMAPI_DIRECT = (1 << 5),        /* direct instead of buffered write */
        BMAPI_MMAP = (1 << 6),          /* allocate for mmap write */
        BMAPI_SYNC = (1 << 7),          /* sync write to flush delalloc space */
        BMAPI_TRYLOCK = (1 << 8),       /* non-blocking request */
@@ -67,13 +64,13 @@ typedef enum {
 /*
  * xfs_iomap_t:  File system I/O map
  *
- * The iomap_bn field is expressed in 512-byte blocks, and is where the 
+ * The iomap_bn field is expressed in 512-byte blocks, and is where the
  * mapping starts on disk.
  *
  * The iomap_offset, iomap_bsize and iomap_delta fields are in bytes.
  * iomap_offset is the offset of the mapping in the file itself.
- * iomap_bsize is the size of the mapping,  iomap_delta is the 
- * desired data's offset into the mapping, given the offset supplied 
+ * iomap_bsize is the size of the mapping,  iomap_delta is the
+ * desired data's offset into the mapping, given the offset supplied
  * to the file I/O map routine.
  *
  * When a request is made to read beyond the logical end of the object,
@@ -84,8 +81,8 @@ typedef enum {
 typedef struct xfs_iomap {
        xfs_daddr_t             iomap_bn;       /* first 512b blk of mapping */
        xfs_buftarg_t           *iomap_target;
-       loff_t                  iomap_offset;   /* offset of mapping, bytes */
-       loff_t                  iomap_bsize;    /* size of mapping, bytes */
+       xfs_off_t               iomap_offset;   /* offset of mapping, bytes */
+       xfs_off_t               iomap_bsize;    /* size of mapping, bytes */
        size_t                  iomap_delta;    /* offset into mapping, bytes */
        iomap_flags_t           iomap_flags;
 } xfs_iomap_t;
@@ -96,12 +93,12 @@ struct xfs_bmbt_irec;
 
 extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int,
                     struct xfs_iomap *, int *);
-extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t,
+extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t,
                                  int, struct xfs_bmbt_irec *, int *, int);
-extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int,
+extern int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int,
                                 struct xfs_bmbt_irec *, int *);
-extern int xfs_iomap_write_allocate(struct xfs_inode *,
+extern int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t,
                                struct xfs_bmbt_irec *, int *);
-extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t);
+extern int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t);
 
 #endif /* __XFS_IOMAP_H__*/
index b57423caef9b86fa0f3fb381d0610f8c3afa8f45..2ec967d93e5ae5eb2aaf1ac06441294ee357382a 100644 (file)
@@ -300,6 +300,15 @@ xfs_mount_validate_sb(
                return XFS_ERROR(EFSCORRUPTED);
        }
 
+       /*
+        * Version 1 directory format has never worked on Linux.
+        */
+       if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) {
+               cmn_err(CE_WARN,
+       "XFS: Attempted to mount file system using version 1 directory format");
+               return XFS_ERROR(ENOSYS);
+       }
+
        /*
         * Until this is fixed only page-sized or smaller data blocks work.
         */
index 5fc6201dd8e2972a6970ad17a22416e209b99edc..30dd08fb9f577bb1943e54d83ba9d3625a45303f 100644 (file)
@@ -210,15 +210,16 @@ typedef int               (*xfs_bmapi_t)(struct xfs_trans *, void *,
                                struct xfs_bmap_free *);
 typedef int            (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
 typedef int            (*xfs_iomap_write_direct_t)(
-                               void *, loff_t, size_t, int,
+                               void *, xfs_off_t, size_t, int,
                                struct xfs_bmbt_irec *, int *, int);
 typedef int            (*xfs_iomap_write_delay_t)(
-                               void *, loff_t, size_t, int,
+                               void *, xfs_off_t, size_t, int,
                                struct xfs_bmbt_irec *, int *);
 typedef int            (*xfs_iomap_write_allocate_t)(
-                               void *, struct xfs_bmbt_irec *, int *);
+                               void *, xfs_off_t, size_t,
+                               struct xfs_bmbt_irec *, int *);
 typedef int            (*xfs_iomap_write_unwritten_t)(
-                               void *, loff_t, size_t);
+                               void *, xfs_off_t, size_t);
 typedef uint           (*xfs_lck_map_shared_t)(void *);
 typedef void           (*xfs_lock_t)(void *, uint);
 typedef void           (*xfs_lock_demote_t)(void *, uint);
@@ -258,9 +259,9 @@ typedef struct xfs_ioops {
 #define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \
        (*(mp)->m_io_ops.xfs_iomap_write_delay) \
                ((io)->io_obj, offset, count, flags, mval, nmap)
-#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, mval, nmap) \
+#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \
        (*(mp)->m_io_ops.xfs_iomap_write_allocate) \
-               ((io)->io_obj, mval, nmap)
+               ((io)->io_obj, offset, count, mval, nmap)
 #define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \
        (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \
                ((io)->io_obj, offset, count)
@@ -428,10 +429,10 @@ typedef struct xfs_mount {
 #define XFS_WRITEIO_LOG_LARGE  16
 
 /*
- * Max and min values for UIO and mount-option defined I/O sizes;
- * min value can't be less than a page.  Currently unused.
+ * Max and min values for mount-option defined I/O
+ * preallocation sizes.
  */
-#define XFS_MAX_IO_LOG         16      /* 64K */
+#define XFS_MAX_IO_LOG         30      /* 1G */
 #define XFS_MIN_IO_LOG         PAGE_SHIFT
 
 /*
index 04609d27ea519d13676e2b99fd8f21d25d9da57e..e4bf711e48ff80f3b1fc9241b12c9bffc94dc348 100644 (file)
@@ -63,6 +63,7 @@ typedef __u64                 xfs_ino_t;      /* <inode> type */
 typedef __s64                  xfs_daddr_t;    /* <disk address> type */
 typedef char *                 xfs_caddr_t;    /* <core address> type */
 typedef __u32                  xfs_dev_t;
+typedef __u32                  xfs_nlink_t;
 
 /* __psint_t is the same size as a pointer */
 #if (BITS_PER_LONG == 32)
index 816b945fa0ea88f92b11e6f69988f6748c8732c7..d1f8146a06ea16d39c09b3997e819800a5189d05 100644 (file)
@@ -147,7 +147,7 @@ xfs_dir_ialloc(
        xfs_inode_t     *dp,            /* directory within whose allocate
                                           the inode. */
        mode_t          mode,
-       nlink_t         nlink,
+       xfs_nlink_t     nlink,
        xfs_dev_t       rdev,
        cred_t          *credp,
        prid_t          prid,           /* project id */
index e1ed6a5880007ffd72d3318f67fc5f5d4309802a..01d98b4b7af76b7ea0e5b61aa69e27da12334a7a 100644 (file)
@@ -42,7 +42,7 @@ extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **);
 extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *,
                                xfs_inode_t **);
 extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
-extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, nlink_t,
+extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t,
                                xfs_dev_t, cred_t *, prid_t, int,
                                xfs_inode_t **, int *);
 extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *);
index 00aae9c6a904e09865cd727aad754c8f83ba43ef..b53736650100d3f62644e00ed0de2e1dba685d51 100644 (file)
@@ -1649,6 +1649,7 @@ xfs_vget(
 #define MNTOPT_SWIDTH  "swidth"        /* data volume stripe width */
 #define MNTOPT_NOUUID  "nouuid"        /* ignore filesystem UUID */
 #define MNTOPT_MTPT    "mtpt"          /* filesystem mount point */
+#define MNTOPT_ALLOCSIZE    "allocsize"    /* preferred allocation size */
 #define MNTOPT_IHASHSIZE    "ihashsize"    /* size of inode hash table */
 #define MNTOPT_NORECOVERY   "norecovery"   /* don't run XFS recovery */
 #define MNTOPT_NOLOGFLUSH   "nologflush"   /* don't hard flush on log writes */
@@ -1657,6 +1658,28 @@ xfs_vget(
 #define MNTOPT_IKEEP   "ikeep"         /* do not free empty inode clusters */
 #define MNTOPT_NOIKEEP "noikeep"       /* free empty inode clusters */
 
+STATIC unsigned long
+suffix_strtoul(const char *cp, char **endp, unsigned int base)
+{
+       int     last, shift_left_factor = 0;
+       char    *value = (char *)cp;
+
+       last = strlen(value) - 1;
+       if (value[last] == 'K' || value[last] == 'k') {
+               shift_left_factor = 10;
+               value[last] = '\0';
+       }
+       if (value[last] == 'M' || value[last] == 'm') {
+               shift_left_factor = 20;
+               value[last] = '\0';
+       }
+       if (value[last] == 'G' || value[last] == 'g') {
+               shift_left_factor = 30;
+               value[last] = '\0';
+       }
+
+       return simple_strtoul(cp, endp, base) << shift_left_factor;
+}
 
 int
 xfs_parseargs(
@@ -1688,60 +1711,60 @@ xfs_parseargs(
                if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
                        if (!value || !*value) {
                                printk("XFS: %s option requires an argument\n",
-                                       MNTOPT_LOGBUFS);
+                                       this_char);
                                return EINVAL;
                        }
                        args->logbufs = simple_strtoul(value, &eov, 10);
                } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
-                       int     last, in_kilobytes = 0;
-
                        if (!value || !*value) {
                                printk("XFS: %s option requires an argument\n",
-                                       MNTOPT_LOGBSIZE);
+                                       this_char);
                                return EINVAL;
                        }
-                       last = strlen(value) - 1;
-                       if (value[last] == 'K' || value[last] == 'k') {
-                               in_kilobytes = 1;
-                               value[last] = '\0';
-                       }
-                       args->logbufsize = simple_strtoul(value, &eov, 10);
-                       if (in_kilobytes)
-                               args->logbufsize <<= 10;
+                       args->logbufsize = suffix_strtoul(value, &eov, 10);
                } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
                        if (!value || !*value) {
                                printk("XFS: %s option requires an argument\n",
-                                       MNTOPT_LOGDEV);
+                                       this_char);
                                return EINVAL;
                        }
                        strncpy(args->logname, value, MAXNAMELEN);
                } else if (!strcmp(this_char, MNTOPT_MTPT)) {
                        if (!value || !*value) {
                                printk("XFS: %s option requires an argument\n",
-                                       MNTOPT_MTPT);
+                                       this_char);
                                return EINVAL;
                        }
                        strncpy(args->mtpt, value, MAXNAMELEN);
                } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
                        if (!value || !*value) {
                                printk("XFS: %s option requires an argument\n",
-                                       MNTOPT_RTDEV);
+                                       this_char);
                                return EINVAL;
                        }
                        strncpy(args->rtname, value, MAXNAMELEN);
                } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
                        if (!value || !*value) {
                                printk("XFS: %s option requires an argument\n",
-                                       MNTOPT_BIOSIZE); 
+                                       this_char);
                                return EINVAL;
                        }
                        iosize = simple_strtoul(value, &eov, 10);
                        args->flags |= XFSMNT_IOSIZE;
                        args->iosizelog = (uint8_t) iosize;
+               } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
+                       if (!value || !*value) {
+                               printk("XFS: %s option requires an argument\n",
+                                       this_char);
+                               return EINVAL;
+                       }
+                       iosize = suffix_strtoul(value, &eov, 10);
+                       args->flags |= XFSMNT_IOSIZE;
+                       args->iosizelog = ffs(iosize) - 1;
                } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
                        if (!value || !*value) {
                                printk("XFS: %s option requires an argument\n",
-                                       this_char); 
+                                       this_char);
                                return EINVAL;
                        }
                        args->flags |= XFSMNT_IHASHSIZE;
@@ -1756,7 +1779,7 @@ xfs_parseargs(
                        args->flags |= XFSMNT_INO64;
 #if !XFS_BIG_INUMS
                        printk("XFS: %s option not allowed on this system\n",
-                               MNTOPT_INO64);
+                               this_char);
                        return EINVAL;
 #endif
                } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
@@ -1766,14 +1789,14 @@ xfs_parseargs(
                } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
                        if (!value || !*value) {
                                printk("XFS: %s option requires an argument\n",
-                                       MNTOPT_SUNIT);
+                                       this_char);
                                return EINVAL;
                        }
                        dsunit = simple_strtoul(value, &eov, 10);
                } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
                        if (!value || !*value) {
                                printk("XFS: %s option requires an argument\n",
-                                       MNTOPT_SWIDTH);
+                                       this_char);
                                return EINVAL;
                        }
                        dswidth = simple_strtoul(value, &eov, 10);
@@ -1781,7 +1804,7 @@ xfs_parseargs(
                        args->flags &= ~XFSMNT_32BITINODES;
 #if !XFS_BIG_INUMS
                        printk("XFS: %s option not allowed on this system\n",
-                               MNTOPT_64BITINODE);
+                               this_char);
                        return EINVAL;
 #endif
                } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
@@ -1877,7 +1900,7 @@ xfs_showargs(
                seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
 
        if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
-               seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log);
+               seq_printf(m, "," MNTOPT_ALLOCSIZE "=%d", 1<<mp->m_writeio_log);
 
        if (mp->m_logbufs > 0)
                seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
index 70092963ca9eb31e7c492dbf70f78946874b0fac..25a526629b125163c772815025fec6be0d283657 100644 (file)
@@ -305,7 +305,7 @@ xfs_setattr(
        int                     mandlock_before, mandlock_after;
        struct xfs_dquot        *udqp, *gdqp, *olddquot1, *olddquot2;
        int                     file_owner;
-       int                     need_iolock = (flags & ATTR_DMI) == 0;
+       int                     need_iolock = 1;
 
        vp = BHV_TO_VNODE(bdp);
        vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -384,6 +384,9 @@ xfs_setattr(
         */
        tp = NULL;
        lock_flags = XFS_ILOCK_EXCL;
+       ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1);
+       if (flags & ATTR_NOLOCK)
+               need_iolock = 0;
        if (!(mask & XFS_AT_SIZE)) {
                if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) ||
                    (mp->m_flags & XFS_MOUNT_WSYNC)) {
@@ -4320,7 +4323,7 @@ xfs_free_file_space(
        int                     rt;
        xfs_fileoff_t           startoffset_fsb;
        xfs_trans_t             *tp;
-       int                     need_iolock = (attr_flags & ATTR_DMI) == 0;
+       int                     need_iolock = 1;
 
        vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
        mp = ip->i_mount;
@@ -4348,8 +4351,12 @@ xfs_free_file_space(
                        return(error);
        }
 
+       ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
+       if (attr_flags & ATTR_NOLOCK)
+               need_iolock = 0;
        if (need_iolock)
                xfs_ilock(ip, XFS_IOLOCK_EXCL);
+
        rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
                        (__uint8_t)NBPP);
        ilen = len + (offset & (rounding - 1));
index c99dbbb5bcb5ae32f02d8c3f4af9d3c4d2638f77..ef855a3bc0f54eed5048af5cf636d4c365bf29e7 100644 (file)
 #define flush_agp_mappings() 
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+
 #endif
index 4e0842b415aa2d317a8c2b4e586eed30aa8da183..1a2c52a056fb8cc23f985ea2b1aea674ab4e2262 100644 (file)
@@ -113,16 +113,7 @@ typedef unsigned long sigset_t;
 #define SIG_UNBLOCK        2   /* for unblocking signals */
 #define SIG_SETMASK        3   /* for setting the signal mask */
 
-/* Type of a signal handler.  */
-typedef void __signalfn_t(int);
-typedef __signalfn_t __user *__sighandler_t;
-
-typedef void __restorefn_t(void);
-typedef __restorefn_t __user *__sigrestore_t;
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct osf_sigaction {
index f32c203952cf766617f2b1464513661db48c629d..93b840e8fa603d32d5b9e6fcfbbb33e7fa0e0b37 100644 (file)
 #define PD31_PF_TMR2OUT      ( GPIO_PORTD | GPIO_PF | 31 )
 #define PD31_BIN_SPI2_TXD    ( GPIO_PORTD | GPIO_BIN | 31 )
 
+/*
+ * PWM controller
+ */
+#define PWMC   __REG(IMX_PWM_BASE + 0x00)      /* PWM Control Register         */
+#define PWMS   __REG(IMX_PWM_BASE + 0x04)      /* PWM Sample Register          */
+#define PWMP   __REG(IMX_PWM_BASE + 0x08)      /* PWM Period Register          */
+#define PWMCNT __REG(IMX_PWM_BASE + 0x0C)      /* PWM Counter Register         */
+
+#define PWMC_HCTR              (0x01<<18)              /* Halfword FIFO Data Swapping  */
+#define PWMC_BCTR              (0x01<<17)              /* Byte FIFO Data Swapping      */
+#define PWMC_SWR               (0x01<<16)              /* Software Reset               */
+#define PWMC_CLKSRC            (0x01<<15)              /* Clock Source                 */
+#define PWMC_PRESCALER(x)      (((x-1) & 0x7F) << 8)   /* PRESCALER                    */
+#define PWMC_IRQ               (0x01<< 7)              /* Interrupt Request            */
+#define PWMC_IRQEN             (0x01<< 6)              /* Interrupt Request Enable     */
+#define PWMC_FIFOAV            (0x01<< 5)              /* FIFO Available               */
+#define PWMC_EN                        (0x01<< 4)              /* Enables/Disables the PWM     */
+#define PWMC_REPEAT(x)         (((x) & 0x03) << 2)     /* Sample Repeats               */
+#define PWMC_CLKSEL(x)         (((x) & 0x03) << 0)     /* Clock Selection              */
+
+#define PWMS_SAMPLE(x)         ((x) & 0xFFFF)          /* Contains a two-sample word   */
+#define PWMP_PERIOD(x)         ((x) & 0xFFFF)          /* Represents the PWM's period  */
+#define PWMC_COUNTER(x)                ((x) & 0xFFFF)          /* Represents the current count value   */
+
 /*
  *  DMA Controller
  */
diff --git a/include/asm-arm/arch-imx/imxfb.h b/include/asm-arm/arch-imx/imxfb.h
new file mode 100644 (file)
index 0000000..2346d45
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * This structure describes the machine which we are running on.
+ */
+struct imxfb_mach_info {
+       u_long          pixclock;
+
+       u_short         xres;
+       u_short         yres;
+
+       u_char          bpp;
+       u_char          hsync_len;
+       u_char          left_margin;
+       u_char          right_margin;
+
+       u_char          vsync_len;
+       u_char          upper_margin;
+       u_char          lower_margin;
+       u_char          sync;
+
+       u_int           cmap_greyscale:1,
+                       cmap_inverse:1,
+                       cmap_static:1,
+                       unused:29;
+
+       u_int           pcr;
+       u_int           pwmr;
+       u_int           lscr1;
+
+       u_char * fixed_screen_cpu;
+       dma_addr_t fixed_screen_dma;
+
+       void (*lcd_power)(int);
+       void (*backlight_power)(int);
+};
+void set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info);
index a8e3c2daefd61528485d42b7f4b5b38d68345ce8..083462668e184a8953ef49ed8eb9753c38d35d24 100644 (file)
@@ -75,8 +75,8 @@ static inline void insw(u32 ptr, void *buf, int length)
         * Is this cycle meant for the CS8900?
         */
        if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-               ((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-                (port <= IXDP2X01_CS8900_VIRT_END))) {
+               (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+                ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
                u8 *buf8 = (u8*)buf;
                register u32 tmp32;
 
@@ -100,8 +100,8 @@ static inline void outsw(u32 ptr, void *buf, int length)
         * Is this cycle meant for the CS8900?
         */
        if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-               ((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-                (port <= IXDP2X01_CS8900_VIRT_END))) {
+               (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+                ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
                register u32 tmp32;
                u8 *buf8 = (u8*)buf;
                do {
@@ -124,8 +124,8 @@ static inline u16 inw(u32 ptr)
         * Is this cycle meant for the CS8900?
         */
        if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-               ((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-                (port <= IXDP2X01_CS8900_VIRT_END))) {
+               (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+                ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
                return (u16)(*port);  
        }
 
@@ -137,8 +137,8 @@ static inline void outw(u16 value, u32 ptr)
        register volatile u32 *port = (volatile u32 *)ptr;
 
        if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-               ((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-                (port <= IXDP2X01_CS8900_VIRT_END))) {
+               (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+                ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
                *port = value;  
                return;
        }
index 39741d3c9a34b199023762377c57f575b0b7e1f7..b5e54a9e9fa76992f06da1e944ead0bd951d95a0 100644 (file)
 #define GPIO111_MMCDAT3                111     /* MMC DAT3 (PXA27x) */
 #define GPIO111_MMCCS1         111     /* MMC Chip Select 1 (PXA27x) */
 #define GPIO112_MMCCMD         112     /* MMC CMD (PXA27x) */
+#define GPIO113_I2S_SYSCLK     113     /* I2S System Clock (PXA27x) */
 #define GPIO113_AC97_RESET_N   113     /* AC97 NRESET on (PXA27x) */
 
 /* GPIO alternate function mode & direction */
 #define GPIO111_MMCDAT3_MD     (111 | GPIO_ALT_FN_1_OUT)
 #define GPIO110_MMCCS1_MD      (111 | GPIO_ALT_FN_1_OUT)
 #define GPIO112_MMCCMD_MD      (112 | GPIO_ALT_FN_1_OUT)
+#define GPIO113_I2S_SYSCLK_MD  (113 | GPIO_ALT_FN_1_OUT)
 #define GPIO113_AC97_RESET_N_MD        (113 | GPIO_ALT_FN_2_OUT)
 #define GPIO117_I2CSCL_MD      (117 | GPIO_ALT_FN_1_OUT)
 #define GPIO118_I2CSDA_MD      (118 | GPIO_ALT_FN_1_IN)
index c443ac83469862d688ceb66df0f620429431fbec..7cff235e667aeea2ef79c9d002bebc85b2d95abb 100644 (file)
@@ -1,16 +1,17 @@
 /* linux/include/asm-arm/arch-s3c2410/regs-nand.h
  *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * Copyright (c) 2004,2005 Simtec Electronics <linux@simtec.co.uk>
  *                   http://www.simtec.co.uk/products/SWLINUX/
  *
  * 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.
  *
- * S3C2410 clock register definitions
+ * S3C2410 NAND register definitions
  *
  *  Changelog:
  *    18-Aug-2004    BJD     Copied file from 2.4 and updated
+ *    01-May-2005    BJD     Added definitions for s3c2440 controller
 */
 
 #ifndef __ASM_ARM_REGS_NAND
 #define S3C2410_NFSTAT  S3C2410_NFREG(0x10)
 #define S3C2410_NFECC   S3C2410_NFREG(0x14)
 
+#define S3C2440_NFCONT   S3C2410_NFREG(0x04)
+#define S3C2440_NFCMD    S3C2410_NFREG(0x08)
+#define S3C2440_NFADDR   S3C2410_NFREG(0x0C)
+#define S3C2440_NFDATA   S3C2410_NFREG(0x10)
+#define S3C2440_NFECCD0  S3C2410_NFREG(0x14)
+#define S3C2440_NFECCD1  S3C2410_NFREG(0x18)
+#define S3C2440_NFECCD   S3C2410_NFREG(0x1C)
+#define S3C2440_NFSTAT   S3C2410_NFREG(0x20)
+#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24)
+#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28)
+#define S3C2440_NFMECC0  S3C2410_NFREG(0x2C)
+#define S3C2440_NFMECC1  S3C2410_NFREG(0x30)
+#define S3C2440_NFSECC   S3C2410_NFREG(0x34)
+#define S3C2440_NFSBLK   S3C2410_NFREG(0x38)
+#define S3C2440_NFEBLK   S3C2410_NFREG(0x3C)
+
 #define S3C2410_NFCONF_EN          (1<<15)
 #define S3C2410_NFCONF_512BYTE     (1<<14)
 #define S3C2410_NFCONF_4STEP       (1<<13)
 
 #define S3C2410_NFSTAT_BUSY        (1<<0)
 
-/* think ECC can only be 8bit read? */
+#define S3C2440_NFCONF_BUSWIDTH_8      (0<<0)
+#define S3C2440_NFCONF_BUSWIDTH_16     (1<<0)
+#define S3C2440_NFCONF_ADVFLASH                (1<<3)
+#define S3C2440_NFCONF_TACLS(x)                ((x)<<12)
+#define S3C2440_NFCONF_TWRPH0(x)       ((x)<<8)
+#define S3C2440_NFCONF_TWRPH1(x)       ((x)<<4)
+
+#define S3C2440_NFCONT_LOCKTIGHT       (1<<13)
+#define S3C2440_NFCONT_SOFTLOCK                (1<<12)
+#define S3C2440_NFCONT_ILLEGALACC_EN   (1<<10)
+#define S3C2440_NFCONT_RNBINT_EN       (1<<9)
+#define S3C2440_NFCONT_RN_FALLING      (1<<8)
+#define S3C2440_NFCONT_SPARE_ECCLOCK   (1<<6)
+#define S3C2440_NFCONT_MAIN_ECCLOCK    (1<<5)
+#define S3C2440_NFCONT_INITECC         (1<<4)
+#define S3C2440_NFCONT_nFCE            (1<<1)
+#define S3C2440_NFCONT_ENABLE          (1<<0)
+
+#define S3C2440_NFSTAT_READY           (1<<0)
+#define S3C2440_NFSTAT_nCE             (1<<1)
+#define S3C2440_NFSTAT_RnB_CHANGE      (1<<2)
+#define S3C2440_NFSTAT_ILLEGAL_ACCESS  (1<<3)
 
 #endif /* __ASM_ARM_REGS_NAND */
 
index cbceacbe5afadae6e8ee0b5ce8b7e993e56a9eaf..a1696ba238d3aad1c891f194ac93d8c0b73c1362 100644 (file)
@@ -38,9 +38,9 @@ typedef struct user_fp elf_fpregset_t;
  */
 #define ELF_CLASS      ELFCLASS32
 #ifdef __ARMEB__
-#define ELF_DATA       ELFDATA2MSB;
+#define ELF_DATA       ELFDATA2MSB
 #else
-#define ELF_DATA       ELFDATA2LSB;
+#define ELF_DATA       ELFDATA2LSB
 #endif
 #define ELF_ARCH       EM_ARM
 
index 4ca3a8e9348f53becec9d7969d8c73d0f64a3d3a..019c45d7573053a9af19088f2df4af8cb4c5e95a 100644 (file)
@@ -114,19 +114,8 @@ extern void __cpu_copy_user_page(void *to, const void *from,
                                 unsigned long user);
 #endif
 
-#define clear_user_page(addr,vaddr,pg)                 \
-       do {                                            \
-               preempt_disable();                      \
-               __cpu_clear_user_page(addr, vaddr);     \
-               preempt_enable();                       \
-       } while (0)
-
-#define copy_user_page(to,from,vaddr,pg)               \
-       do {                                            \
-               preempt_disable();                      \
-               __cpu_copy_user_page(to, from, vaddr);  \
-               preempt_enable();                       \
-       } while (0)
+#define clear_user_page(addr,vaddr,pg)  __cpu_clear_user_page(addr, vaddr)
+#define copy_user_page(to,from,vaddr,pg) __cpu_copy_user_page(to, from, vaddr)
 
 #define clear_page(page)       memzero((void *)(page), PAGE_SIZE)
 extern void copy_page(void *to, const void *from);
@@ -171,6 +160,9 @@ typedef unsigned long pgprot_t;
 
 #endif /* STRICT_MM_TYPECHECKS */
 
+/* the upper-most page table pointer */
+extern pmd_t *top_pmd;
+
 /* Pure 2^n version of get_order */
 static inline int get_order(unsigned long size)
 {
index 4a9845997a75b861dce954441f57c1c8dbc09e7c..7d4118e090542222ec87020f9840e21f121b43ec 100644 (file)
@@ -23,8 +23,6 @@
 #include <asm/procinfo.h>
 #include <asm/types.h>
 
-#define KERNEL_STACK_SIZE      PAGE_SIZE
-
 union debug_insn {
        u32     arm;
        u16     thumb;
@@ -87,8 +85,9 @@ unsigned long get_wchan(struct task_struct *p);
  */
 extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
-#define KSTK_EIP(tsk)  (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019])
-#define KSTK_ESP(tsk)  (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017])
+#define KSTK_REGS(tsk) (((struct pt_regs *)(THREAD_START_SP + (unsigned long)(tsk)->thread_info)) - 1)
+#define KSTK_EIP(tsk)  KSTK_REGS(tsk)->ARM_pc
+#define KSTK_ESP(tsk)  KSTK_REGS(tsk)->ARM_sp
 
 /*
  * Prefetching support - only ARMv5.
index b860dc3c5dc71ca994363246a0739f759a48a720..46e69ae395af53a9d2c7db10be7479ec12836678 100644 (file)
@@ -117,20 +117,7 @@ typedef unsigned long sigset_t;
 #define SA_IRQNOMASK           0x08000000
 #endif
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void __signalfn_t(int);
-typedef __signalfn_t __user *__sighandler_t;
-
-typedef void __restorefn_t(void);
-typedef __restorefn_t __user *__sigrestore_t;
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index a61618fb433cbe9b12bfa7d83aec0321997c33a7..66c585c50cf910c5928739272ee9057f3432fa5c 100644 (file)
 
 #include <asm/fpstate.h>
 
+#define THREAD_SIZE_ORDER      1
+#define THREAD_SIZE            8192
+#define THREAD_START_SP                (THREAD_SIZE - 8)
+
 #ifndef __ASSEMBLY__
 
 struct task_struct;
@@ -77,8 +81,6 @@ struct thread_info {
 #define init_thread_info       (init_thread_union.thread_info)
 #define init_stack             (init_thread_union.stack)
 
-#define THREAD_SIZE            8192
-
 /*
  * how to get the thread information struct from C
  */
index 8b149474db2488092635c23eeb8498a1701ef399..5a47fdb3015da78a8f851acfb5e3fb2777350f69 100644 (file)
@@ -36,7 +36,7 @@ typedef struct { void *null; } elf_fpregset_t;
  * These are used to set parameters in the core dumps.
  */
 #define ELF_CLASS      ELFCLASS32
-#define ELF_DATA       ELFDATA2LSB;
+#define ELF_DATA       ELFDATA2LSB
 #define ELF_ARCH       EM_ARM
 
 #define USE_ELF_CORE_DUMP
index a1aacefa6562cbc9d035dbb01e36177fa3ef3bb7..37ad25355591f57bdbc3fb3dbc3795c2a452b818 100644 (file)
@@ -117,16 +117,7 @@ typedef unsigned long sigset_t;
 #define SA_IRQNOMASK           0x08000000
 #endif
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
@@ -175,9 +166,6 @@ typedef struct sigaltstack {
 #include <asm/sigcontext.h>
 
 #define sigmask(sig)   (1UL << ((sig) - 1))
-//FIXME!!!
-//#define HAVE_ARCH_GET_SIGNAL_TO_DELIVER
-
 #endif
 
 
index 2330769ba55dc758ba2230f0179fc78856acb8e6..dfe039593a78d067e9478826a2fac0876b4d0d27 100644 (file)
@@ -108,16 +108,7 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index c930bb176875741e134a5e55a2c42ca24804d5ab..d407bde57ecaaf6f56e812731bf3c7072d55fd5b 100644 (file)
@@ -107,16 +107,7 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index 976ac29598b78d0b2c0c90516480e93434d8f506..195ccdc069e6c229dc22024a9d96d0b790f07735 100644 (file)
@@ -8,6 +8,8 @@ extern char _data[], _sdata[], _edata[];
 extern char __bss_start[], __bss_stop[];
 extern char __init_begin[], __init_end[];
 extern char _sinittext[], _einittext[];
+extern char _sextratext[] __attribute__((weak));
+extern char _eextratext[] __attribute__((weak));
 extern char _end[];
 
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
diff --git a/include/asm-generic/signal.h b/include/asm-generic/signal.h
new file mode 100644 (file)
index 0000000..9418d6e
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef SIG_BLOCK
+#define SIG_BLOCK          0   /* for blocking signals */
+#endif
+#ifndef SIG_UNBLOCK
+#define SIG_UNBLOCK        1   /* for unblocking signals */
+#endif
+#ifndef SIG_SETMASK
+#define SIG_SETMASK        2   /* for setting the signal mask */
+#endif
+
+#ifndef __ASSEMBLY__
+typedef void __signalfn_t(int);
+typedef __signalfn_t __user *__sighandler_t;
+
+typedef void __restorefn_t(void);
+typedef __restorefn_t __user *__sigrestore_t;
+
+#define SIG_DFL        ((__force __sighandler_t)0)     /* default signal handling */
+#define SIG_IGN        ((__force __sighandler_t)1)     /* ignore signal */
+#define SIG_ERR        ((__force __sighandler_t)-1)    /* error return from signal */
+#endif
index 82431edeb2a108a83df9a44a768b2d3f33471385..1ec8a3427120876f6ef7d998b72798a37c0cc53a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
+#ifndef _ASM_H8300_KMAP_TYPES_H
+#define _ASM_H8300_KMAP_TYPES_H
 
 enum km_type {
        KM_BOUNCE_READ,
@@ -13,6 +13,8 @@ enum km_type {
        KM_PTE1,
        KM_IRQ0,
        KM_IRQ1,
+       KM_SOFTIRQ0,
+       KM_SOFTIRQ1,
        KM_TYPE_NR
 };
 
index abe08856c84fdc86e58a495c37c42cb4d9eb5227..63f727a59850bfa64f3723d30d2dc7a324553ed6 100644 (file)
@@ -4,6 +4,7 @@
 #define PROT_READ      0x1             /* page can be read */
 #define PROT_WRITE     0x2             /* page can be written */
 #define PROT_EXEC      0x4             /* page can be executed */
+#define PROT_SEM       0x8             /* page may be used for atomic ops */
 #define PROT_NONE      0x0             /* page can not be accessed */
 #define PROT_GROWSDOWN 0x01000000      /* mprotect flag: extend change to start of growsdown vma */
 #define PROT_GROWSUP   0x02000000      /* mprotect flag: extend change to end of growsup vma */
@@ -19,6 +20,8 @@
 #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
 #define MAP_LOCKED     0x2000          /* pages are locked */
 #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 MS_ASYNC       1               /* sync memory asynchronously */
 #define MS_INVALIDATE  2               /* invalidate the caches */
index ac3e01bd639666856421be05cc41f35bcbce71d9..8eccdc1761635a71ff3802726694297647bebf76 100644 (file)
@@ -107,16 +107,7 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index a917ff50354f363b69b909099cfbdcca1fed20ab..b82f5f3ab887b4307fa2e248c2122bdfe8d32bfc 100644 (file)
@@ -21,4 +21,14 @@ int unmap_page_from_agp(struct page *page);
    worth it. Would need a page for it. */
 #define flush_agp_cache() asm volatile("wbinvd":::"memory")
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+
 #endif
index f4782284807a50c20bab727d6f547109b76cf5c9..79727afb94c955895fd42e0649f47912c1b67fe3 100644 (file)
@@ -257,7 +257,7 @@ static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
        return 0;
 }
 
-struct fd_routine_l {
+static struct fd_routine_l {
        int (*_request_dma)(unsigned int dmanr, const char * device_id);
        void (*_free_dma)(unsigned int dmanr);
        int (*_get_dma_residue)(unsigned int dummy);
index af3d8571c5c7c06a38967b1559d4a40ca07993e7..f4a6ebac02472ce335530ac44a0e922a2c16224a 100644 (file)
@@ -5,9 +5,7 @@
 #define FASTCALL(x)    x __attribute__((regparm(3)))
 #define fastcall       __attribute__((regparm(3)))
 
-#ifdef CONFIG_REGPARM
-# define prevent_tail_call(ret) __asm__ ("" : "=r" (ret) : "0" (ret))
-#endif
+#define prevent_tail_call(ret) __asm__ ("" : "=r" (ret) : "0" (ret))
 
 #ifdef CONFIG_X86_ALIGNMENT_16
 #define __ALIGN .align 16,0x90
index 1b46fd3f2ae3156447ee7b74b5b2d827bafc9882..c6044488e9e6085a971c7a59640a56adefe22d7b 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __ASM_MACH_IPI_H
 #define __ASM_MACH_IPI_H
 
-inline void send_IPI_mask_sequence(cpumask_t, int vector);
+void send_IPI_mask_sequence(cpumask_t, int vector);
 
 static inline void send_IPI_mask(cpumask_t mask, int vector)
 {
index 508865e26308e7006ec11219391cb4b50c082a14..eb7f2b4234aa94e0385fc8dc8a5344fa00f14d08 100644 (file)
@@ -52,8 +52,8 @@ struct mod_arch_specific
 #define MODULE_PROC_FAMILY "CYRIXIII "
 #elif defined CONFIG_MVIAC3_2
 #define MODULE_PROC_FAMILY "VIAC3-2 "
-#elif CONFIG_MGEODE
-#define MODULE_PROC_FAMILY "GEODE "
+#elif CONFIG_MGEODEGX1
+#define MODULE_PROC_FAMILY "GEODEGX1 "
 #else
 #error unknown processor family
 #endif
index 0f082bd1c4557ed1049d596b41e8062e7dfe51d8..cbb47d34aa31402f1f102183635fc5b31eff66c8 100644 (file)
@@ -110,20 +110,7 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void __signalfn_t(int);
-typedef __signalfn_t __user *__sighandler_t;
-
-typedef void __restorefn_t(void);
-typedef __restorefn_t __user *__sigrestore_t;
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index 40c54f69780e66ccd417f736816736a56851dce4..c347098498397e67c1bf66453806ef3f7c811037 100644 (file)
@@ -53,6 +53,7 @@ extern struct init_timer_opts timer_cyclone_init;
 
 extern unsigned long calibrate_tsc(void);
 extern void init_cpu_khz(void);
+extern int recalibrate_cpu_khz(void);
 #ifdef CONFIG_HPET_TIMER
 extern struct init_timer_opts timer_hpet_init;
 extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr);
index d1316f1e6ee18f464926ba1de462f4cb6f7a2e4d..4e517f0e6afa34e81e9aecdeee51bf0eaec2b967 100644 (file)
 #define flush_agp_mappings()           /* nothing */
 #define flush_agp_cache()              mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+
 #endif /* _ASM_IA64_AGP_H */
diff --git a/include/asm-ia64/ioctl32.h b/include/asm-ia64/ioctl32.h
deleted file mode 100644 (file)
index d0d227f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <linux/ioctl32.h>
index ed5416c5b1ac6c63ec66aa173508178da7d3ece7..7f3333dd00e44b3ed4e8296728c509e23f4a3922 100644 (file)
@@ -177,6 +177,10 @@ typedef union {
 
 extern long perfmonctl(int fd, int cmd, void *arg, int narg);
 
+typedef struct {
+       void (*handler)(int irq, void *arg, struct pt_regs *regs);
+} pfm_intr_handler_desc_t;
+
 extern void pfm_save_regs (struct task_struct *);
 extern void pfm_load_regs (struct task_struct *);
 
@@ -187,6 +191,10 @@ extern void pfm_syst_wide_update_task(struct task_struct *, unsigned long info,
 extern void pfm_inherit(struct task_struct *task, struct pt_regs *regs);
 extern void pfm_init_percpu(void);
 extern void pfm_handle_work(void);
+extern int  pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *h);
+extern int  pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *h);
+
+
 
 /*
  * Reset PMD register flags
index ea121a002309176cd50055c6fcd497be1d1b2d94..fcc9c3344ab40f3ebd3891eb273fd1898f9e3fdc 100644 (file)
@@ -8,7 +8,7 @@
  * This hopefully works with any (fixed) IA-64 page-size, as defined
  * in <asm/page.h>.
  *
- * Copyright (C) 1998-2004 Hewlett-Packard Co
+ * Copyright (C) 1998-2005 Hewlett-Packard Co
  *     David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -551,7 +551,11 @@ do {                                                                                       \
 
 /* These tell get_user_pages() that the first gate page is accessible from user-level.  */
 #define FIXADDR_USER_START     GATE_ADDR
-#define FIXADDR_USER_END       (GATE_ADDR + 2*PERCPU_PAGE_SIZE)
+#ifdef HAVE_BUGGY_SEGREL
+# define FIXADDR_USER_END      (GATE_ADDR + 2*PAGE_SIZE)
+#else
+# define FIXADDR_USER_END      (GATE_ADDR + 2*PERCPU_PAGE_SIZE)
+#endif
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
index 9e1ba8b7fb68ada212e21dd89ce3606948ddc274..91bbd1f2246140121bbaec497101790c6dc278cf 100644 (file)
@@ -403,7 +403,10 @@ extern void ia64_setreg_unknown_kr (void);
  * task_struct at this point.
  */
 
-/* Return TRUE if task T owns the fph partition of the CPU we're running on. */
+/*
+ * Return TRUE if task T owns the fph partition of the CPU we're running on.
+ * Must be called from code that has preemption disabled.
+ */
 #define ia64_is_local_fpu_owner(t)                                                             \
 ({                                                                                             \
        struct task_struct *__ia64_islfo_task = (t);                                            \
@@ -411,7 +414,10 @@ extern void ia64_setreg_unknown_kr (void);
         && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER));        \
 })
 
-/* Mark task T as owning the fph partition of the CPU we're running on. */
+/*
+ * Mark task T as owning the fph partition of the CPU we're running on.
+ * Must be called from code that has preemption disabled.
+ */
 #define ia64_set_local_fpu_owner(t) do {                                               \
        struct task_struct *__ia64_slfo_task = (t);                                     \
        __ia64_slfo_task->thread.last_fph_cpu = smp_processor_id();                     \
index 85a577ae91467126092cdde23875114c60104d06..608168d713d374293847753114173622ff0853c1 100644 (file)
 
 #endif /* __KERNEL__ */
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 # ifndef __ASSEMBLY__
 
 /* Avoid too many header ordering problems.  */
 struct siginfo;
 
-/* Type of a signal handler.  */
-typedef void __user (*__sighandler_t)(int);
-
 typedef struct sigaltstack {
        void __user *ss_sp;
        int ss_flags;
index 960d626ee589fa45a28d6ba0df79ba7837d84065..1bfdfb4d7b0110224b17f51a429f7d880c32c7a6 100644 (file)
  */
 #define CAC_BASE               (CACHED   | AS_CAC_SPACE)
 #define AMO_BASE               (UNCACHED | AS_AMO_SPACE)
+#define AMO_PHYS_BASE          (UNCACHED_PHYS | AS_AMO_SPACE)
 #define GET_BASE               (CACHED   | AS_GET_SPACE)
 
 /*
 #define PHYS_TO_DMA(x)          ( (((u64)(x) & NASID_MASK) >> 2) | NODE_OFFSET(x))
 
 
+/*
+ * Macros to test for address type.
+ */
+#define IS_AMO_ADDRESS(x)      (((u64)(x) & (REGION_BITS | AS_MASK)) == AMO_BASE)
+#define IS_AMO_PHYS_ADDRESS(x) (((u64)(x) & (REGION_BITS | AS_MASK)) == AMO_PHYS_BASE)
+
+
 /*
  * The following definitions pertain to the IO special address
  * space.  They define the location of the big and little windows
index 7c349f07916a1bd6a55db4f2833ece12c63f22b3..635fdce854a84b89129a9b292ac3b43392ced642 100644 (file)
@@ -5,7 +5,7 @@
  *
  * SGI specific setup.
  *
- * Copyright (C) 1995-1997,1999,2001-2004 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 1995-1997,1999,2001-2005 Silicon Graphics, Inc.  All rights reserved.
  * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _ASM_IA64_SN_ARCH_H
@@ -47,6 +47,21 @@ DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
 #define MAX_COMPACT_NODES      2048
 #define CPUS_PER_NODE          4
 
+
+/*
+ * Compact node ID to nasid mappings kept in the per-cpu data areas of each
+ * cpu.
+ */
+DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]);
+#define sn_cnodeid_to_nasid    (&__get_cpu_var(__sn_cnodeid_to_nasid[0]))
+
+
+
+extern u8 sn_partition_id;
+extern u8 sn_system_size;
+extern u8 sn_sharing_domain_size;
+extern u8 sn_region_size;
+
 extern void sn_flush_all_caches(long addr, long bytes);
 
 #endif /* _ASM_IA64_SN_ARCH_H */
diff --git a/include/asm-ia64/sn/fetchop.h b/include/asm-ia64/sn/fetchop.h
deleted file mode 100644 (file)
index 5f4ad8f..0000000
+++ /dev/null
@@ -1,85 +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) 2001-2004 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_FETCHOP_H
-#define _ASM_IA64_SN_FETCHOP_H
-
-#include <linux/config.h>
-
-#define FETCHOP_BASENAME       "sgi_fetchop"
-#define FETCHOP_FULLNAME       "/dev/sgi_fetchop"
-
-
-
-#define FETCHOP_VAR_SIZE 64 /* 64 byte per fetchop variable */
-
-#define FETCHOP_LOAD           0
-#define FETCHOP_INCREMENT      8
-#define FETCHOP_DECREMENT      16
-#define FETCHOP_CLEAR          24
-
-#define FETCHOP_STORE          0
-#define FETCHOP_AND            24
-#define FETCHOP_OR             32
-
-#define FETCHOP_CLEAR_CACHE    56
-
-#define FETCHOP_LOAD_OP(addr, op) ( \
-         *(volatile long *)((char*) (addr) + (op)))
-
-#define FETCHOP_STORE_OP(addr, op, x) ( \
-         *(volatile long *)((char*) (addr) + (op)) = (long) (x))
-
-#ifdef __KERNEL__
-
-/*
- * Convert a region 6 (kaddr) address to the address of the fetchop variable
- */
-#define FETCHOP_KADDR_TO_MSPEC_ADDR(kaddr)     TO_MSPEC(kaddr)
-
-
-/*
- * Each Atomic Memory Operation (AMO formerly known as fetchop)
- * variable is 64 bytes long.  The first 8 bytes are used.  The
- * remaining 56 bytes are unaddressable due to the operation taking
- * that portion of the address.
- * 
- * NOTE: The AMO_t _MUST_ be placed in either the first or second half
- * of the cache line.  The cache line _MUST NOT_ be used for anything
- * other than additional AMO_t entries.  This is because there are two
- * addresses which reference the same physical cache line.  One will
- * be a cached entry with the memory type bits all set.  This address
- * may be loaded into processor cache.  The AMO_t will be referenced
- * uncached via the memory special memory type.  If any portion of the
- * cached cache-line is modified, when that line is flushed, it will
- * overwrite the uncached value in physical memory and lead to
- * inconsistency.
- */
-typedef struct {
-        u64 variable;
-        u64 unused[7];
-} AMO_t;
-
-
-/*
- * The following APIs are externalized to the kernel to allocate/free pages of
- * fetchop variables.
- *     fetchop_kalloc_page     - Allocate/initialize 1 fetchop page on the
- *                               specified cnode. 
- *     fetchop_kfree_page      - Free a previously allocated fetchop page
- */
-
-unsigned long fetchop_kalloc_page(int nid);
-void fetchop_kfree_page(unsigned long maddr);
-
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_IA64_SN_FETCHOP_H */
-
index d5dbd55e44b5f9d039c9e493969160793861e026..08050d37b662563038abfb9b7cc9e93f77f83abc 100644 (file)
@@ -29,8 +29,9 @@
 #define L1_BRICKTYPE_CHI_CG     0x76            /* v */
 #define L1_BRICKTYPE_X          0x78            /* x */
 #define L1_BRICKTYPE_X2         0x79            /* y */
-#define L1_BRICKTYPE_SA                0x5e            /* ^ */ /* TIO bringup brick */
+#define L1_BRICKTYPE_SA                0x5e            /* ^ */
 #define L1_BRICKTYPE_PA                0x6a            /* j */
 #define L1_BRICKTYPE_IA                0x6b            /* k */
+#define L1_BRICKTYPE_ATHENA    0x2b            /* + */
 
 #endif /* _ASM_IA64_SN_L1_H */
index 13cc1002b29493fa05a4adf871016841b691b62e..7138b1eafd6b46d48a5f83f10fc7606eb1885ef7 100644 (file)
@@ -13,7 +13,6 @@
 #include <asm/irq.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/intr.h>
-#include <asm/sn/pda.h>
 #include <asm/sn/bte.h>
 
 /*
@@ -67,20 +66,18 @@ typedef struct nodepda_s nodepda_t;
  * The next set of definitions provides this.
  * Routines are expected to use 
  *
- *     nodepda                 -> to access node PDA for the node on which code is running
- *     subnodepda              -> to access subnode PDA for the subnode on which code is running
- *
- *     NODEPDA(cnode)          -> to access node PDA for cnodeid 
- *     SUBNODEPDA(cnode,sn)    -> to access subnode PDA for cnodeid/subnode
+ *     sn_nodepda   - to access node PDA for the node on which code is running
+ *     NODEPDA(cnodeid)   - to access node PDA for cnodeid
  */
 
-#define        nodepda         pda->p_nodepda          /* Ptr to this node's PDA */
-#define        NODEPDA(cnode)          (nodepda->pernode_pdaindr[cnode])
+DECLARE_PER_CPU(struct nodepda_s *, __sn_nodepda);
+#define sn_nodepda             (__get_cpu_var(__sn_nodepda))
+#define        NODEPDA(cnodeid)        (sn_nodepda->pernode_pdaindr[cnodeid])
 
 /*
  * Check if given a compact node id the corresponding node has all the
  * cpus disabled. 
  */
-#define is_headless_node(cnode)                (nr_cpus_node(cnode) == 0)
+#define is_headless_node(cnodeid)      (nr_cpus_node(cnodeid) == 0)
 
 #endif /* _ASM_IA64_SN_NODEPDA_H */
index cd19f17bf91a6b3225f381fdf087322ee54f7204..ea5590c76ca48eafc3505ced25ef048d1d8d1b0e 100644 (file)
 
 typedef struct pda_s {
 
-       /* Having a pointer in the begining of PDA tends to increase
-        * the chance of having this pointer in cache. (Yes something
-        * else gets pushed out). Doing this reduces the number of memory
-        * access to all nodepda variables to be one
-        */
-       struct nodepda_s *p_nodepda;            /* Pointer to Per node PDA */
-       struct subnodepda_s *p_subnodepda;      /* Pointer to CPU  subnode PDA */
-
        /*
         * Support for SN LEDs
         */
@@ -49,7 +41,6 @@ typedef struct pda_s {
 
        unsigned long   sn_soft_irr[4];
        unsigned long   sn_in_service_ivecs[4];
-       short           cnodeid_to_nasid_table[MAX_NUMNODES];
        int             sn_lb_int_war_ticks;
        int             sn_last_irq;
        int             sn_first_irq;
index 2f885088e095695000f4eb03e18d24a40e9cf1a9..323fa0cd8d83d671d04fb51977dd9963b18784de 100644 (file)
 #define SH_EVENT_OCCURRED_RTC3_INT_SHFT          26
 #define SH_EVENT_OCCURRED_RTC3_INT_MASK          0x0000000004000000
 
+/* ==================================================================== */
+/*                       Register "SH_IPI_ACCESS"                       */
+/*                 CPU interrupt Access Permission Bits                 */
+/* ==================================================================== */
+
+#define SH1_IPI_ACCESS                           0x0000000110060480
+#define SH2_IPI_ACCESS0                          0x0000000010060c00
+#define SH2_IPI_ACCESS1                          0x0000000010060c80
+#define SH2_IPI_ACCESS2                          0x0000000010060d00
+#define SH2_IPI_ACCESS3                          0x0000000010060d80
+
 /* ==================================================================== */
 /*                        Register "SH_INT_CMPB"                        */
 /*                  RTC Compare Value for Processor B                   */
 #define SH_INT_CMPD_REAL_TIME_CMPD_SHFT          0
 #define SH_INT_CMPD_REAL_TIME_CMPD_MASK          0x007fffffffffffff
 
+/* ==================================================================== */
+/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC0"                 */
+/*                      privilege vector for acc=0                      */
+/* ==================================================================== */
+
+#define SH1_MD_DQLP_MMR_DIR_PRIVEC0              0x0000000100030300
+
+/* ==================================================================== */
+/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC0"                 */
+/*                      privilege vector for acc=0                      */
+/* ==================================================================== */
+
+#define SH1_MD_DQRP_MMR_DIR_PRIVEC0              0x0000000100050300
 
 /* ==================================================================== */
 /* Some MMRs are functionally identical (or close enough) on both SHUB1 */
index fbd880e6bb960ae4164972d9615deccff0e9ecee..831b72111fdcf0f3839b639a82a380e7859bfdcd 100644 (file)
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_SHUBIO_H
 #define _ASM_IA64_SN_SHUBIO_H
 
-#define HUB_WIDGET_ID_MAX 0xf
-#define IIO_NUM_ITTES   7
-#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
-
-#define    IIO_WID                   0x00400000    /* Crosstalk Widget Identification */
-                                                   /* This register is also accessible from
-                                                    * Crosstalk at address 0x0.  */
-#define    IIO_WSTAT                 0x00400008    /* Crosstalk Widget Status */
-#define    IIO_WCR                   0x00400020    /* Crosstalk Widget Control Register */
-#define    IIO_ILAPR                 0x00400100    /* IO Local Access Protection Register */
-#define    IIO_ILAPO                 0x00400108    /* IO Local Access Protection Override */
-#define    IIO_IOWA                  0x00400110    /* IO Outbound Widget Access */
-#define    IIO_IIWA                  0x00400118    /* IO Inbound Widget Access */
-#define    IIO_IIDEM                 0x00400120    /* IO Inbound Device Error Mask */
-#define    IIO_ILCSR                 0x00400128    /* IO LLP Control and Status Register */
-#define    IIO_ILLR                  0x00400130    /* IO LLP Log Register    */
-#define    IIO_IIDSR                 0x00400138    /* IO Interrupt Destination */
-
-#define    IIO_IGFX0                 0x00400140    /* IO Graphics Node-Widget Map 0 */
-#define    IIO_IGFX1                 0x00400148    /* IO Graphics Node-Widget Map 1 */
-
-#define    IIO_ISCR0                 0x00400150    /* IO Scratch Register 0 */
-#define    IIO_ISCR1                 0x00400158    /* IO Scratch Register 1 */
-
-#define    IIO_ITTE1                 0x00400160    /* IO Translation Table Entry 1 */
-#define    IIO_ITTE2                 0x00400168    /* IO Translation Table Entry 2 */
-#define    IIO_ITTE3                 0x00400170    /* IO Translation Table Entry 3 */
-#define    IIO_ITTE4                 0x00400178    /* IO Translation Table Entry 4 */
-#define    IIO_ITTE5                 0x00400180    /* IO Translation Table Entry 5 */
-#define    IIO_ITTE6                 0x00400188    /* IO Translation Table Entry 6 */
-#define    IIO_ITTE7                 0x00400190    /* IO Translation Table Entry 7 */
-
-#define    IIO_IPRB0                 0x00400198    /* IO PRB Entry 0         */
-#define    IIO_IPRB8                 0x004001A0    /* IO PRB Entry 8         */
-#define    IIO_IPRB9                 0x004001A8    /* IO PRB Entry 9         */
-#define    IIO_IPRBA                 0x004001B0    /* IO PRB Entry A         */
-#define    IIO_IPRBB                 0x004001B8    /* IO PRB Entry B         */
-#define    IIO_IPRBC                 0x004001C0    /* IO PRB Entry C         */
-#define    IIO_IPRBD                 0x004001C8    /* IO PRB Entry D         */
-#define    IIO_IPRBE                 0x004001D0    /* IO PRB Entry E         */
-#define    IIO_IPRBF                 0x004001D8    /* IO PRB Entry F         */
-
-#define    IIO_IXCC                  0x004001E0    /* IO Crosstalk Credit Count Timeout */
-#define    IIO_IMEM                  0x004001E8    /* IO Miscellaneous Error Mask */
-#define    IIO_IXTT                  0x004001F0    /* IO Crosstalk Timeout Threshold */
-#define    IIO_IECLR                 0x004001F8    /* IO Error Clear Register */
-#define    IIO_IBCR                  0x00400200    /* IO BTE Control Register */
-
-#define    IIO_IXSM                  0x00400208    /* IO Crosstalk Spurious Message */
-#define    IIO_IXSS                  0x00400210    /* IO Crosstalk Spurious Sideband */
-
-#define    IIO_ILCT                  0x00400218    /* IO LLP Channel Test    */
-
-#define    IIO_IIEPH1                0x00400220    /* IO Incoming Error Packet Header, Part 1 */
-#define    IIO_IIEPH2                0x00400228    /* IO Incoming Error Packet Header, Part 2 */
-
-
-#define    IIO_ISLAPR                0x00400230    /* IO SXB Local Access Protection Regster */
-#define    IIO_ISLAPO                0x00400238    /* IO SXB Local Access Protection Override */
-
-#define    IIO_IWI                   0x00400240    /* IO Wrapper Interrupt Register */
-#define    IIO_IWEL                  0x00400248    /* IO Wrapper Error Log Register */
-#define    IIO_IWC                   0x00400250    /* IO Wrapper Control Register */
-#define    IIO_IWS                   0x00400258    /* IO Wrapper Status Register */
-#define    IIO_IWEIM                 0x00400260    /* IO Wrapper Error Interrupt Masking Register */
-
-#define    IIO_IPCA                  0x00400300    /* IO PRB Counter Adjust */
-
-#define    IIO_IPRTE0_A              0x00400308    /* IO PIO Read Address Table Entry 0, Part A */
-#define    IIO_IPRTE1_A              0x00400310    /* IO PIO Read Address Table Entry 1, Part A */
-#define    IIO_IPRTE2_A              0x00400318    /* IO PIO Read Address Table Entry 2, Part A */
-#define    IIO_IPRTE3_A               0x00400320    /* IO PIO Read Address Table Entry 3, Part A */
-#define    IIO_IPRTE4_A               0x00400328    /* IO PIO Read Address Table Entry 4, Part A */
-#define    IIO_IPRTE5_A               0x00400330    /* IO PIO Read Address Table Entry 5, Part A */
-#define    IIO_IPRTE6_A               0x00400338    /* IO PIO Read Address Table Entry 6, Part A */
-#define    IIO_IPRTE7_A               0x00400340    /* IO PIO Read Address Table Entry 7, Part A */
-
-#define    IIO_IPRTE0_B              0x00400348    /* IO PIO Read Address Table Entry 0, Part B */
-#define    IIO_IPRTE1_B              0x00400350    /* IO PIO Read Address Table Entry 1, Part B */
-#define    IIO_IPRTE2_B              0x00400358    /* IO PIO Read Address Table Entry 2, Part B */
-#define    IIO_IPRTE3_B               0x00400360    /* IO PIO Read Address Table Entry 3, Part B */
-#define    IIO_IPRTE4_B               0x00400368    /* IO PIO Read Address Table Entry 4, Part B */
-#define    IIO_IPRTE5_B               0x00400370    /* IO PIO Read Address Table Entry 5, Part B */
-#define    IIO_IPRTE6_B               0x00400378    /* IO PIO Read Address Table Entry 6, Part B */
-#define    IIO_IPRTE7_B               0x00400380    /* IO PIO Read Address Table Entry 7, Part B */
-
-#define    IIO_IPDR                  0x00400388    /* IO PIO Deallocation Register */
-#define    IIO_ICDR                  0x00400390    /* IO CRB Entry Deallocation Register */
-#define    IIO_IFDR                  0x00400398    /* IO IOQ FIFO Depth Register */
-#define    IIO_IIAP                  0x004003A0    /* IO IIQ Arbitration Parameters */
-#define    IIO_ICMR                  0x004003A8    /* IO CRB Management Register */
-#define    IIO_ICCR                  0x004003B0    /* IO CRB Control Register */
-#define    IIO_ICTO                  0x004003B8    /* IO CRB Timeout         */
-#define    IIO_ICTP                  0x004003C0    /* IO CRB Timeout Prescalar */
-
-#define    IIO_ICRB0_A               0x00400400    /* IO CRB Entry 0_A       */
-#define    IIO_ICRB0_B               0x00400408    /* IO CRB Entry 0_B       */
-#define    IIO_ICRB0_C               0x00400410    /* IO CRB Entry 0_C       */
-#define    IIO_ICRB0_D               0x00400418    /* IO CRB Entry 0_D       */
-#define    IIO_ICRB0_E               0x00400420    /* IO CRB Entry 0_E       */
-
-#define    IIO_ICRB1_A               0x00400430    /* IO CRB Entry 1_A       */
-#define    IIO_ICRB1_B               0x00400438    /* IO CRB Entry 1_B       */
-#define    IIO_ICRB1_C               0x00400440    /* IO CRB Entry 1_C       */
-#define    IIO_ICRB1_D               0x00400448    /* IO CRB Entry 1_D       */
-#define    IIO_ICRB1_E               0x00400450    /* IO CRB Entry 1_E       */
-
-#define    IIO_ICRB2_A               0x00400460    /* IO CRB Entry 2_A       */
-#define    IIO_ICRB2_B               0x00400468    /* IO CRB Entry 2_B       */
-#define    IIO_ICRB2_C               0x00400470    /* IO CRB Entry 2_C       */
-#define    IIO_ICRB2_D               0x00400478    /* IO CRB Entry 2_D       */
-#define    IIO_ICRB2_E               0x00400480    /* IO CRB Entry 2_E       */
-
-#define    IIO_ICRB3_A               0x00400490    /* IO CRB Entry 3_A       */
-#define    IIO_ICRB3_B               0x00400498    /* IO CRB Entry 3_B       */
-#define    IIO_ICRB3_C               0x004004a0    /* IO CRB Entry 3_C       */
-#define    IIO_ICRB3_D               0x004004a8    /* IO CRB Entry 3_D       */
-#define    IIO_ICRB3_E               0x004004b0    /* IO CRB Entry 3_E       */
-
-#define    IIO_ICRB4_A               0x004004c0    /* IO CRB Entry 4_A       */
-#define    IIO_ICRB4_B               0x004004c8    /* IO CRB Entry 4_B       */
-#define    IIO_ICRB4_C               0x004004d0    /* IO CRB Entry 4_C       */
-#define    IIO_ICRB4_D               0x004004d8    /* IO CRB Entry 4_D       */
-#define    IIO_ICRB4_E               0x004004e0    /* IO CRB Entry 4_E       */
-
-#define    IIO_ICRB5_A               0x004004f0    /* IO CRB Entry 5_A       */
-#define    IIO_ICRB5_B               0x004004f8    /* IO CRB Entry 5_B       */
-#define    IIO_ICRB5_C               0x00400500    /* IO CRB Entry 5_C       */
-#define    IIO_ICRB5_D               0x00400508    /* IO CRB Entry 5_D       */
-#define    IIO_ICRB5_E               0x00400510    /* IO CRB Entry 5_E       */
-
-#define    IIO_ICRB6_A               0x00400520    /* IO CRB Entry 6_A       */
-#define    IIO_ICRB6_B               0x00400528    /* IO CRB Entry 6_B       */
-#define    IIO_ICRB6_C               0x00400530    /* IO CRB Entry 6_C       */
-#define    IIO_ICRB6_D               0x00400538    /* IO CRB Entry 6_D       */
-#define    IIO_ICRB6_E               0x00400540    /* IO CRB Entry 6_E       */
-
-#define    IIO_ICRB7_A               0x00400550    /* IO CRB Entry 7_A       */
-#define    IIO_ICRB7_B               0x00400558    /* IO CRB Entry 7_B       */
-#define    IIO_ICRB7_C               0x00400560    /* IO CRB Entry 7_C       */
-#define    IIO_ICRB7_D               0x00400568    /* IO CRB Entry 7_D       */
-#define    IIO_ICRB7_E               0x00400570    /* IO CRB Entry 7_E       */
-
-#define    IIO_ICRB8_A               0x00400580    /* IO CRB Entry 8_A       */
-#define    IIO_ICRB8_B               0x00400588    /* IO CRB Entry 8_B       */
-#define    IIO_ICRB8_C               0x00400590    /* IO CRB Entry 8_C       */
-#define    IIO_ICRB8_D               0x00400598    /* IO CRB Entry 8_D       */
-#define    IIO_ICRB8_E               0x004005a0    /* IO CRB Entry 8_E       */
-
-#define    IIO_ICRB9_A               0x004005b0    /* IO CRB Entry 9_A       */
-#define    IIO_ICRB9_B               0x004005b8    /* IO CRB Entry 9_B       */
-#define    IIO_ICRB9_C               0x004005c0    /* IO CRB Entry 9_C       */
-#define    IIO_ICRB9_D               0x004005c8    /* IO CRB Entry 9_D       */
-#define    IIO_ICRB9_E               0x004005d0    /* IO CRB Entry 9_E       */
-
-#define    IIO_ICRBA_A               0x004005e0    /* IO CRB Entry A_A       */
-#define    IIO_ICRBA_B               0x004005e8    /* IO CRB Entry A_B       */
-#define    IIO_ICRBA_C               0x004005f0    /* IO CRB Entry A_C       */
-#define    IIO_ICRBA_D               0x004005f8    /* IO CRB Entry A_D       */
-#define    IIO_ICRBA_E               0x00400600    /* IO CRB Entry A_E       */
-
-#define    IIO_ICRBB_A               0x00400610    /* IO CRB Entry B_A       */
-#define    IIO_ICRBB_B               0x00400618    /* IO CRB Entry B_B       */
-#define    IIO_ICRBB_C               0x00400620    /* IO CRB Entry B_C       */
-#define    IIO_ICRBB_D               0x00400628    /* IO CRB Entry B_D       */
-#define    IIO_ICRBB_E               0x00400630    /* IO CRB Entry B_E       */
-
-#define    IIO_ICRBC_A               0x00400640    /* IO CRB Entry C_A       */
-#define    IIO_ICRBC_B               0x00400648    /* IO CRB Entry C_B       */
-#define    IIO_ICRBC_C               0x00400650    /* IO CRB Entry C_C       */
-#define    IIO_ICRBC_D               0x00400658    /* IO CRB Entry C_D       */
-#define    IIO_ICRBC_E               0x00400660    /* IO CRB Entry C_E       */
-
-#define    IIO_ICRBD_A               0x00400670    /* IO CRB Entry D_A       */
-#define    IIO_ICRBD_B               0x00400678    /* IO CRB Entry D_B       */
-#define    IIO_ICRBD_C               0x00400680    /* IO CRB Entry D_C       */
-#define    IIO_ICRBD_D               0x00400688    /* IO CRB Entry D_D       */
-#define    IIO_ICRBD_E               0x00400690    /* IO CRB Entry D_E       */
-
-#define    IIO_ICRBE_A               0x004006a0    /* IO CRB Entry E_A       */
-#define    IIO_ICRBE_B               0x004006a8    /* IO CRB Entry E_B       */
-#define    IIO_ICRBE_C               0x004006b0    /* IO CRB Entry E_C       */
-#define    IIO_ICRBE_D               0x004006b8    /* IO CRB Entry E_D       */
-#define    IIO_ICRBE_E               0x004006c0    /* IO CRB Entry E_E       */
-
-#define    IIO_ICSML                 0x00400700    /* IO CRB Spurious Message Low */
-#define    IIO_ICSMM                 0x00400708    /* IO CRB Spurious Message Middle */
-#define    IIO_ICSMH                 0x00400710    /* IO CRB Spurious Message High */
-
-#define    IIO_IDBSS                 0x00400718    /* IO Debug Submenu Select */
-
-#define    IIO_IBLS0                 0x00410000    /* IO BTE Length Status 0 */
-#define    IIO_IBSA0                 0x00410008    /* IO BTE Source Address 0 */
-#define    IIO_IBDA0                 0x00410010    /* IO BTE Destination Address 0 */
-#define    IIO_IBCT0                 0x00410018    /* IO BTE Control Terminate 0 */
-#define    IIO_IBNA0                 0x00410020    /* IO BTE Notification Address 0 */
-#define    IIO_IBIA0                 0x00410028    /* IO BTE Interrupt Address 0 */
-#define    IIO_IBLS1                 0x00420000    /* IO BTE Length Status 1 */
-#define    IIO_IBSA1                 0x00420008    /* IO BTE Source Address 1 */
-#define    IIO_IBDA1                 0x00420010    /* IO BTE Destination Address 1 */
-#define    IIO_IBCT1                 0x00420018    /* IO BTE Control Terminate 1 */
-#define    IIO_IBNA1                 0x00420020    /* IO BTE Notification Address 1 */
-#define    IIO_IBIA1                 0x00420028    /* IO BTE Interrupt Address 1 */
-
-#define    IIO_IPCR                  0x00430000    /* IO Performance Control */
-#define    IIO_IPPR                  0x00430008    /* IO Performance Profiling */
-
-
-/************************************************************************
- *                                                                      *
+#define HUB_WIDGET_ID_MAX      0xf
+#define IIO_NUM_ITTES          7
+#define HUB_NUM_BIG_WINDOW     (IIO_NUM_ITTES - 1)
+
+#define                IIO_WID                 0x00400000      /* Crosstalk Widget Identification */
+                                                       /* This register is also accessible from
+                                                        * Crosstalk at address 0x0.  */
+#define                IIO_WSTAT               0x00400008      /* Crosstalk Widget Status */
+#define                IIO_WCR                 0x00400020      /* Crosstalk Widget Control Register */
+#define                IIO_ILAPR               0x00400100      /* IO Local Access Protection Register */
+#define                IIO_ILAPO               0x00400108      /* IO Local Access Protection Override */
+#define                IIO_IOWA                0x00400110      /* IO Outbound Widget Access */
+#define                IIO_IIWA                0x00400118      /* IO Inbound Widget Access */
+#define                IIO_IIDEM               0x00400120      /* IO Inbound Device Error Mask */
+#define                IIO_ILCSR               0x00400128      /* IO LLP Control and Status Register */
+#define                IIO_ILLR                0x00400130      /* IO LLP Log Register    */
+#define                IIO_IIDSR               0x00400138      /* IO Interrupt Destination */
+
+#define                IIO_IGFX0               0x00400140      /* IO Graphics Node-Widget Map 0 */
+#define                IIO_IGFX1               0x00400148      /* IO Graphics Node-Widget Map 1 */
+
+#define                IIO_ISCR0               0x00400150      /* IO Scratch Register 0 */
+#define                IIO_ISCR1               0x00400158      /* IO Scratch Register 1 */
+
+#define                IIO_ITTE1               0x00400160      /* IO Translation Table Entry 1 */
+#define                IIO_ITTE2               0x00400168      /* IO Translation Table Entry 2 */
+#define                IIO_ITTE3               0x00400170      /* IO Translation Table Entry 3 */
+#define                IIO_ITTE4               0x00400178      /* IO Translation Table Entry 4 */
+#define                IIO_ITTE5               0x00400180      /* IO Translation Table Entry 5 */
+#define                IIO_ITTE6               0x00400188      /* IO Translation Table Entry 6 */
+#define                IIO_ITTE7               0x00400190      /* IO Translation Table Entry 7 */
+
+#define                IIO_IPRB0               0x00400198      /* IO PRB Entry 0   */
+#define                IIO_IPRB8               0x004001A0      /* IO PRB Entry 8   */
+#define                IIO_IPRB9               0x004001A8      /* IO PRB Entry 9   */
+#define                IIO_IPRBA               0x004001B0      /* IO PRB Entry A   */
+#define                IIO_IPRBB               0x004001B8      /* IO PRB Entry B   */
+#define                IIO_IPRBC               0x004001C0      /* IO PRB Entry C   */
+#define                IIO_IPRBD               0x004001C8      /* IO PRB Entry D   */
+#define                IIO_IPRBE               0x004001D0      /* IO PRB Entry E   */
+#define                IIO_IPRBF               0x004001D8      /* IO PRB Entry F   */
+
+#define                IIO_IXCC                0x004001E0      /* IO Crosstalk Credit Count Timeout */
+#define                IIO_IMEM                0x004001E8      /* IO Miscellaneous Error Mask */
+#define                IIO_IXTT                0x004001F0      /* IO Crosstalk Timeout Threshold */
+#define                IIO_IECLR               0x004001F8      /* IO Error Clear Register */
+#define                IIO_IBCR                0x00400200      /* IO BTE Control Register */
+
+#define                IIO_IXSM                0x00400208      /* IO Crosstalk Spurious Message */
+#define                IIO_IXSS                0x00400210      /* IO Crosstalk Spurious Sideband */
+
+#define                IIO_ILCT                0x00400218      /* IO LLP Channel Test    */
+
+#define                IIO_IIEPH1              0x00400220      /* IO Incoming Error Packet Header, Part 1 */
+#define                IIO_IIEPH2              0x00400228      /* IO Incoming Error Packet Header, Part 2 */
+
+#define                IIO_ISLAPR              0x00400230      /* IO SXB Local Access Protection Regster */
+#define                IIO_ISLAPO              0x00400238      /* IO SXB Local Access Protection Override */
+
+#define                IIO_IWI                 0x00400240      /* IO Wrapper Interrupt Register */
+#define                IIO_IWEL                0x00400248      /* IO Wrapper Error Log Register */
+#define                IIO_IWC                 0x00400250      /* IO Wrapper Control Register */
+#define                IIO_IWS                 0x00400258      /* IO Wrapper Status Register */
+#define                IIO_IWEIM               0x00400260      /* IO Wrapper Error Interrupt Masking Register */
+
+#define                IIO_IPCA                0x00400300      /* IO PRB Counter Adjust */
+
+#define                IIO_IPRTE0_A            0x00400308      /* IO PIO Read Address Table Entry 0, Part A */
+#define                IIO_IPRTE1_A            0x00400310      /* IO PIO Read Address Table Entry 1, Part A */
+#define                IIO_IPRTE2_A            0x00400318      /* IO PIO Read Address Table Entry 2, Part A */
+#define                IIO_IPRTE3_A            0x00400320      /* IO PIO Read Address Table Entry 3, Part A */
+#define                IIO_IPRTE4_A            0x00400328      /* IO PIO Read Address Table Entry 4, Part A */
+#define                IIO_IPRTE5_A            0x00400330      /* IO PIO Read Address Table Entry 5, Part A */
+#define                IIO_IPRTE6_A            0x00400338      /* IO PIO Read Address Table Entry 6, Part A */
+#define                IIO_IPRTE7_A            0x00400340      /* IO PIO Read Address Table Entry 7, Part A */
+
+#define                IIO_IPRTE0_B            0x00400348      /* IO PIO Read Address Table Entry 0, Part B */
+#define                IIO_IPRTE1_B            0x00400350      /* IO PIO Read Address Table Entry 1, Part B */
+#define                IIO_IPRTE2_B            0x00400358      /* IO PIO Read Address Table Entry 2, Part B */
+#define                IIO_IPRTE3_B            0x00400360      /* IO PIO Read Address Table Entry 3, Part B */
+#define                IIO_IPRTE4_B            0x00400368      /* IO PIO Read Address Table Entry 4, Part B */
+#define                IIO_IPRTE5_B            0x00400370      /* IO PIO Read Address Table Entry 5, Part B */
+#define                IIO_IPRTE6_B            0x00400378      /* IO PIO Read Address Table Entry 6, Part B */
+#define                IIO_IPRTE7_B            0x00400380      /* IO PIO Read Address Table Entry 7, Part B */
+
+#define                IIO_IPDR                0x00400388      /* IO PIO Deallocation Register */
+#define                IIO_ICDR                0x00400390      /* IO CRB Entry Deallocation Register */
+#define                IIO_IFDR                0x00400398      /* IO IOQ FIFO Depth Register */
+#define                IIO_IIAP                0x004003A0      /* IO IIQ Arbitration Parameters */
+#define                IIO_ICMR                0x004003A8      /* IO CRB Management Register */
+#define                IIO_ICCR                0x004003B0      /* IO CRB Control Register */
+#define                IIO_ICTO                0x004003B8      /* IO CRB Timeout   */
+#define                IIO_ICTP                0x004003C0      /* IO CRB Timeout Prescalar */
+
+#define                IIO_ICRB0_A             0x00400400      /* IO CRB Entry 0_A */
+#define                IIO_ICRB0_B             0x00400408      /* IO CRB Entry 0_B */
+#define                IIO_ICRB0_C             0x00400410      /* IO CRB Entry 0_C */
+#define                IIO_ICRB0_D             0x00400418      /* IO CRB Entry 0_D */
+#define                IIO_ICRB0_E             0x00400420      /* IO CRB Entry 0_E */
+
+#define                IIO_ICRB1_A             0x00400430      /* IO CRB Entry 1_A */
+#define                IIO_ICRB1_B             0x00400438      /* IO CRB Entry 1_B */
+#define                IIO_ICRB1_C             0x00400440      /* IO CRB Entry 1_C */
+#define                IIO_ICRB1_D             0x00400448      /* IO CRB Entry 1_D */
+#define                IIO_ICRB1_E             0x00400450      /* IO CRB Entry 1_E */
+
+#define                IIO_ICRB2_A             0x00400460      /* IO CRB Entry 2_A */
+#define                IIO_ICRB2_B             0x00400468      /* IO CRB Entry 2_B */
+#define                IIO_ICRB2_C             0x00400470      /* IO CRB Entry 2_C */
+#define                IIO_ICRB2_D             0x00400478      /* IO CRB Entry 2_D */
+#define                IIO_ICRB2_E             0x00400480      /* IO CRB Entry 2_E */
+
+#define                IIO_ICRB3_A             0x00400490      /* IO CRB Entry 3_A */
+#define                IIO_ICRB3_B             0x00400498      /* IO CRB Entry 3_B */
+#define                IIO_ICRB3_C             0x004004a0      /* IO CRB Entry 3_C */
+#define                IIO_ICRB3_D             0x004004a8      /* IO CRB Entry 3_D */
+#define                IIO_ICRB3_E             0x004004b0      /* IO CRB Entry 3_E */
+
+#define                IIO_ICRB4_A             0x004004c0      /* IO CRB Entry 4_A */
+#define                IIO_ICRB4_B             0x004004c8      /* IO CRB Entry 4_B */
+#define                IIO_ICRB4_C             0x004004d0      /* IO CRB Entry 4_C */
+#define                IIO_ICRB4_D             0x004004d8      /* IO CRB Entry 4_D */
+#define                IIO_ICRB4_E             0x004004e0      /* IO CRB Entry 4_E */
+
+#define                IIO_ICRB5_A             0x004004f0      /* IO CRB Entry 5_A */
+#define                IIO_ICRB5_B             0x004004f8      /* IO CRB Entry 5_B */
+#define                IIO_ICRB5_C             0x00400500      /* IO CRB Entry 5_C */
+#define                IIO_ICRB5_D             0x00400508      /* IO CRB Entry 5_D */
+#define                IIO_ICRB5_E             0x00400510      /* IO CRB Entry 5_E */
+
+#define                IIO_ICRB6_A             0x00400520      /* IO CRB Entry 6_A */
+#define                IIO_ICRB6_B             0x00400528      /* IO CRB Entry 6_B */
+#define                IIO_ICRB6_C             0x00400530      /* IO CRB Entry 6_C */
+#define                IIO_ICRB6_D             0x00400538      /* IO CRB Entry 6_D */
+#define                IIO_ICRB6_E             0x00400540      /* IO CRB Entry 6_E */
+
+#define                IIO_ICRB7_A             0x00400550      /* IO CRB Entry 7_A */
+#define                IIO_ICRB7_B             0x00400558      /* IO CRB Entry 7_B */
+#define                IIO_ICRB7_C             0x00400560      /* IO CRB Entry 7_C */
+#define                IIO_ICRB7_D             0x00400568      /* IO CRB Entry 7_D */
+#define                IIO_ICRB7_E             0x00400570      /* IO CRB Entry 7_E */
+
+#define                IIO_ICRB8_A             0x00400580      /* IO CRB Entry 8_A */
+#define                IIO_ICRB8_B             0x00400588      /* IO CRB Entry 8_B */
+#define                IIO_ICRB8_C             0x00400590      /* IO CRB Entry 8_C */
+#define                IIO_ICRB8_D             0x00400598      /* IO CRB Entry 8_D */
+#define                IIO_ICRB8_E             0x004005a0      /* IO CRB Entry 8_E */
+
+#define                IIO_ICRB9_A             0x004005b0      /* IO CRB Entry 9_A */
+#define                IIO_ICRB9_B             0x004005b8      /* IO CRB Entry 9_B */
+#define                IIO_ICRB9_C             0x004005c0      /* IO CRB Entry 9_C */
+#define                IIO_ICRB9_D             0x004005c8      /* IO CRB Entry 9_D */
+#define                IIO_ICRB9_E             0x004005d0      /* IO CRB Entry 9_E */
+
+#define                IIO_ICRBA_A             0x004005e0      /* IO CRB Entry A_A */
+#define                IIO_ICRBA_B             0x004005e8      /* IO CRB Entry A_B */
+#define                IIO_ICRBA_C             0x004005f0      /* IO CRB Entry A_C */
+#define                IIO_ICRBA_D             0x004005f8      /* IO CRB Entry A_D */
+#define                IIO_ICRBA_E             0x00400600      /* IO CRB Entry A_E */
+
+#define                IIO_ICRBB_A             0x00400610      /* IO CRB Entry B_A */
+#define                IIO_ICRBB_B             0x00400618      /* IO CRB Entry B_B */
+#define                IIO_ICRBB_C             0x00400620      /* IO CRB Entry B_C */
+#define                IIO_ICRBB_D             0x00400628      /* IO CRB Entry B_D */
+#define                IIO_ICRBB_E             0x00400630      /* IO CRB Entry B_E */
+
+#define                IIO_ICRBC_A             0x00400640      /* IO CRB Entry C_A */
+#define                IIO_ICRBC_B             0x00400648      /* IO CRB Entry C_B */
+#define                IIO_ICRBC_C             0x00400650      /* IO CRB Entry C_C */
+#define                IIO_ICRBC_D             0x00400658      /* IO CRB Entry C_D */
+#define                IIO_ICRBC_E             0x00400660      /* IO CRB Entry C_E */
+
+#define                IIO_ICRBD_A             0x00400670      /* IO CRB Entry D_A */
+#define                IIO_ICRBD_B             0x00400678      /* IO CRB Entry D_B */
+#define                IIO_ICRBD_C             0x00400680      /* IO CRB Entry D_C */
+#define                IIO_ICRBD_D             0x00400688      /* IO CRB Entry D_D */
+#define                IIO_ICRBD_E             0x00400690      /* IO CRB Entry D_E */
+
+#define                IIO_ICRBE_A             0x004006a0      /* IO CRB Entry E_A */
+#define                IIO_ICRBE_B             0x004006a8      /* IO CRB Entry E_B */
+#define                IIO_ICRBE_C             0x004006b0      /* IO CRB Entry E_C */
+#define                IIO_ICRBE_D             0x004006b8      /* IO CRB Entry E_D */
+#define                IIO_ICRBE_E             0x004006c0      /* IO CRB Entry E_E */
+
+#define                IIO_ICSML               0x00400700      /* IO CRB Spurious Message Low */
+#define                IIO_ICSMM               0x00400708      /* IO CRB Spurious Message Middle */
+#define                IIO_ICSMH               0x00400710      /* IO CRB Spurious Message High */
+
+#define                IIO_IDBSS               0x00400718      /* IO Debug Submenu Select */
+
+#define                IIO_IBLS0               0x00410000      /* IO BTE Length Status 0 */
+#define                IIO_IBSA0               0x00410008      /* IO BTE Source Address 0 */
+#define                IIO_IBDA0               0x00410010      /* IO BTE Destination Address 0 */
+#define                IIO_IBCT0               0x00410018      /* IO BTE Control Terminate 0 */
+#define                IIO_IBNA0               0x00410020      /* IO BTE Notification Address 0 */
+#define                IIO_IBIA0               0x00410028      /* IO BTE Interrupt Address 0 */
+#define                IIO_IBLS1               0x00420000      /* IO BTE Length Status 1 */
+#define                IIO_IBSA1               0x00420008      /* IO BTE Source Address 1 */
+#define                IIO_IBDA1               0x00420010      /* IO BTE Destination Address 1 */
+#define                IIO_IBCT1               0x00420018      /* IO BTE Control Terminate 1 */
+#define                IIO_IBNA1               0x00420020      /* IO BTE Notification Address 1 */
+#define                IIO_IBIA1               0x00420028      /* IO BTE Interrupt Address 1 */
+
+#define                IIO_IPCR                0x00430000      /* IO Performance Control */
+#define                IIO_IPPR                0x00430008      /* IO Performance Profiling */
+
+/************************************************************************
+ *                                                                     *
  * Description:  This register echoes some information from the         *
  * LB_REV_ID register. It is available through Crosstalk as described   *
  * above. The REV_NUM and MFG_NUM fields receive their values from      *
  * the REVISION and MANUFACTURER fields in the LB_REV_ID register.      *
  * The PART_NUM field's value is the Crosstalk device ID number that    *
  * Steve Miller assigned to the SHub chip.                              *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_wid_u {
-       uint64_t        ii_wid_regval;
-       struct  {
-               uint64_t        w_rsvd_1                  :      1;
-               uint64_t        w_mfg_num                 :     11;
-               uint64_t        w_part_num                :     16;
-               uint64_t        w_rev_num                 :      4;
-               uint64_t        w_rsvd                    :     32;
+       uint64_t ii_wid_regval;
+       struct {
+               uint64_t w_rsvd_1:1;
+               uint64_t w_mfg_num:11;
+               uint64_t w_part_num:16;
+               uint64_t w_rev_num:4;
+               uint64_t w_rsvd:32;
        } ii_wid_fld_s;
 } ii_wid_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  The fields in this register are set upon detection of an error      *
  * and cleared by various mechanisms, as explained in the               *
  * description.                                                         *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_wstat_u {
-       uint64_t        ii_wstat_regval;
-       struct  {
-               uint64_t        w_pending                 :      4;
-               uint64_t        w_xt_crd_to               :      1;
-               uint64_t        w_xt_tail_to              :      1;
-               uint64_t        w_rsvd_3                  :      3;
-               uint64_t       w_tx_mx_rty               :      1;
-               uint64_t        w_rsvd_2                  :      6;
-               uint64_t        w_llp_tx_cnt              :      8;
-               uint64_t        w_rsvd_1                  :      8;
-               uint64_t        w_crazy                   :      1;
-               uint64_t        w_rsvd                    :     31;
+       uint64_t ii_wstat_regval;
+       struct {
+               uint64_t w_pending:4;
+               uint64_t w_xt_crd_to:1;
+               uint64_t w_xt_tail_to:1;
+               uint64_t w_rsvd_3:3;
+               uint64_t w_tx_mx_rty:1;
+               uint64_t w_rsvd_2:6;
+               uint64_t w_llp_tx_cnt:8;
+               uint64_t w_rsvd_1:8;
+               uint64_t w_crazy:1;
+               uint64_t w_rsvd:31;
        } ii_wstat_fld_s;
 } ii_wstat_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  This is a read-write enabled register. It controls     *
  * various aspects of the Crosstalk flow control.                       *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_wcr_u {
-       uint64_t        ii_wcr_regval;
-       struct  {
-               uint64_t        w_wid                     :      4;
-               uint64_t        w_tag                     :      1;
-               uint64_t        w_rsvd_1                  :      8;
-               uint64_t        w_dst_crd                 :      3;
-               uint64_t        w_f_bad_pkt               :      1;
-               uint64_t        w_dir_con                 :      1;
-               uint64_t        w_e_thresh                :      5;
-               uint64_t        w_rsvd                    :     41;
+       uint64_t ii_wcr_regval;
+       struct {
+               uint64_t w_wid:4;
+               uint64_t w_tag:1;
+               uint64_t w_rsvd_1:8;
+               uint64_t w_dst_crd:3;
+               uint64_t w_f_bad_pkt:1;
+               uint64_t w_dir_con:1;
+               uint64_t w_e_thresh:5;
+               uint64_t w_rsvd:41;
        } ii_wcr_fld_s;
 } ii_wcr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  This register's value is a bit vector that guards      *
  * access to local registers within the II as well as to external       *
  * Crosstalk widgets. Each bit in the register corresponds to a         *
@@ -311,21 +306,18 @@ typedef union ii_wcr_u {
  * region ID bits are enabled in this same register. It can also be     *
  * accessed through the IAlias space by the local processors.           *
  * The reset value of this register allows access by all nodes.         *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ilapr_u {
-       uint64_t        ii_ilapr_regval;
-       struct  {
-               uint64_t        i_region                  :     64;
+       uint64_t ii_ilapr_regval;
+       struct {
+               uint64_t i_region:64;
        } ii_ilapr_fld_s;
 } ii_ilapr_u_t;
 
-
-
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  A write to this register of the 64-bit value           *
  * "SGIrules" in ASCII, will cause the bit in the ILAPR register        *
  * corresponding to the region of the requestor to be set (allow        *
@@ -334,59 +326,54 @@ typedef union ii_ilapr_u {
  * This register can also be accessed through the IAlias space.         *
  * However, this access will not change the access permissions in the   *
  * ILAPR.                                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ilapo_u {
-       uint64_t        ii_ilapo_regval;
-       struct  {
-               uint64_t        i_io_ovrride            :       64;
+       uint64_t ii_ilapo_regval;
+       struct {
+               uint64_t i_io_ovrride:64;
        } ii_ilapo_fld_s;
 } ii_ilapo_u_t;
 
-
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register qualifies all the PIO and Graphics writes launched    *
  * from the SHUB towards a widget.                                      *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iowa_u {
-       uint64_t        ii_iowa_regval;
-       struct  {
-               uint64_t        i_w0_oac                  :      1;
-               uint64_t        i_rsvd_1                  :      7;
-                uint64_t       i_wx_oac                  :      8;
-               uint64_t        i_rsvd                    :     48;
+       uint64_t ii_iowa_regval;
+       struct {
+               uint64_t i_w0_oac:1;
+               uint64_t i_rsvd_1:7;
+               uint64_t i_wx_oac:8;
+               uint64_t i_rsvd:48;
        } ii_iowa_fld_s;
 } ii_iowa_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  This register qualifies all the requests launched      *
  * from a widget towards the Shub. This register is intended to be      *
  * used by software in case of misbehaving widgets.                     *
- *                                                                      *
- *                                                                      *
+ *                                                                     *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iiwa_u {
-       uint64_t        ii_iiwa_regval;
-       struct  {
-               uint64_t        i_w0_iac                  :      1;
-               uint64_t        i_rsvd_1                  :      7;
-               uint64_t        i_wx_iac                  :      8;
-               uint64_t        i_rsvd                    :     48;
+       uint64_t ii_iiwa_regval;
+       struct {
+               uint64_t i_w0_iac:1;
+               uint64_t i_rsvd_1:7;
+               uint64_t i_wx_iac:8;
+               uint64_t i_rsvd:48;
        } ii_iiwa_fld_s;
 } ii_iiwa_u_t;
 
-
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  This register qualifies all the operations launched    *
  * from a widget towards the SHub. It allows individual access          *
  * control for up to 8 devices per widget. A device refers to           *
@@ -401,72 +388,69 @@ typedef union ii_iiwa_u {
  * The bits in this field are set by writing a 1 to them. Incoming      *
  * replies from Crosstalk are not subject to this access control        *
  * mechanism.                                                           *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iidem_u {
-       uint64_t        ii_iidem_regval;
-       struct  {
-               uint64_t        i_w8_dxs                  :      8;
-               uint64_t        i_w9_dxs                  :      8;
-               uint64_t        i_wa_dxs                  :      8;
-               uint64_t        i_wb_dxs                  :      8;
-               uint64_t        i_wc_dxs                  :      8;
-               uint64_t        i_wd_dxs                  :      8;
-               uint64_t        i_we_dxs                  :      8;
-               uint64_t        i_wf_dxs                  :      8;
+       uint64_t ii_iidem_regval;
+       struct {
+               uint64_t i_w8_dxs:8;
+               uint64_t i_w9_dxs:8;
+               uint64_t i_wa_dxs:8;
+               uint64_t i_wb_dxs:8;
+               uint64_t i_wc_dxs:8;
+               uint64_t i_wd_dxs:8;
+               uint64_t i_we_dxs:8;
+               uint64_t i_wf_dxs:8;
        } ii_iidem_fld_s;
 } ii_iidem_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the various programmable fields necessary    *
  * for controlling and observing the LLP signals.                       *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ilcsr_u {
-       uint64_t        ii_ilcsr_regval;
-       struct  {
-               uint64_t        i_nullto                  :      6;
-               uint64_t        i_rsvd_4                  :      2;
-               uint64_t        i_wrmrst                  :      1;
-               uint64_t        i_rsvd_3                  :      1;
-               uint64_t        i_llp_en                  :      1;
-               uint64_t        i_bm8                     :      1;
-               uint64_t        i_llp_stat                :      2;
-               uint64_t        i_remote_power            :      1;
-               uint64_t        i_rsvd_2                  :      1;
-               uint64_t        i_maxrtry                 :     10;
-               uint64_t        i_d_avail_sel             :      2;
-               uint64_t        i_rsvd_1                  :      4;
-               uint64_t        i_maxbrst                 :     10;
-                uint64_t       i_rsvd                    :     22;
+       uint64_t ii_ilcsr_regval;
+       struct {
+               uint64_t i_nullto:6;
+               uint64_t i_rsvd_4:2;
+               uint64_t i_wrmrst:1;
+               uint64_t i_rsvd_3:1;
+               uint64_t i_llp_en:1;
+               uint64_t i_bm8:1;
+               uint64_t i_llp_stat:2;
+               uint64_t i_remote_power:1;
+               uint64_t i_rsvd_2:1;
+               uint64_t i_maxrtry:10;
+               uint64_t i_d_avail_sel:2;
+               uint64_t i_rsvd_1:4;
+               uint64_t i_maxbrst:10;
+               uint64_t i_rsvd:22;
 
        } ii_ilcsr_fld_s;
 } ii_ilcsr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This is simply a status registers that monitors the LLP error       *
- * rate.                                                                *
- *                                                                      *
+ * rate.                                                               *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_illr_u {
-       uint64_t        ii_illr_regval;
-       struct  {
-               uint64_t        i_sn_cnt                  :     16;
-               uint64_t        i_cb_cnt                  :     16;
-               uint64_t        i_rsvd                    :     32;
+       uint64_t ii_illr_regval;
+       struct {
+               uint64_t i_sn_cnt:16;
+               uint64_t i_cb_cnt:16;
+               uint64_t i_rsvd:32;
        } ii_illr_fld_s;
 } ii_illr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  All II-detected non-BTE error interrupts are           *
  * specified via this register.                                         *
  * NOTE: The PI interrupt register address is hardcoded in the II. If   *
@@ -476,107 +460,100 @@ typedef union ii_illr_u {
  * PI_ID==1, then the II sends the interrupt request to address         *
  * offset 0x01A0_0090 within the local register address space of PI1    *
  * on the node specified by the NODE field.                             *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iidsr_u {
-       uint64_t        ii_iidsr_regval;
-       struct  {
-               uint64_t        i_level                   :      8;
-               uint64_t        i_pi_id                   :      1;
-               uint64_t        i_node                    :     11;
-               uint64_t       i_rsvd_3                  :      4;
-               uint64_t        i_enable                  :      1;
-               uint64_t        i_rsvd_2                  :      3;
-               uint64_t        i_int_sent                :      2;
-               uint64_t       i_rsvd_1                  :      2;
-               uint64_t        i_pi0_forward_int         :      1;
-               uint64_t        i_pi1_forward_int         :      1;
-               uint64_t        i_rsvd                    :     30;
+       uint64_t ii_iidsr_regval;
+       struct {
+               uint64_t i_level:8;
+               uint64_t i_pi_id:1;
+               uint64_t i_node:11;
+               uint64_t i_rsvd_3:4;
+               uint64_t i_enable:1;
+               uint64_t i_rsvd_2:3;
+               uint64_t i_int_sent:2;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_pi0_forward_int:1;
+               uint64_t i_pi1_forward_int:1;
+               uint64_t i_rsvd:30;
        } ii_iidsr_fld_s;
 } ii_iidsr_u_t;
 
-
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are two instances of this register. This register is used     *
  * for matching up the incoming responses from the graphics widget to   *
  * the processor that initiated the graphics operation. The             *
  * write-responses are converted to graphics credits and returned to    *
  * the processor so that the processor interface can manage the flow    *
  * control.                                                             *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_igfx0_u {
-       uint64_t        ii_igfx0_regval;
-       struct  {
-               uint64_t        i_w_num                   :      4;
-               uint64_t       i_pi_id                   :      1;
-               uint64_t        i_n_num                   :     12;
-               uint64_t       i_p_num                   :      1;
-               uint64_t       i_rsvd                    :     46;
+       uint64_t ii_igfx0_regval;
+       struct {
+               uint64_t i_w_num:4;
+               uint64_t i_pi_id:1;
+               uint64_t i_n_num:12;
+               uint64_t i_p_num:1;
+               uint64_t i_rsvd:46;
        } ii_igfx0_fld_s;
 } ii_igfx0_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are two instances of this register. This register is used     *
  * for matching up the incoming responses from the graphics widget to   *
  * the processor that initiated the graphics operation. The             *
  * write-responses are converted to graphics credits and returned to    *
  * the processor so that the processor interface can manage the flow    *
  * control.                                                             *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_igfx1_u {
-       uint64_t        ii_igfx1_regval;
-       struct  {
-               uint64_t        i_w_num                   :      4;
-               uint64_t       i_pi_id                   :      1;
-               uint64_t        i_n_num                   :     12;
-               uint64_t       i_p_num                   :      1;
-               uint64_t       i_rsvd                    :     46;
+       uint64_t ii_igfx1_regval;
+       struct {
+               uint64_t i_w_num:4;
+               uint64_t i_pi_id:1;
+               uint64_t i_n_num:12;
+               uint64_t i_p_num:1;
+               uint64_t i_rsvd:46;
        } ii_igfx1_fld_s;
 } ii_igfx1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are two instances of this registers. These registers are      *
  * used as scratch registers for software use.                          *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iscr0_u {
-       uint64_t        ii_iscr0_regval;
-       struct  {
-               uint64_t        i_scratch                 :     64;
+       uint64_t ii_iscr0_regval;
+       struct {
+               uint64_t i_scratch:64;
        } ii_iscr0_fld_s;
 } ii_iscr0_u_t;
 
-
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are two instances of this registers. These registers are      *
  * used as scratch registers for software use.                          *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iscr1_u {
-       uint64_t        ii_iscr1_regval;
-       struct  {
-               uint64_t        i_scratch                 :     64;
+       uint64_t ii_iscr1_regval;
+       struct {
+               uint64_t i_scratch:64;
        } ii_iscr1_fld_s;
 } ii_iscr1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are seven instances of translation table entry   *
  * registers. Each register maps a Shub Big Window to a 48-bit          *
  * address on Crosstalk.                                                *
@@ -599,23 +576,22 @@ typedef union ii_iscr1_u {
  * Crosstalk space addressable by the Shub is thus the lower            *
  * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
  * of this space can be accessed.                                       *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_itte1_u {
-       uint64_t        ii_itte1_regval;
-       struct  {
-               uint64_t        i_offset                  :      5;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_w_num                   :      4;
-               uint64_t        i_iosp                    :      1;
-               uint64_t        i_rsvd                    :     51;
+       uint64_t ii_itte1_regval;
+       struct {
+               uint64_t i_offset:5;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_w_num:4;
+               uint64_t i_iosp:1;
+               uint64_t i_rsvd:51;
        } ii_itte1_fld_s;
 } ii_itte1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are seven instances of translation table entry   *
  * registers. Each register maps a Shub Big Window to a 48-bit          *
  * address on Crosstalk.                                                *
@@ -638,23 +614,22 @@ typedef union ii_itte1_u {
  * Crosstalk space addressable by the Shub is thus the lower            *
  * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
  * of this space can be accessed.                                       *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_itte2_u {
-       uint64_t        ii_itte2_regval;
-       struct  {
-               uint64_t        i_offset                  :      5;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_w_num                   :      4;
-               uint64_t        i_iosp                    :      1;
-               uint64_t       i_rsvd                    :     51;
+       uint64_t ii_itte2_regval;
+       struct {
+               uint64_t i_offset:5;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_w_num:4;
+               uint64_t i_iosp:1;
+               uint64_t i_rsvd:51;
        } ii_itte2_fld_s;
 } ii_itte2_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are seven instances of translation table entry   *
  * registers. Each register maps a Shub Big Window to a 48-bit          *
  * address on Crosstalk.                                                *
@@ -677,23 +652,22 @@ typedef union ii_itte2_u {
  * Crosstalk space addressable by the SHub is thus the lower            *
  * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
  * of this space can be accessed.                                       *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_itte3_u {
-       uint64_t        ii_itte3_regval;
-       struct  {
-               uint64_t        i_offset                  :      5;
-               uint64_t       i_rsvd_1                  :      3;
-               uint64_t       i_w_num                   :      4;
-               uint64_t       i_iosp                    :      1;
-               uint64_t       i_rsvd                    :     51;
+       uint64_t ii_itte3_regval;
+       struct {
+               uint64_t i_offset:5;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_w_num:4;
+               uint64_t i_iosp:1;
+               uint64_t i_rsvd:51;
        } ii_itte3_fld_s;
 } ii_itte3_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are seven instances of translation table entry   *
  * registers. Each register maps a SHub Big Window to a 48-bit          *
  * address on Crosstalk.                                                *
@@ -716,23 +690,22 @@ typedef union ii_itte3_u {
  * Crosstalk space addressable by the SHub is thus the lower            *
  * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
  * of this space can be accessed.                                       *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_itte4_u {
-       uint64_t        ii_itte4_regval;
-       struct  {
-               uint64_t        i_offset                  :      5;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t       i_w_num                   :      4;
-               uint64_t       i_iosp                    :      1;
-               uint64_t       i_rsvd                    :     51;
+       uint64_t ii_itte4_regval;
+       struct {
+               uint64_t i_offset:5;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_w_num:4;
+               uint64_t i_iosp:1;
+               uint64_t i_rsvd:51;
        } ii_itte4_fld_s;
 } ii_itte4_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are seven instances of translation table entry   *
  * registers. Each register maps a SHub Big Window to a 48-bit          *
  * address on Crosstalk.                                                *
@@ -755,23 +728,22 @@ typedef union ii_itte4_u {
  * Crosstalk space addressable by the Shub is thus the lower            *
  * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
  * of this space can be accessed.                                       *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_itte5_u {
-       uint64_t        ii_itte5_regval;
-       struct  {
-               uint64_t        i_offset                  :      5;
-               uint64_t       i_rsvd_1                  :      3;
-               uint64_t       i_w_num                   :      4;
-               uint64_t       i_iosp                    :      1;
-               uint64_t       i_rsvd                    :     51;
+       uint64_t ii_itte5_regval;
+       struct {
+               uint64_t i_offset:5;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_w_num:4;
+               uint64_t i_iosp:1;
+               uint64_t i_rsvd:51;
        } ii_itte5_fld_s;
 } ii_itte5_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are seven instances of translation table entry   *
  * registers. Each register maps a Shub Big Window to a 48-bit          *
  * address on Crosstalk.                                                *
@@ -794,23 +766,22 @@ typedef union ii_itte5_u {
  * Crosstalk space addressable by the Shub is thus the lower            *
  * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
  * of this space can be accessed.                                       *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_itte6_u {
-       uint64_t        ii_itte6_regval;
-       struct  {
-               uint64_t        i_offset                  :      5;
-               uint64_t       i_rsvd_1                  :      3;
-               uint64_t       i_w_num                   :      4;
-               uint64_t       i_iosp                    :      1;
-               uint64_t       i_rsvd                    :     51;
+       uint64_t ii_itte6_regval;
+       struct {
+               uint64_t i_offset:5;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_w_num:4;
+               uint64_t i_iosp:1;
+               uint64_t i_rsvd:51;
        } ii_itte6_fld_s;
 } ii_itte6_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are seven instances of translation table entry   *
  * registers. Each register maps a Shub Big Window to a 48-bit          *
  * address on Crosstalk.                                                *
@@ -833,23 +804,22 @@ typedef union ii_itte6_u {
  * Crosstalk space addressable by the SHub is thus the lower            *
  * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
  * of this space can be accessed.                                       *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_itte7_u {
-       uint64_t        ii_itte7_regval;
-       struct  {
-               uint64_t        i_offset                  :      5;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t       i_w_num                   :      4;
-               uint64_t       i_iosp                    :      1;
-               uint64_t       i_rsvd                    :     51;
+       uint64_t ii_itte7_regval;
+       struct {
+               uint64_t i_offset:5;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_w_num:4;
+               uint64_t i_iosp:1;
+               uint64_t i_rsvd:51;
        } ii_itte7_fld_s;
 } ii_itte7_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 9 instances of this register, one per        *
  * actual widget in this implementation of SHub and Crossbow.           *
  * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
@@ -868,33 +838,32 @@ typedef union ii_itte7_u {
  * register; the write will correct the C field and capture its new     *
  * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
  * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
+ * .                                                                   *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprb0_u {
-       uint64_t        ii_iprb0_regval;
-       struct  {
-               uint64_t        i_c                       :      8;
-               uint64_t        i_na                      :     14;
-               uint64_t       i_rsvd_2                  :      2;
-               uint64_t        i_nb                      :     14;
-               uint64_t        i_rsvd_1                  :      2;
-               uint64_t        i_m                       :      2;
-               uint64_t        i_f                       :      1;
-               uint64_t        i_of_cnt                  :      5;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_rd_to                   :      1;
-               uint64_t        i_spur_wr                 :      1;
-               uint64_t        i_spur_rd                 :      1;
-               uint64_t        i_rsvd                    :     11;
-               uint64_t        i_mult_err                :      1;
+       uint64_t ii_iprb0_regval;
+       struct {
+               uint64_t i_c:8;
+               uint64_t i_na:14;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_nb:14;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_m:2;
+               uint64_t i_f:1;
+               uint64_t i_of_cnt:5;
+               uint64_t i_error:1;
+               uint64_t i_rd_to:1;
+               uint64_t i_spur_wr:1;
+               uint64_t i_spur_rd:1;
+               uint64_t i_rsvd:11;
+               uint64_t i_mult_err:1;
        } ii_iprb0_fld_s;
 } ii_iprb0_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 9 instances of this register, one per        *
  * actual widget in this implementation of SHub and Crossbow.           *
  * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
@@ -913,33 +882,32 @@ typedef union ii_iprb0_u {
  * register; the write will correct the C field and capture its new     *
  * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
  * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
+ * .                                                                   *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprb8_u {
-       uint64_t        ii_iprb8_regval;
-       struct  {
-               uint64_t        i_c                       :      8;
-               uint64_t        i_na                      :     14;
-               uint64_t       i_rsvd_2                  :      2;
-               uint64_t        i_nb                      :     14;
-               uint64_t       i_rsvd_1                  :      2;
-               uint64_t       i_m                       :      2;
-               uint64_t       i_f                       :      1;
-               uint64_t       i_of_cnt                  :      5;
-               uint64_t       i_error                   :      1;
-               uint64_t       i_rd_to                   :      1;
-               uint64_t       i_spur_wr                 :      1;
-               uint64_t        i_spur_rd                 :      1;
-               uint64_t       i_rsvd                    :     11;
-               uint64_t        i_mult_err                :      1;
+       uint64_t ii_iprb8_regval;
+       struct {
+               uint64_t i_c:8;
+               uint64_t i_na:14;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_nb:14;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_m:2;
+               uint64_t i_f:1;
+               uint64_t i_of_cnt:5;
+               uint64_t i_error:1;
+               uint64_t i_rd_to:1;
+               uint64_t i_spur_wr:1;
+               uint64_t i_spur_rd:1;
+               uint64_t i_rsvd:11;
+               uint64_t i_mult_err:1;
        } ii_iprb8_fld_s;
 } ii_iprb8_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 9 instances of this register, one per        *
  * actual widget in this implementation of SHub and Crossbow.           *
  * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
@@ -958,33 +926,32 @@ typedef union ii_iprb8_u {
  * register; the write will correct the C field and capture its new     *
  * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
  * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
+ * .                                                                   *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprb9_u {
-       uint64_t        ii_iprb9_regval;
-       struct  {
-               uint64_t        i_c                       :      8;
-               uint64_t        i_na                      :     14;
-               uint64_t        i_rsvd_2                  :      2;
-               uint64_t        i_nb                      :     14;
-               uint64_t        i_rsvd_1                  :      2;
-               uint64_t        i_m                       :      2;
-               uint64_t        i_f                       :      1;
-               uint64_t        i_of_cnt                  :      5;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_rd_to                   :      1;
-               uint64_t        i_spur_wr                 :      1;
-               uint64_t        i_spur_rd                 :      1;
-               uint64_t        i_rsvd                    :     11;
-               uint64_t        i_mult_err                :      1;
+       uint64_t ii_iprb9_regval;
+       struct {
+               uint64_t i_c:8;
+               uint64_t i_na:14;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_nb:14;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_m:2;
+               uint64_t i_f:1;
+               uint64_t i_of_cnt:5;
+               uint64_t i_error:1;
+               uint64_t i_rd_to:1;
+               uint64_t i_spur_wr:1;
+               uint64_t i_spur_rd:1;
+               uint64_t i_rsvd:11;
+               uint64_t i_mult_err:1;
        } ii_iprb9_fld_s;
 } ii_iprb9_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 9 instances of this register, one per        *
  * actual widget in this implementation of SHub and Crossbow.        *
  * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
@@ -1003,33 +970,32 @@ typedef union ii_iprb9_u {
  * register; the write will correct the C field and capture its new     *
  * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
  * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- *                                                                      *
- *                                                                      *
+ *                                                                     *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprba_u {
-       uint64_t        ii_iprba_regval;
-       struct  {
-               uint64_t        i_c                       :      8;
-               uint64_t        i_na                      :     14;
-               uint64_t       i_rsvd_2                  :      2;
-               uint64_t        i_nb                      :     14;
-               uint64_t        i_rsvd_1                  :      2;
-               uint64_t        i_m                       :      2;
-               uint64_t        i_f                       :      1;
-               uint64_t        i_of_cnt                  :      5;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_rd_to                   :      1;
-               uint64_t        i_spur_wr                 :      1;
-               uint64_t        i_spur_rd                 :      1;
-               uint64_t        i_rsvd                    :     11;
-               uint64_t        i_mult_err                :      1;
+       uint64_t ii_iprba_regval;
+       struct {
+               uint64_t i_c:8;
+               uint64_t i_na:14;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_nb:14;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_m:2;
+               uint64_t i_f:1;
+               uint64_t i_of_cnt:5;
+               uint64_t i_error:1;
+               uint64_t i_rd_to:1;
+               uint64_t i_spur_wr:1;
+               uint64_t i_spur_rd:1;
+               uint64_t i_rsvd:11;
+               uint64_t i_mult_err:1;
        } ii_iprba_fld_s;
 } ii_iprba_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 9 instances of this register, one per        *
  * actual widget in this implementation of SHub and Crossbow.           *
  * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
@@ -1048,33 +1014,32 @@ typedef union ii_iprba_u {
  * register; the write will correct the C field and capture its new     *
  * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
  * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
+ * .                                                                   *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprbb_u {
-       uint64_t        ii_iprbb_regval;
-       struct  {
-               uint64_t        i_c                       :      8;
-               uint64_t        i_na                      :     14;
-               uint64_t        i_rsvd_2                  :      2;
-               uint64_t        i_nb                      :     14;
-               uint64_t        i_rsvd_1                  :      2;
-               uint64_t        i_m                       :      2;
-               uint64_t        i_f                       :      1;
-               uint64_t        i_of_cnt                  :      5;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_rd_to                   :      1;
-               uint64_t        i_spur_wr                 :      1;
-               uint64_t        i_spur_rd                 :      1;
-               uint64_t        i_rsvd                    :     11;
-               uint64_t        i_mult_err                :      1;
+       uint64_t ii_iprbb_regval;
+       struct {
+               uint64_t i_c:8;
+               uint64_t i_na:14;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_nb:14;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_m:2;
+               uint64_t i_f:1;
+               uint64_t i_of_cnt:5;
+               uint64_t i_error:1;
+               uint64_t i_rd_to:1;
+               uint64_t i_spur_wr:1;
+               uint64_t i_spur_rd:1;
+               uint64_t i_rsvd:11;
+               uint64_t i_mult_err:1;
        } ii_iprbb_fld_s;
 } ii_iprbb_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 9 instances of this register, one per        *
  * actual widget in this implementation of SHub and Crossbow.           *
  * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
@@ -1093,33 +1058,32 @@ typedef union ii_iprbb_u {
  * register; the write will correct the C field and capture its new     *
  * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
  * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
+ * .                                                                   *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprbc_u {
-       uint64_t        ii_iprbc_regval;
-       struct  {
-               uint64_t        i_c                       :      8;
-               uint64_t        i_na                      :     14;
-               uint64_t        i_rsvd_2                  :      2;
-               uint64_t        i_nb                      :     14;
-               uint64_t        i_rsvd_1                  :      2;
-               uint64_t        i_m                       :      2;
-               uint64_t        i_f                       :      1;
-               uint64_t        i_of_cnt                  :      5;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_rd_to                   :      1;
-               uint64_t        i_spur_wr                 :      1;
-               uint64_t        i_spur_rd                 :      1;
-               uint64_t        i_rsvd                    :     11;
-               uint64_t        i_mult_err                :      1;
+       uint64_t ii_iprbc_regval;
+       struct {
+               uint64_t i_c:8;
+               uint64_t i_na:14;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_nb:14;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_m:2;
+               uint64_t i_f:1;
+               uint64_t i_of_cnt:5;
+               uint64_t i_error:1;
+               uint64_t i_rd_to:1;
+               uint64_t i_spur_wr:1;
+               uint64_t i_spur_rd:1;
+               uint64_t i_rsvd:11;
+               uint64_t i_mult_err:1;
        } ii_iprbc_fld_s;
 } ii_iprbc_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 9 instances of this register, one per        *
  * actual widget in this implementation of SHub and Crossbow.           *
  * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
@@ -1138,33 +1102,32 @@ typedef union ii_iprbc_u {
  * register; the write will correct the C field and capture its new     *
  * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
  * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
+ * .                                                                   *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprbd_u {
-       uint64_t        ii_iprbd_regval;
-       struct  {
-               uint64_t        i_c                       :      8;
-               uint64_t        i_na                      :     14;
-               uint64_t        i_rsvd_2                  :      2;
-               uint64_t        i_nb                      :     14;
-               uint64_t        i_rsvd_1                  :      2;
-               uint64_t        i_m                       :      2;
-               uint64_t        i_f                       :      1;
-               uint64_t        i_of_cnt                  :      5;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_rd_to                   :      1;
-               uint64_t        i_spur_wr                 :      1;
-               uint64_t        i_spur_rd                 :      1;
-               uint64_t        i_rsvd                    :     11;
-               uint64_t        i_mult_err                :      1;
+       uint64_t ii_iprbd_regval;
+       struct {
+               uint64_t i_c:8;
+               uint64_t i_na:14;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_nb:14;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_m:2;
+               uint64_t i_f:1;
+               uint64_t i_of_cnt:5;
+               uint64_t i_error:1;
+               uint64_t i_rd_to:1;
+               uint64_t i_spur_wr:1;
+               uint64_t i_spur_rd:1;
+               uint64_t i_rsvd:11;
+               uint64_t i_mult_err:1;
        } ii_iprbd_fld_s;
 } ii_iprbd_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 9 instances of this register, one per        *
  * actual widget in this implementation of SHub and Crossbow.           *
  * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
@@ -1183,33 +1146,32 @@ typedef union ii_iprbd_u {
  * register; the write will correct the C field and capture its new     *
  * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
  * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
+ * .                                                                   *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprbe_u {
-       uint64_t        ii_iprbe_regval;
-       struct  {
-               uint64_t        i_c                       :      8;
-               uint64_t        i_na                      :     14;
-               uint64_t        i_rsvd_2                  :      2;
-               uint64_t        i_nb                      :     14;
-               uint64_t        i_rsvd_1                  :      2;
-               uint64_t        i_m                       :      2;
-               uint64_t        i_f                       :      1;
-               uint64_t        i_of_cnt                  :      5;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_rd_to                   :      1;
-               uint64_t        i_spur_wr                 :      1;
-               uint64_t        i_spur_rd                 :      1;
-               uint64_t        i_rsvd                    :     11;
-               uint64_t        i_mult_err                :      1;
+       uint64_t ii_iprbe_regval;
+       struct {
+               uint64_t i_c:8;
+               uint64_t i_na:14;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_nb:14;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_m:2;
+               uint64_t i_f:1;
+               uint64_t i_of_cnt:5;
+               uint64_t i_error:1;
+               uint64_t i_rd_to:1;
+               uint64_t i_spur_wr:1;
+               uint64_t i_spur_rd:1;
+               uint64_t i_rsvd:11;
+               uint64_t i_mult_err:1;
        } ii_iprbe_fld_s;
 } ii_iprbe_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 9 instances of this register, one per        *
  * actual widget in this implementation of Shub and Crossbow.           *
  * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
@@ -1228,33 +1190,32 @@ typedef union ii_iprbe_u {
  * register; the write will correct the C field and capture its new     *
  * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
  * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
+ * .                                                                   *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprbf_u {
-        uint64_t       ii_iprbf_regval;
-        struct  {
-                uint64_t       i_c                       :      8;
-                uint64_t       i_na                      :     14;
-                uint64_t       i_rsvd_2                  :      2;
-                uint64_t       i_nb                      :     14;
-                uint64_t       i_rsvd_1                  :      2;
-                uint64_t       i_m                       :      2;
-                uint64_t       i_f                       :      1;
-                uint64_t       i_of_cnt                  :      5;
-                uint64_t       i_error                   :      1;
-                uint64_t       i_rd_to                   :      1;
-                uint64_t       i_spur_wr                 :      1;
-                uint64_t       i_spur_rd                 :      1;
-                uint64_t       i_rsvd                    :     11;
-                uint64_t       i_mult_err                :      1;
-        } ii_iprbe_fld_s;
+       uint64_t ii_iprbf_regval;
+       struct {
+               uint64_t i_c:8;
+               uint64_t i_na:14;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_nb:14;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_m:2;
+               uint64_t i_f:1;
+               uint64_t i_of_cnt:5;
+               uint64_t i_error:1;
+               uint64_t i_rd_to:1;
+               uint64_t i_spur_wr:1;
+               uint64_t i_spur_rd:1;
+               uint64_t i_rsvd:11;
+               uint64_t i_mult_err:1;
+       } ii_iprbe_fld_s;
 } ii_iprbf_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register specifies the timeout value to use for monitoring     *
  * Crosstalk credits which are used outbound to Crosstalk. An           *
  * internal counter called the Crosstalk Credit Timeout Counter         *
@@ -1267,20 +1228,19 @@ typedef union ii_iprbf_u {
  * Crosstalk Credit Timeout has occurred. The internal counter is not   *
  * readable from software, and stops counting at its maximum value,     *
  * so it cannot cause more than one interrupt.                          *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ixcc_u {
-       uint64_t        ii_ixcc_regval;
-       struct  {
-               uint64_t        i_time_out                :     26;
-               uint64_t        i_rsvd                    :     38;
+       uint64_t ii_ixcc_regval;
+       struct {
+               uint64_t i_time_out:26;
+               uint64_t i_rsvd:38;
        } ii_ixcc_fld_s;
 } ii_ixcc_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  This register qualifies all the PIO and DMA            *
  * operations launched from widget 0 towards the SHub. In               *
  * addition, it also qualifies accesses by the BTE streams.             *
@@ -1292,27 +1252,25 @@ typedef union ii_ixcc_u {
  * the Wx_IAC field. The bits in this field are set by writing a 1 to   *
  * them. Incoming replies from Crosstalk are not subject to this        *
  * access control mechanism.                                            *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_imem_u {
-       uint64_t        ii_imem_regval;
-       struct  {
-               uint64_t        i_w0_esd                  :      1;
-               uint64_t        i_rsvd_3                  :      3;
-               uint64_t        i_b0_esd                  :      1;
-               uint64_t        i_rsvd_2                  :      3;
-               uint64_t        i_b1_esd                  :      1;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_clr_precise             :      1;
-               uint64_t       i_rsvd                    :     51;
+       uint64_t ii_imem_regval;
+       struct {
+               uint64_t i_w0_esd:1;
+               uint64_t i_rsvd_3:3;
+               uint64_t i_b0_esd:1;
+               uint64_t i_rsvd_2:3;
+               uint64_t i_b1_esd:1;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_clr_precise:1;
+               uint64_t i_rsvd:51;
        } ii_imem_fld_s;
 } ii_imem_u_t;
 
-
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  This register specifies the timeout value to use for   *
  * monitoring Crosstalk tail flits coming into the Shub in the          *
  * TAIL_TO field. An internal counter associated with this register     *
@@ -1332,90 +1290,87 @@ typedef union ii_imem_u {
  * the value in the RRSP_TO field, a Read Response Timeout has          *
  * occurred, and error handling occurs as described in the Error        *
  * Handling section of this document.                                   *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ixtt_u {
-       uint64_t        ii_ixtt_regval;
-       struct  {
-               uint64_t        i_tail_to                 :     26;
-               uint64_t        i_rsvd_1                  :      6;
-               uint64_t        i_rrsp_ps                 :     23;
-               uint64_t        i_rrsp_to                 :      5;
-               uint64_t        i_rsvd                    :      4;
+       uint64_t ii_ixtt_regval;
+       struct {
+               uint64_t i_tail_to:26;
+               uint64_t i_rsvd_1:6;
+               uint64_t i_rrsp_ps:23;
+               uint64_t i_rrsp_to:5;
+               uint64_t i_rsvd:4;
        } ii_ixtt_fld_s;
 } ii_ixtt_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  Writing a 1 to the fields of this register clears the appropriate   *
  * error bits in other areas of SHub. Note that when the                *
  * E_PRB_x bits are used to clear error bits in PRB registers,          *
  * SPUR_RD and SPUR_WR may persist, because they require additional     *
  * action to clear them. See the IPRBx and IXSS Register                *
  * specifications.                                                      *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ieclr_u {
-       uint64_t        ii_ieclr_regval;
-       struct  {
-               uint64_t        i_e_prb_0                 :      1;
-               uint64_t        i_rsvd                    :      7;
-               uint64_t        i_e_prb_8                 :      1;
-               uint64_t        i_e_prb_9                 :      1;
-               uint64_t        i_e_prb_a                 :      1;
-               uint64_t        i_e_prb_b                 :      1;
-               uint64_t        i_e_prb_c                 :      1;
-               uint64_t        i_e_prb_d                 :      1;
-               uint64_t        i_e_prb_e                 :      1;
-               uint64_t        i_e_prb_f                 :      1;
-               uint64_t        i_e_crazy                 :      1;
-               uint64_t        i_e_bte_0                 :      1;
-               uint64_t        i_e_bte_1                 :      1;
-               uint64_t        i_reserved_1              :     10;
-               uint64_t        i_spur_rd_hdr             :      1;
-               uint64_t        i_cam_intr_to             :      1;
-               uint64_t        i_cam_overflow            :      1;
-               uint64_t        i_cam_read_miss           :      1;
-               uint64_t        i_ioq_rep_underflow       :      1;
-               uint64_t        i_ioq_req_underflow       :      1;
-               uint64_t        i_ioq_rep_overflow        :      1;
-               uint64_t        i_ioq_req_overflow        :      1;
-               uint64_t        i_iiq_rep_overflow        :      1;
-               uint64_t        i_iiq_req_overflow        :      1;
-               uint64_t        i_ii_xn_rep_cred_overflow :      1;
-               uint64_t        i_ii_xn_req_cred_overflow :      1;
-               uint64_t        i_ii_xn_invalid_cmd       :      1;
-               uint64_t        i_xn_ii_invalid_cmd       :      1;
-               uint64_t        i_reserved_2              :     21;
+       uint64_t ii_ieclr_regval;
+       struct {
+               uint64_t i_e_prb_0:1;
+               uint64_t i_rsvd:7;
+               uint64_t i_e_prb_8:1;
+               uint64_t i_e_prb_9:1;
+               uint64_t i_e_prb_a:1;
+               uint64_t i_e_prb_b:1;
+               uint64_t i_e_prb_c:1;
+               uint64_t i_e_prb_d:1;
+               uint64_t i_e_prb_e:1;
+               uint64_t i_e_prb_f:1;
+               uint64_t i_e_crazy:1;
+               uint64_t i_e_bte_0:1;
+               uint64_t i_e_bte_1:1;
+               uint64_t i_reserved_1:10;
+               uint64_t i_spur_rd_hdr:1;
+               uint64_t i_cam_intr_to:1;
+               uint64_t i_cam_overflow:1;
+               uint64_t i_cam_read_miss:1;
+               uint64_t i_ioq_rep_underflow:1;
+               uint64_t i_ioq_req_underflow:1;
+               uint64_t i_ioq_rep_overflow:1;
+               uint64_t i_ioq_req_overflow:1;
+               uint64_t i_iiq_rep_overflow:1;
+               uint64_t i_iiq_req_overflow:1;
+               uint64_t i_ii_xn_rep_cred_overflow:1;
+               uint64_t i_ii_xn_req_cred_overflow:1;
+               uint64_t i_ii_xn_invalid_cmd:1;
+               uint64_t i_xn_ii_invalid_cmd:1;
+               uint64_t i_reserved_2:21;
        } ii_ieclr_fld_s;
 } ii_ieclr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register controls both BTEs. SOFT_RESET is intended for        *
  * recovery after an error. COUNT controls the total number of CRBs     *
  * that both BTEs (combined) can use, which affects total BTE           *
  * bandwidth.                                                           *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibcr_u {
-       uint64_t        ii_ibcr_regval;
-       struct  {
-               uint64_t        i_count                   :      4;
-               uint64_t        i_rsvd_1                  :      4;
-               uint64_t        i_soft_reset              :      1;
-               uint64_t        i_rsvd                    :     55;
+       uint64_t ii_ibcr_regval;
+       struct {
+               uint64_t i_count:4;
+               uint64_t i_rsvd_1:4;
+               uint64_t i_soft_reset:1;
+               uint64_t i_rsvd:55;
        } ii_ibcr_fld_s;
 } ii_ibcr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the header of a spurious read response       *
  * received from Crosstalk. A spurious read response is defined as a    *
  * read response received by II from a widget for which (1) the SIDN    *
@@ -1440,49 +1395,47 @@ typedef union ii_ibcr_u {
  * will be set. Any SPUR_RD bits in any other PRB registers indicate    *
  * spurious messages from other widets which were detected after the    *
  * header was captured..                                                *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ixsm_u {
-       uint64_t        ii_ixsm_regval;
-       struct  {
-               uint64_t        i_byte_en                 :     32;
-               uint64_t        i_reserved                :      1;
-               uint64_t        i_tag                     :      3;
-               uint64_t        i_alt_pactyp              :      4;
-               uint64_t        i_bo                      :      1;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_vbpm                    :      1;
-               uint64_t        i_gbr                     :      1;
-               uint64_t        i_ds                      :      2;
-               uint64_t        i_ct                      :      1;
-               uint64_t        i_tnum                    :      5;
-               uint64_t        i_pactyp                  :      4;
-               uint64_t        i_sidn                    :      4;
-               uint64_t        i_didn                    :      4;
+       uint64_t ii_ixsm_regval;
+       struct {
+               uint64_t i_byte_en:32;
+               uint64_t i_reserved:1;
+               uint64_t i_tag:3;
+               uint64_t i_alt_pactyp:4;
+               uint64_t i_bo:1;
+               uint64_t i_error:1;
+               uint64_t i_vbpm:1;
+               uint64_t i_gbr:1;
+               uint64_t i_ds:2;
+               uint64_t i_ct:1;
+               uint64_t i_tnum:5;
+               uint64_t i_pactyp:4;
+               uint64_t i_sidn:4;
+               uint64_t i_didn:4;
        } ii_ixsm_fld_s;
 } ii_ixsm_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the sideband bits of a spurious read         *
  * response received from Crosstalk.                                    *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ixss_u {
-       uint64_t        ii_ixss_regval;
-       struct  {
-               uint64_t        i_sideband                :      8;
-               uint64_t        i_rsvd                    :     55;
-               uint64_t        i_valid                   :      1;
+       uint64_t ii_ixss_regval;
+       struct {
+               uint64_t i_sideband:8;
+               uint64_t i_rsvd:55;
+               uint64_t i_valid:1;
        } ii_ixss_fld_s;
 } ii_ixss_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register enables software to access the II LLP's test port.    *
  * Refer to the LLP 2.5 documentation for an explanation of the test    *
  * port. Software can write to this register to program the values      *
@@ -1490,27 +1443,26 @@ typedef union ii_ixss_u {
  * TestMask and TestSeed). Similarly, software can read from this       *
  * register to obtain the values of the test port's status outputs      *
  * (TestCBerr, TestValid and TestData).                                 *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ilct_u {
-       uint64_t        ii_ilct_regval;
-       struct  {
-               uint64_t        i_test_seed               :     20;
-               uint64_t        i_test_mask               :      8;
-               uint64_t        i_test_data               :     20;
-               uint64_t        i_test_valid              :      1;
-               uint64_t        i_test_cberr              :      1;
-               uint64_t        i_test_flit               :      3;
-               uint64_t        i_test_clear              :      1;
-               uint64_t        i_test_err_capture        :      1;
-               uint64_t        i_rsvd                    :      9;
+       uint64_t ii_ilct_regval;
+       struct {
+               uint64_t i_test_seed:20;
+               uint64_t i_test_mask:8;
+               uint64_t i_test_data:20;
+               uint64_t i_test_valid:1;
+               uint64_t i_test_cberr:1;
+               uint64_t i_test_flit:3;
+               uint64_t i_test_clear:1;
+               uint64_t i_test_err_capture:1;
+               uint64_t i_rsvd:9;
        } ii_ilct_fld_s;
 } ii_ilct_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  If the II detects an illegal incoming Duplonet packet (request or   *
  * reply) when VALID==0 in the IIEPH1 register, then it saves the       *
  * contents of the packet's header flit in the IIEPH1 and IIEPH2        *
@@ -1526,575 +1478,549 @@ typedef union ii_ilct_u {
  * packet when VALID==1 in the IIEPH1 register, then it merely sets     *
  * the OVERRUN bit to indicate that a subsequent error has happened,    *
  * and does nothing further.                                            *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iieph1_u {
-       uint64_t        ii_iieph1_regval;
-       struct  {
-               uint64_t        i_command                 :      7;
-               uint64_t        i_rsvd_5                  :      1;
-               uint64_t        i_suppl                   :     14;
-               uint64_t        i_rsvd_4                  :      1;
-               uint64_t        i_source                  :     14;
-               uint64_t        i_rsvd_3                  :      1;
-               uint64_t        i_err_type                :      4;
-               uint64_t        i_rsvd_2                  :      4;
-               uint64_t        i_overrun                 :      1;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_valid                   :      1;
-               uint64_t        i_rsvd                    :     13;
+       uint64_t ii_iieph1_regval;
+       struct {
+               uint64_t i_command:7;
+               uint64_t i_rsvd_5:1;
+               uint64_t i_suppl:14;
+               uint64_t i_rsvd_4:1;
+               uint64_t i_source:14;
+               uint64_t i_rsvd_3:1;
+               uint64_t i_err_type:4;
+               uint64_t i_rsvd_2:4;
+               uint64_t i_overrun:1;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_valid:1;
+               uint64_t i_rsvd:13;
        } ii_iieph1_fld_s;
 } ii_iieph1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register holds the Address field from the header flit of an    *
  * incoming erroneous Duplonet packet, along with the tail bit which    *
  * accompanied this header flit. This register is essentially an        *
  * extension of IIEPH1. Two registers were necessary because the 64     *
  * bits available in only a single register were insufficient to        *
  * capture the entire header flit of an erroneous packet.               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iieph2_u {
-       uint64_t        ii_iieph2_regval;
-       struct  {
-               uint64_t        i_rsvd_0                  :      3;
-               uint64_t        i_address                 :     47;
-               uint64_t        i_rsvd_1                  :     10;
-               uint64_t        i_tail                    :      1;
-               uint64_t        i_rsvd                    :      3;
+       uint64_t ii_iieph2_regval;
+       struct {
+               uint64_t i_rsvd_0:3;
+               uint64_t i_address:47;
+               uint64_t i_rsvd_1:10;
+               uint64_t i_tail:1;
+               uint64_t i_rsvd:3;
        } ii_iieph2_fld_s;
 } ii_iieph2_u_t;
 
-
 /******************************/
 
-
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register's value is a bit vector that guards access from SXBs  *
  * to local registers within the II as well as to external Crosstalk    *
  * widgets                                                             *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_islapr_u {
-       uint64_t        ii_islapr_regval;
-       struct  {
-               uint64_t        i_region                  :     64;
+       uint64_t ii_islapr_regval;
+       struct {
+               uint64_t i_region:64;
        } ii_islapr_fld_s;
 } ii_islapr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  A write to this register of the 56-bit value "Pup+Bun" will cause  *
  * the bit in the ISLAPR register corresponding to the region of the   *
  * requestor to be set (access allowed).                               (
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_islapo_u {
-       uint64_t        ii_islapo_regval;
-       struct  {
-               uint64_t        i_io_sbx_ovrride          :     56;
-               uint64_t        i_rsvd                    :      8;
+       uint64_t ii_islapo_regval;
+       struct {
+               uint64_t i_io_sbx_ovrride:56;
+               uint64_t i_rsvd:8;
        } ii_islapo_fld_s;
 } ii_islapo_u_t;
 
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  Determines how long the wrapper will wait aftr an interrupt is     *
  * initially issued from the II before it times out the outstanding    *
  * interrupt and drops it from the interrupt queue.                    * 
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iwi_u {
-       uint64_t        ii_iwi_regval;
-       struct  {
-               uint64_t        i_prescale                :     24;
-               uint64_t        i_rsvd                    :      8;
-               uint64_t        i_timeout                 :      8;
-               uint64_t        i_rsvd1                   :      8;
-               uint64_t        i_intrpt_retry_period     :      8;
-               uint64_t        i_rsvd2                   :      8;
+       uint64_t ii_iwi_regval;
+       struct {
+               uint64_t i_prescale:24;
+               uint64_t i_rsvd:8;
+               uint64_t i_timeout:8;
+               uint64_t i_rsvd1:8;
+               uint64_t i_intrpt_retry_period:8;
+               uint64_t i_rsvd2:8;
        } ii_iwi_fld_s;
 } ii_iwi_u_t;
 
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  Log errors which have occurred in the II wrapper. The errors are   *
  * cleared by writing to the IECLR register.                           * 
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iwel_u {
-       uint64_t        ii_iwel_regval;
-       struct  {
-               uint64_t        i_intr_timed_out          :      1;
-               uint64_t        i_rsvd                    :      7;
-               uint64_t        i_cam_overflow            :      1;
-               uint64_t        i_cam_read_miss           :      1;
-               uint64_t        i_rsvd1                   :      2;
-               uint64_t        i_ioq_rep_underflow       :      1;
-               uint64_t        i_ioq_req_underflow       :      1;
-               uint64_t        i_ioq_rep_overflow        :      1;
-               uint64_t        i_ioq_req_overflow        :      1;
-               uint64_t        i_iiq_rep_overflow        :      1;
-               uint64_t        i_iiq_req_overflow        :      1;
-               uint64_t        i_rsvd2                   :      6;
-               uint64_t        i_ii_xn_rep_cred_over_under:     1;
-               uint64_t        i_ii_xn_req_cred_over_under:     1;
-               uint64_t        i_rsvd3                   :      6;
-               uint64_t        i_ii_xn_invalid_cmd       :      1;
-               uint64_t        i_xn_ii_invalid_cmd       :      1;
-               uint64_t        i_rsvd4                   :     30;
+       uint64_t ii_iwel_regval;
+       struct {
+               uint64_t i_intr_timed_out:1;
+               uint64_t i_rsvd:7;
+               uint64_t i_cam_overflow:1;
+               uint64_t i_cam_read_miss:1;
+               uint64_t i_rsvd1:2;
+               uint64_t i_ioq_rep_underflow:1;
+               uint64_t i_ioq_req_underflow:1;
+               uint64_t i_ioq_rep_overflow:1;
+               uint64_t i_ioq_req_overflow:1;
+               uint64_t i_iiq_rep_overflow:1;
+               uint64_t i_iiq_req_overflow:1;
+               uint64_t i_rsvd2:6;
+               uint64_t i_ii_xn_rep_cred_over_under:1;
+               uint64_t i_ii_xn_req_cred_over_under:1;
+               uint64_t i_rsvd3:6;
+               uint64_t i_ii_xn_invalid_cmd:1;
+               uint64_t i_xn_ii_invalid_cmd:1;
+               uint64_t i_rsvd4:30;
        } ii_iwel_fld_s;
 } ii_iwel_u_t;
 
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  Controls the II wrapper.                                           * 
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iwc_u {
-       uint64_t        ii_iwc_regval;
-       struct  {
-               uint64_t        i_dma_byte_swap           :      1;
-               uint64_t        i_rsvd                    :      3;
-               uint64_t        i_cam_read_lines_reset    :      1;
-               uint64_t        i_rsvd1                   :      3;
-               uint64_t        i_ii_xn_cred_over_under_log:     1;
-               uint64_t        i_rsvd2                   :     19;
-               uint64_t        i_xn_rep_iq_depth         :      5;
-               uint64_t        i_rsvd3                   :      3;
-               uint64_t        i_xn_req_iq_depth         :      5;
-               uint64_t        i_rsvd4                   :      3;
-               uint64_t        i_iiq_depth               :      6;
-               uint64_t        i_rsvd5                   :     12;
-               uint64_t        i_force_rep_cred          :      1;
-               uint64_t        i_force_req_cred          :      1;
+       uint64_t ii_iwc_regval;
+       struct {
+               uint64_t i_dma_byte_swap:1;
+               uint64_t i_rsvd:3;
+               uint64_t i_cam_read_lines_reset:1;
+               uint64_t i_rsvd1:3;
+               uint64_t i_ii_xn_cred_over_under_log:1;
+               uint64_t i_rsvd2:19;
+               uint64_t i_xn_rep_iq_depth:5;
+               uint64_t i_rsvd3:3;
+               uint64_t i_xn_req_iq_depth:5;
+               uint64_t i_rsvd4:3;
+               uint64_t i_iiq_depth:6;
+               uint64_t i_rsvd5:12;
+               uint64_t i_force_rep_cred:1;
+               uint64_t i_force_req_cred:1;
        } ii_iwc_fld_s;
 } ii_iwc_u_t;
 
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  Status in the II wrapper.                                          * 
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iws_u {
-       uint64_t        ii_iws_regval;
-       struct  {
-               uint64_t        i_xn_rep_iq_credits       :      5;
-               uint64_t        i_rsvd                    :      3;
-               uint64_t        i_xn_req_iq_credits       :      5;
-               uint64_t        i_rsvd1                   :     51;
+       uint64_t ii_iws_regval;
+       struct {
+               uint64_t i_xn_rep_iq_credits:5;
+               uint64_t i_rsvd:3;
+               uint64_t i_xn_req_iq_credits:5;
+               uint64_t i_rsvd1:51;
        } ii_iws_fld_s;
 } ii_iws_u_t;
 
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  Masks errors in the IWEL register.                                 *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iweim_u {
-       uint64_t        ii_iweim_regval;
-       struct  {
-               uint64_t        i_intr_timed_out          :      1;
-               uint64_t        i_rsvd                    :      7;
-               uint64_t        i_cam_overflow            :      1;
-               uint64_t        i_cam_read_miss           :      1;
-               uint64_t        i_rsvd1                   :      2;
-               uint64_t        i_ioq_rep_underflow       :      1;
-               uint64_t        i_ioq_req_underflow       :      1;
-               uint64_t        i_ioq_rep_overflow        :      1;
-               uint64_t        i_ioq_req_overflow        :      1;
-               uint64_t        i_iiq_rep_overflow        :      1;
-               uint64_t        i_iiq_req_overflow        :      1;
-               uint64_t        i_rsvd2                   :      6;
-               uint64_t        i_ii_xn_rep_cred_overflow :      1;
-               uint64_t        i_ii_xn_req_cred_overflow :      1;
-               uint64_t        i_rsvd3                   :      6;
-               uint64_t        i_ii_xn_invalid_cmd       :      1;
-               uint64_t        i_xn_ii_invalid_cmd       :      1;
-               uint64_t        i_rsvd4                   :     30;
+       uint64_t ii_iweim_regval;
+       struct {
+               uint64_t i_intr_timed_out:1;
+               uint64_t i_rsvd:7;
+               uint64_t i_cam_overflow:1;
+               uint64_t i_cam_read_miss:1;
+               uint64_t i_rsvd1:2;
+               uint64_t i_ioq_rep_underflow:1;
+               uint64_t i_ioq_req_underflow:1;
+               uint64_t i_ioq_rep_overflow:1;
+               uint64_t i_ioq_req_overflow:1;
+               uint64_t i_iiq_rep_overflow:1;
+               uint64_t i_iiq_req_overflow:1;
+               uint64_t i_rsvd2:6;
+               uint64_t i_ii_xn_rep_cred_overflow:1;
+               uint64_t i_ii_xn_req_cred_overflow:1;
+               uint64_t i_rsvd3:6;
+               uint64_t i_ii_xn_invalid_cmd:1;
+               uint64_t i_xn_ii_invalid_cmd:1;
+               uint64_t i_rsvd4:30;
        } ii_iweim_fld_s;
 } ii_iweim_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  A write to this register causes a particular field in the           *
  * corresponding widget's PRB entry to be adjusted up or down by 1.     *
  * This counter should be used when recovering from error and reset     *
  * conditions. Note that software would be capable of causing           *
  * inadvertent overflow or underflow of these counters.                 *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ipca_u {
-       uint64_t        ii_ipca_regval;
-       struct  {
-               uint64_t        i_wid                     :      4;
-               uint64_t        i_adjust                  :      1;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_field                   :      2;
-               uint64_t        i_rsvd                    :     54;
+       uint64_t ii_ipca_regval;
+       struct {
+               uint64_t i_wid:4;
+               uint64_t i_adjust:1;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_field:2;
+               uint64_t i_rsvd:54;
        } ii_ipca_fld_s;
 } ii_ipca_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
-
 typedef union ii_iprte0a_u {
-       uint64_t        ii_iprte0a_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :     54;
-               uint64_t        i_widget                  :      4;
-               uint64_t        i_to_cnt                  :      5;
-               uint64_t       i_vld                     :      1;
+       uint64_t ii_iprte0a_regval;
+       struct {
+               uint64_t i_rsvd_1:54;
+               uint64_t i_widget:4;
+               uint64_t i_to_cnt:5;
+               uint64_t i_vld:1;
        } ii_iprte0a_fld_s;
 } ii_iprte0a_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte1a_u {
-       uint64_t        ii_iprte1a_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :     54;
-               uint64_t        i_widget                  :      4;
-               uint64_t        i_to_cnt                  :      5;
-               uint64_t       i_vld                     :      1;
+       uint64_t ii_iprte1a_regval;
+       struct {
+               uint64_t i_rsvd_1:54;
+               uint64_t i_widget:4;
+               uint64_t i_to_cnt:5;
+               uint64_t i_vld:1;
        } ii_iprte1a_fld_s;
 } ii_iprte1a_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte2a_u {
-       uint64_t        ii_iprte2a_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :     54;
-               uint64_t        i_widget                  :      4;
-               uint64_t        i_to_cnt                  :      5;
-               uint64_t       i_vld                     :      1;
+       uint64_t ii_iprte2a_regval;
+       struct {
+               uint64_t i_rsvd_1:54;
+               uint64_t i_widget:4;
+               uint64_t i_to_cnt:5;
+               uint64_t i_vld:1;
        } ii_iprte2a_fld_s;
 } ii_iprte2a_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte3a_u {
-       uint64_t        ii_iprte3a_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :     54;
-               uint64_t        i_widget                  :      4;
-               uint64_t        i_to_cnt                  :      5;
-               uint64_t        i_vld                     :      1;
+       uint64_t ii_iprte3a_regval;
+       struct {
+               uint64_t i_rsvd_1:54;
+               uint64_t i_widget:4;
+               uint64_t i_to_cnt:5;
+               uint64_t i_vld:1;
        } ii_iprte3a_fld_s;
 } ii_iprte3a_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte4a_u {
-       uint64_t        ii_iprte4a_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :     54;
-               uint64_t        i_widget                  :      4;
-               uint64_t        i_to_cnt                  :      5;
-               uint64_t        i_vld                     :      1;
+       uint64_t ii_iprte4a_regval;
+       struct {
+               uint64_t i_rsvd_1:54;
+               uint64_t i_widget:4;
+               uint64_t i_to_cnt:5;
+               uint64_t i_vld:1;
        } ii_iprte4a_fld_s;
 } ii_iprte4a_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte5a_u {
-       uint64_t        ii_iprte5a_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :     54;
-               uint64_t        i_widget                  :      4;
-               uint64_t        i_to_cnt                  :      5;
-               uint64_t        i_vld                     :      1;
+       uint64_t ii_iprte5a_regval;
+       struct {
+               uint64_t i_rsvd_1:54;
+               uint64_t i_widget:4;
+               uint64_t i_to_cnt:5;
+               uint64_t i_vld:1;
        } ii_iprte5a_fld_s;
 } ii_iprte5a_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte6a_u {
-       uint64_t        ii_iprte6a_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :     54;
-               uint64_t        i_widget                  :      4;
-               uint64_t        i_to_cnt                  :      5;
-               uint64_t        i_vld                     :      1;
+       uint64_t ii_iprte6a_regval;
+       struct {
+               uint64_t i_rsvd_1:54;
+               uint64_t i_widget:4;
+               uint64_t i_to_cnt:5;
+               uint64_t i_vld:1;
        } ii_iprte6a_fld_s;
 } ii_iprte6a_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte7a_u {
-        uint64_t       ii_iprte7a_regval;
-        struct  {
-                uint64_t       i_rsvd_1                  :     54;
-                uint64_t       i_widget                  :      4;
-                uint64_t       i_to_cnt                  :      5;
-                uint64_t       i_vld                     :      1;
-        } ii_iprtea7_fld_s;
+       uint64_t ii_iprte7a_regval;
+       struct {
+               uint64_t i_rsvd_1:54;
+               uint64_t i_widget:4;
+               uint64_t i_to_cnt:5;
+               uint64_t i_vld:1;
+       } ii_iprtea7_fld_s;
 } ii_iprte7a_u_t;
 
-
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
-
 typedef union ii_iprte0b_u {
-       uint64_t        ii_iprte0b_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_address                 :     47;
-               uint64_t        i_init                    :      3;
-               uint64_t       i_source                  :     11;
+       uint64_t ii_iprte0b_regval;
+       struct {
+               uint64_t i_rsvd_1:3;
+               uint64_t i_address:47;
+               uint64_t i_init:3;
+               uint64_t i_source:11;
        } ii_iprte0b_fld_s;
 } ii_iprte0b_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte1b_u {
-       uint64_t        ii_iprte1b_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_address                 :     47;
-               uint64_t        i_init                    :      3;
-               uint64_t       i_source                  :     11;
+       uint64_t ii_iprte1b_regval;
+       struct {
+               uint64_t i_rsvd_1:3;
+               uint64_t i_address:47;
+               uint64_t i_init:3;
+               uint64_t i_source:11;
        } ii_iprte1b_fld_s;
 } ii_iprte1b_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte2b_u {
-       uint64_t        ii_iprte2b_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_address                 :     47;
-               uint64_t        i_init                    :      3;
-               uint64_t       i_source                  :     11;
+       uint64_t ii_iprte2b_regval;
+       struct {
+               uint64_t i_rsvd_1:3;
+               uint64_t i_address:47;
+               uint64_t i_init:3;
+               uint64_t i_source:11;
        } ii_iprte2b_fld_s;
 } ii_iprte2b_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte3b_u {
-       uint64_t        ii_iprte3b_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_address                 :     47;
-               uint64_t        i_init                    :      3;
-               uint64_t       i_source                  :     11;
+       uint64_t ii_iprte3b_regval;
+       struct {
+               uint64_t i_rsvd_1:3;
+               uint64_t i_address:47;
+               uint64_t i_init:3;
+               uint64_t i_source:11;
        } ii_iprte3b_fld_s;
 } ii_iprte3b_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte4b_u {
-       uint64_t        ii_iprte4b_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_address                 :     47;
-               uint64_t        i_init                    :      3;
-               uint64_t       i_source                  :     11;
+       uint64_t ii_iprte4b_regval;
+       struct {
+               uint64_t i_rsvd_1:3;
+               uint64_t i_address:47;
+               uint64_t i_init:3;
+               uint64_t i_source:11;
        } ii_iprte4b_fld_s;
 } ii_iprte4b_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte5b_u {
-       uint64_t        ii_iprte5b_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_address                 :     47;
-               uint64_t        i_init                    :      3;
-               uint64_t       i_source                  :     11;
+       uint64_t ii_iprte5b_regval;
+       struct {
+               uint64_t i_rsvd_1:3;
+               uint64_t i_address:47;
+               uint64_t i_init:3;
+               uint64_t i_source:11;
        } ii_iprte5b_fld_s;
 } ii_iprte5b_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte6b_u {
-       uint64_t        ii_iprte6b_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_address                 :     47;
-               uint64_t        i_init                    :      3;
-               uint64_t       i_source                  :     11;
+       uint64_t ii_iprte6b_regval;
+       struct {
+               uint64_t i_rsvd_1:3;
+               uint64_t i_address:47;
+               uint64_t i_init:3;
+               uint64_t i_source:11;
 
        } ii_iprte6b_fld_s;
 } ii_iprte6b_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  There are 8 instances of this register. This register contains      *
  * the information that the II has to remember once it has launched a   *
  * PIO Read operation. The contents are used to form the correct        *
  * Router Network packet and direct the Crosstalk reply to the          *
  * appropriate processor.                                               *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iprte7b_u {
-        uint64_t       ii_iprte7b_regval;
-        struct  {
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_address                 :     47;
-               uint64_t        i_init                    :      3;
-               uint64_t       i_source                  :     11;
-        } ii_iprte7b_fld_s;
+       uint64_t ii_iprte7b_regval;
+       struct {
+               uint64_t i_rsvd_1:3;
+               uint64_t i_address:47;
+               uint64_t i_init:3;
+               uint64_t i_source:11;
+       } ii_iprte7b_fld_s;
 } ii_iprte7b_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  SHub II contains a feature which did not exist in      *
  * the Hub which automatically cleans up after a Read Response          *
  * timeout, including deallocation of the IPRTE and recovery of IBuf    *
@@ -2108,23 +2034,22 @@ typedef union ii_iprte7b_u {
  * Note that this register does not affect the contents of the IPRTE    *
  * registers. The Valid bits in those registers have to be              *
  * specifically turned off by software.                                 *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ipdr_u {
-       uint64_t        ii_ipdr_regval;
-       struct  {
-               uint64_t        i_te                      :      3;
-               uint64_t        i_rsvd_1                  :      1;
-               uint64_t        i_pnd                     :      1;
-               uint64_t        i_init_rpcnt              :      1;
-               uint64_t        i_rsvd                    :     58;
+       uint64_t ii_ipdr_regval;
+       struct {
+               uint64_t i_te:3;
+               uint64_t i_rsvd_1:1;
+               uint64_t i_pnd:1;
+               uint64_t i_init_rpcnt:1;
+               uint64_t i_rsvd:58;
        } ii_ipdr_fld_s;
 } ii_ipdr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  A write to this register causes a CRB entry to be returned to the   *
  * queue of free CRBs. The entry should have previously been cleared    *
  * (mark bit) via backdoor access to the pertinent CRB entry. This      *
@@ -2137,21 +2062,20 @@ typedef union ii_ipdr_u {
  * software clears the mark bit, and finally 4) software writes to      *
  * the ICDR register to return the CRB entry to the list of free CRB    *
  * entries.                                                             *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icdr_u {
-       uint64_t        ii_icdr_regval;
-       struct  {
-               uint64_t        i_crb_num                 :      4;
-               uint64_t        i_pnd                     :      1;
-               uint64_t       i_rsvd                    :     59;
+       uint64_t ii_icdr_regval;
+       struct {
+               uint64_t i_crb_num:4;
+               uint64_t i_pnd:1;
+               uint64_t i_rsvd:59;
        } ii_icdr_fld_s;
 } ii_icdr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register provides debug access to two FIFOs inside of II.      *
  * Both IOQ_MAX* fields of this register contain the instantaneous      *
  * depth (in units of the number of available entries) of the           *
@@ -2164,130 +2088,124 @@ typedef union ii_icdr_u {
  * this register is written. If there are any active entries in any     *
  * of these FIFOs when this register is written, the results are        *
  * undefined.                                                           *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ifdr_u {
-       uint64_t        ii_ifdr_regval;
-       struct  {
-               uint64_t        i_ioq_max_rq              :      7;
-               uint64_t        i_set_ioq_rq              :      1;
-               uint64_t        i_ioq_max_rp              :      7;
-               uint64_t        i_set_ioq_rp              :      1;
-               uint64_t        i_rsvd                    :     48;
+       uint64_t ii_ifdr_regval;
+       struct {
+               uint64_t i_ioq_max_rq:7;
+               uint64_t i_set_ioq_rq:1;
+               uint64_t i_ioq_max_rp:7;
+               uint64_t i_set_ioq_rp:1;
+               uint64_t i_rsvd:48;
        } ii_ifdr_fld_s;
 } ii_ifdr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register allows the II to become sluggish in removing          *
  * messages from its inbound queue (IIQ). This will cause messages to   *
  * back up in either virtual channel. Disabling the "molasses" mode     *
  * subsequently allows the II to be tested under stress. In the         *
  * sluggish ("Molasses") mode, the localized effects of congestion      *
  * can be observed.                                                     *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iiap_u {
-        uint64_t       ii_iiap_regval;
-        struct  {
-                uint64_t       i_rq_mls                  :      6;
-               uint64_t        i_rsvd_1                  :      2;
-               uint64_t        i_rp_mls                  :      6;
-               uint64_t       i_rsvd                    :     50;
-        } ii_iiap_fld_s;
+       uint64_t ii_iiap_regval;
+       struct {
+               uint64_t i_rq_mls:6;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_rp_mls:6;
+               uint64_t i_rsvd:50;
+       } ii_iiap_fld_s;
 } ii_iiap_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register allows several parameters of CRB operation to be      *
  * set. Note that writing to this register can have catastrophic side   *
  * effects, if the CRB is not quiescent, i.e. if the CRB is             *
  * processing protocol messages when the write occurs.                  *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icmr_u {
-       uint64_t        ii_icmr_regval;
-       struct  {
-               uint64_t        i_sp_msg                  :      1;
-               uint64_t        i_rd_hdr                  :      1;
-               uint64_t        i_rsvd_4                  :      2;
-               uint64_t        i_c_cnt                   :      4;
-               uint64_t        i_rsvd_3                  :      4;
-               uint64_t        i_clr_rqpd                :      1;
-               uint64_t        i_clr_rppd                :      1;
-               uint64_t        i_rsvd_2                  :      2;
-               uint64_t        i_fc_cnt                  :      4;
-               uint64_t        i_crb_vld                 :     15;
-               uint64_t        i_crb_mark                :     15;
-               uint64_t        i_rsvd_1                  :      2;
-               uint64_t        i_precise                 :      1;
-               uint64_t        i_rsvd                    :     11;
+       uint64_t ii_icmr_regval;
+       struct {
+               uint64_t i_sp_msg:1;
+               uint64_t i_rd_hdr:1;
+               uint64_t i_rsvd_4:2;
+               uint64_t i_c_cnt:4;
+               uint64_t i_rsvd_3:4;
+               uint64_t i_clr_rqpd:1;
+               uint64_t i_clr_rppd:1;
+               uint64_t i_rsvd_2:2;
+               uint64_t i_fc_cnt:4;
+               uint64_t i_crb_vld:15;
+               uint64_t i_crb_mark:15;
+               uint64_t i_rsvd_1:2;
+               uint64_t i_precise:1;
+               uint64_t i_rsvd:11;
        } ii_icmr_fld_s;
 } ii_icmr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register allows control of the table portion of the CRB        *
  * logic via software. Control operations from this register have       *
  * priority over all incoming Crosstalk or BTE requests.                *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_iccr_u {
-       uint64_t        ii_iccr_regval;
-       struct  {
-               uint64_t        i_crb_num                 :      4;
-               uint64_t        i_rsvd_1                  :      4;
-               uint64_t        i_cmd                     :      8;
-               uint64_t        i_pending                 :      1;
-               uint64_t        i_rsvd                    :     47;
+       uint64_t ii_iccr_regval;
+       struct {
+               uint64_t i_crb_num:4;
+               uint64_t i_rsvd_1:4;
+               uint64_t i_cmd:8;
+               uint64_t i_pending:1;
+               uint64_t i_rsvd:47;
        } ii_iccr_fld_s;
 } ii_iccr_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register allows the maximum timeout value to be programmed.    *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icto_u {
-       uint64_t        ii_icto_regval;
-       struct  {
-               uint64_t        i_timeout                 :      8;
-               uint64_t        i_rsvd                    :     56;
+       uint64_t ii_icto_regval;
+       struct {
+               uint64_t i_timeout:8;
+               uint64_t i_rsvd:56;
        } ii_icto_fld_s;
 } ii_icto_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register allows the timeout prescalar to be programmed. An     *
  * internal counter is associated with this register. When the          *
  * internal counter reaches the value of the PRESCALE field, the        *
  * timer registers in all valid CRBs are incremented (CRBx_D[TIMEOUT]   *
  * field). The internal counter resets to zero, and then continues      *
  * counting.                                                            *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ictp_u {
-       uint64_t        ii_ictp_regval;
-       struct  {
-               uint64_t        i_prescale                :     24;
-               uint64_t        i_rsvd                    :     40;
+       uint64_t ii_ictp_regval;
+       struct {
+               uint64_t i_prescale:24;
+               uint64_t i_rsvd:40;
        } ii_ictp_fld_s;
 } ii_ictp_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
  * used for Crosstalk operations (both cacheline and partial            *
  * operations) or BTE/IO. Because the CRB entries are very wide, five   *
@@ -2306,243 +2224,234 @@ typedef union ii_ictp_u {
  * recovering any potential error state from before the reset).         *
  * The following four tables summarize the format for the four          *
  * registers that are used for each ICRB# Entry.                        *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icrb0_a_u {
-       uint64_t        ii_icrb0_a_regval;
-       struct  {
-               uint64_t        ia_iow                    :      1;
-               uint64_t        ia_vld                    :      1;
-               uint64_t        ia_addr                   :     47;
-               uint64_t        ia_tnum                   :      5;
-               uint64_t        ia_sidn                   :      4;
-               uint64_t       ia_rsvd                   :      6;
+       uint64_t ii_icrb0_a_regval;
+       struct {
+               uint64_t ia_iow:1;
+               uint64_t ia_vld:1;
+               uint64_t ia_addr:47;
+               uint64_t ia_tnum:5;
+               uint64_t ia_sidn:4;
+               uint64_t ia_rsvd:6;
        } ii_icrb0_a_fld_s;
 } ii_icrb0_a_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
  * used for Crosstalk operations (both cacheline and partial            *
  * operations) or BTE/IO. Because the CRB entries are very wide, five   *
  * registers (_A to _E) are required to read and write each entry.      *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icrb0_b_u {
-       uint64_t        ii_icrb0_b_regval;
-       struct  {
-               uint64_t        ib_xt_err                 :      1;
-               uint64_t        ib_mark                   :      1;
-               uint64_t        ib_ln_uce                 :      1;
-               uint64_t        ib_errcode                :      3;
-               uint64_t        ib_error                  :      1;
-               uint64_t        ib_stall__bte_1           :      1;
-               uint64_t        ib_stall__bte_0           :      1;
-               uint64_t        ib_stall__intr            :      1;
-               uint64_t        ib_stall_ib               :      1;
-               uint64_t        ib_intvn                  :      1;
-               uint64_t        ib_wb                     :      1;
-               uint64_t        ib_hold                   :      1;
-               uint64_t        ib_ack                    :      1;
-               uint64_t        ib_resp                   :      1;
-               uint64_t        ib_ack_cnt                :     11;
-               uint64_t        ib_rsvd                   :      7;
-               uint64_t        ib_exc                    :      5;
-               uint64_t        ib_init                   :      3;
-               uint64_t        ib_imsg                   :      8;
-               uint64_t        ib_imsgtype               :      2;
-               uint64_t        ib_use_old                :      1;
-               uint64_t        ib_rsvd_1                 :     11;
+       uint64_t ii_icrb0_b_regval;
+       struct {
+               uint64_t ib_xt_err:1;
+               uint64_t ib_mark:1;
+               uint64_t ib_ln_uce:1;
+               uint64_t ib_errcode:3;
+               uint64_t ib_error:1;
+               uint64_t ib_stall__bte_1:1;
+               uint64_t ib_stall__bte_0:1;
+               uint64_t ib_stall__intr:1;
+               uint64_t ib_stall_ib:1;
+               uint64_t ib_intvn:1;
+               uint64_t ib_wb:1;
+               uint64_t ib_hold:1;
+               uint64_t ib_ack:1;
+               uint64_t ib_resp:1;
+               uint64_t ib_ack_cnt:11;
+               uint64_t ib_rsvd:7;
+               uint64_t ib_exc:5;
+               uint64_t ib_init:3;
+               uint64_t ib_imsg:8;
+               uint64_t ib_imsgtype:2;
+               uint64_t ib_use_old:1;
+               uint64_t ib_rsvd_1:11;
        } ii_icrb0_b_fld_s;
 } ii_icrb0_b_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
  * used for Crosstalk operations (both cacheline and partial            *
  * operations) or BTE/IO. Because the CRB entries are very wide, five   *
  * registers (_A to _E) are required to read and write each entry.      *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icrb0_c_u {
-       uint64_t        ii_icrb0_c_regval;
-       struct  {
-               uint64_t        ic_source                 :     15;
-               uint64_t        ic_size                   :      2;
-               uint64_t        ic_ct                     :      1;
-               uint64_t        ic_bte_num                :      1;
-               uint64_t        ic_gbr                    :      1;
-               uint64_t        ic_resprqd                :      1;
-               uint64_t        ic_bo                     :      1;
-               uint64_t        ic_suppl                  :     15;
-               uint64_t        ic_rsvd                   :     27;
+       uint64_t ii_icrb0_c_regval;
+       struct {
+               uint64_t ic_source:15;
+               uint64_t ic_size:2;
+               uint64_t ic_ct:1;
+               uint64_t ic_bte_num:1;
+               uint64_t ic_gbr:1;
+               uint64_t ic_resprqd:1;
+               uint64_t ic_bo:1;
+               uint64_t ic_suppl:15;
+               uint64_t ic_rsvd:27;
        } ii_icrb0_c_fld_s;
 } ii_icrb0_c_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
  * used for Crosstalk operations (both cacheline and partial            *
  * operations) or BTE/IO. Because the CRB entries are very wide, five   *
  * registers (_A to _E) are required to read and write each entry.      *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icrb0_d_u {
-       uint64_t        ii_icrb0_d_regval;
-       struct  {
-               uint64_t        id_pa_be                  :     43;
-               uint64_t        id_bte_op                 :      1;
-               uint64_t        id_pr_psc                 :      4;
-               uint64_t        id_pr_cnt                 :      4;
-               uint64_t        id_sleep                  :      1;
-               uint64_t        id_rsvd                   :     11;
+       uint64_t ii_icrb0_d_regval;
+       struct {
+               uint64_t id_pa_be:43;
+               uint64_t id_bte_op:1;
+               uint64_t id_pr_psc:4;
+               uint64_t id_pr_cnt:4;
+               uint64_t id_sleep:1;
+               uint64_t id_rsvd:11;
        } ii_icrb0_d_fld_s;
 } ii_icrb0_d_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
  * used for Crosstalk operations (both cacheline and partial            *
  * operations) or BTE/IO. Because the CRB entries are very wide, five   *
  * registers (_A to _E) are required to read and write each entry.      *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icrb0_e_u {
-       uint64_t        ii_icrb0_e_regval;
-       struct  {
-               uint64_t        ie_timeout                :      8;
-               uint64_t        ie_context                :     15;
-               uint64_t        ie_rsvd                   :      1;
-               uint64_t        ie_tvld                   :      1;
-               uint64_t        ie_cvld                   :      1;
-               uint64_t        ie_rsvd_0                 :     38;
+       uint64_t ii_icrb0_e_regval;
+       struct {
+               uint64_t ie_timeout:8;
+               uint64_t ie_context:15;
+               uint64_t ie_rsvd:1;
+               uint64_t ie_tvld:1;
+               uint64_t ie_cvld:1;
+               uint64_t ie_rsvd_0:38;
        } ii_icrb0_e_fld_s;
 } ii_icrb0_e_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the lower 64 bits of the header of the       *
  * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
  * register is set.                                                     *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icsml_u {
-       uint64_t        ii_icsml_regval;
-       struct  {
-               uint64_t        i_tt_addr                 :     47;
-               uint64_t        i_newsuppl_ex             :     14;
-               uint64_t        i_reserved                :      2;
-               uint64_t       i_overflow                :      1;
+       uint64_t ii_icsml_regval;
+       struct {
+               uint64_t i_tt_addr:47;
+               uint64_t i_newsuppl_ex:14;
+               uint64_t i_reserved:2;
+               uint64_t i_overflow:1;
        } ii_icsml_fld_s;
 } ii_icsml_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the middle 64 bits of the header of the      *
  * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
  * register is set.                                                     *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icsmm_u {
-       uint64_t        ii_icsmm_regval;
-       struct  {
-               uint64_t        i_tt_ack_cnt              :     11;
-               uint64_t        i_reserved                :     53;
+       uint64_t ii_icsmm_regval;
+       struct {
+               uint64_t i_tt_ack_cnt:11;
+               uint64_t i_reserved:53;
        } ii_icsmm_fld_s;
 } ii_icsmm_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the microscopic state, all the inputs to     *
  * the protocol table, captured with the spurious message. Valid when   *
  * the SP_MSG bit in the ICMR register is set.                          *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_icsmh_u {
-       uint64_t        ii_icsmh_regval;
-       struct  {
-               uint64_t        i_tt_vld                  :      1;
-               uint64_t        i_xerr                    :      1;
-               uint64_t        i_ft_cwact_o              :      1;
-               uint64_t        i_ft_wact_o               :      1;
-               uint64_t       i_ft_active_o             :      1;
-               uint64_t        i_sync                    :      1;
-               uint64_t        i_mnusg                   :      1;
-               uint64_t        i_mnusz                   :      1;
-               uint64_t        i_plusz                   :      1;
-               uint64_t        i_plusg                   :      1;
-               uint64_t        i_tt_exc                  :      5;
-               uint64_t        i_tt_wb                   :      1;
-               uint64_t        i_tt_hold                 :      1;
-               uint64_t        i_tt_ack                  :      1;
-               uint64_t        i_tt_resp                 :      1;
-               uint64_t        i_tt_intvn                :      1;
-               uint64_t        i_g_stall_bte1            :      1;
-               uint64_t        i_g_stall_bte0            :      1;
-               uint64_t        i_g_stall_il              :      1;
-               uint64_t        i_g_stall_ib              :      1;
-               uint64_t        i_tt_imsg                 :      8;
-               uint64_t        i_tt_imsgtype             :      2;
-               uint64_t        i_tt_use_old              :      1;
-               uint64_t        i_tt_respreqd             :      1;
-               uint64_t        i_tt_bte_num              :      1;
-               uint64_t        i_cbn                     :      1;
-               uint64_t        i_match                   :      1;
-               uint64_t        i_rpcnt_lt_34             :      1;
-               uint64_t        i_rpcnt_ge_34             :      1;
-               uint64_t        i_rpcnt_lt_18             :      1;
-               uint64_t        i_rpcnt_ge_18             :      1;
-               uint64_t       i_rpcnt_lt_2              :      1;
-               uint64_t        i_rpcnt_ge_2              :      1;
-               uint64_t        i_rqcnt_lt_18             :      1;
-               uint64_t        i_rqcnt_ge_18             :      1;
-               uint64_t        i_rqcnt_lt_2              :      1;
-               uint64_t        i_rqcnt_ge_2              :      1;
-               uint64_t        i_tt_device               :      7;
-               uint64_t        i_tt_init                 :      3;
-               uint64_t        i_reserved                :      5;
+       uint64_t ii_icsmh_regval;
+       struct {
+               uint64_t i_tt_vld:1;
+               uint64_t i_xerr:1;
+               uint64_t i_ft_cwact_o:1;
+               uint64_t i_ft_wact_o:1;
+               uint64_t i_ft_active_o:1;
+               uint64_t i_sync:1;
+               uint64_t i_mnusg:1;
+               uint64_t i_mnusz:1;
+               uint64_t i_plusz:1;
+               uint64_t i_plusg:1;
+               uint64_t i_tt_exc:5;
+               uint64_t i_tt_wb:1;
+               uint64_t i_tt_hold:1;
+               uint64_t i_tt_ack:1;
+               uint64_t i_tt_resp:1;
+               uint64_t i_tt_intvn:1;
+               uint64_t i_g_stall_bte1:1;
+               uint64_t i_g_stall_bte0:1;
+               uint64_t i_g_stall_il:1;
+               uint64_t i_g_stall_ib:1;
+               uint64_t i_tt_imsg:8;
+               uint64_t i_tt_imsgtype:2;
+               uint64_t i_tt_use_old:1;
+               uint64_t i_tt_respreqd:1;
+               uint64_t i_tt_bte_num:1;
+               uint64_t i_cbn:1;
+               uint64_t i_match:1;
+               uint64_t i_rpcnt_lt_34:1;
+               uint64_t i_rpcnt_ge_34:1;
+               uint64_t i_rpcnt_lt_18:1;
+               uint64_t i_rpcnt_ge_18:1;
+               uint64_t i_rpcnt_lt_2:1;
+               uint64_t i_rpcnt_ge_2:1;
+               uint64_t i_rqcnt_lt_18:1;
+               uint64_t i_rqcnt_ge_18:1;
+               uint64_t i_rqcnt_lt_2:1;
+               uint64_t i_rqcnt_ge_2:1;
+               uint64_t i_tt_device:7;
+               uint64_t i_tt_init:3;
+               uint64_t i_reserved:5;
        } ii_icsmh_fld_s;
 } ii_icsmh_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  The Shub DEBUG unit provides a 3-bit selection signal to the        *
  * II core and a 3-bit selection signal to the fsbclk domain in the II  *
  * wrapper.                                                             *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_idbss_u {
-       uint64_t        ii_idbss_regval;
-       struct  {
-               uint64_t        i_iioclk_core_submenu     :      3;
-               uint64_t        i_rsvd                    :      5;
-               uint64_t        i_fsbclk_wrapper_submenu  :      3;
-               uint64_t        i_rsvd_1                  :      5;
-               uint64_t        i_iioclk_menu             :      5;
-               uint64_t        i_rsvd_2                  :     43;
+       uint64_t ii_idbss_regval;
+       struct {
+               uint64_t i_iioclk_core_submenu:3;
+               uint64_t i_rsvd:5;
+               uint64_t i_fsbclk_wrapper_submenu:3;
+               uint64_t i_rsvd_1:5;
+               uint64_t i_iioclk_menu:5;
+               uint64_t i_rsvd_2:43;
        } ii_idbss_fld_s;
 } ii_idbss_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  This register is used to set up the length for a       *
  * transfer and then to monitor the progress of that transfer. This     *
  * register needs to be initialized before a transfer is started. A     *
@@ -2553,63 +2462,60 @@ typedef union ii_idbss_u {
  * transfer completes, hardware will clear the Busy bit. The length     *
  * field will also contain the number of cache lines left to be         *
  * transferred.                                                         *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibls0_u {
-       uint64_t        ii_ibls0_regval;
-       struct  {
-               uint64_t        i_length                  :     16;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_busy                    :      1;
-               uint64_t       i_rsvd                    :     43;
+       uint64_t ii_ibls0_regval;
+       struct {
+               uint64_t i_length:16;
+               uint64_t i_error:1;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_busy:1;
+               uint64_t i_rsvd:43;
        } ii_ibls0_fld_s;
 } ii_ibls0_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register should be loaded before a transfer is started. The    *
  * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
  * address as described in Section 1.3, Figure2 and Figure3. Since      *
  * the bottom 7 bits of the address are always taken to be zero, BTE    *
  * transfers are always cacheline-aligned.                              *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibsa0_u {
-       uint64_t        ii_ibsa0_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      7;
-               uint64_t        i_addr                    :     42;
-               uint64_t       i_rsvd                    :     15;
+       uint64_t ii_ibsa0_regval;
+       struct {
+               uint64_t i_rsvd_1:7;
+               uint64_t i_addr:42;
+               uint64_t i_rsvd:15;
        } ii_ibsa0_fld_s;
 } ii_ibsa0_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register should be loaded before a transfer is started. The    *
  * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
  * address as described in Section 1.3, Figure2 and Figure3. Since      *
  * the bottom 7 bits of the address are always taken to be zero, BTE    *
  * transfers are always cacheline-aligned.                              *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibda0_u {
-       uint64_t        ii_ibda0_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      7;
-               uint64_t        i_addr                    :     42;
-               uint64_t        i_rsvd                    :     15;
+       uint64_t ii_ibda0_regval;
+       struct {
+               uint64_t i_rsvd_1:7;
+               uint64_t i_addr:42;
+               uint64_t i_rsvd:15;
        } ii_ibda0_fld_s;
 } ii_ibda0_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  Writing to this register sets up the attributes of the transfer     *
  * and initiates the transfer operation. Reading this register has      *
  * the side effect of terminating any transfer in progress. Note:       *
@@ -2617,61 +2523,58 @@ typedef union ii_ibda0_u {
  * other BTE. If a BTE stream has to be stopped (due to error           *
  * handling for example), both BTE streams should be stopped and        *
  * their transfers discarded.                                           *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibct0_u {
-       uint64_t        ii_ibct0_regval;
-       struct  {
-               uint64_t        i_zerofill                :      1;
-               uint64_t        i_rsvd_2                  :      3;
-               uint64_t        i_notify                  :      1;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t       i_poison                  :      1;
-               uint64_t       i_rsvd                    :     55;
+       uint64_t ii_ibct0_regval;
+       struct {
+               uint64_t i_zerofill:1;
+               uint64_t i_rsvd_2:3;
+               uint64_t i_notify:1;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_poison:1;
+               uint64_t i_rsvd:55;
        } ii_ibct0_fld_s;
 } ii_ibct0_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the address to which the WINV is sent.       *
  * This address has to be cache line aligned.                           *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibna0_u {
-       uint64_t        ii_ibna0_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      7;
-               uint64_t        i_addr                    :     42;
-               uint64_t        i_rsvd                    :     15;
+       uint64_t ii_ibna0_regval;
+       struct {
+               uint64_t i_rsvd_1:7;
+               uint64_t i_addr:42;
+               uint64_t i_rsvd:15;
        } ii_ibna0_fld_s;
 } ii_ibna0_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the programmable level as well as the node   *
  * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                                *
- *                                                                      *
+ * sent.                                                               *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibia0_u {
-       uint64_t        ii_ibia0_regval;
-       struct  {
-               uint64_t        i_rsvd_2                   :     1;
-               uint64_t        i_node_id                 :     11;
-               uint64_t        i_rsvd_1                  :      4;
-               uint64_t        i_level                   :      7;
-               uint64_t       i_rsvd                    :     41;
+       uint64_t ii_ibia0_regval;
+       struct {
+               uint64_t i_rsvd_2:1;
+               uint64_t i_node_id:11;
+               uint64_t i_rsvd_1:4;
+               uint64_t i_level:7;
+               uint64_t i_rsvd:41;
        } ii_ibia0_fld_s;
 } ii_ibia0_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  * Description:  This register is used to set up the length for a       *
  * transfer and then to monitor the progress of that transfer. This     *
  * register needs to be initialized before a transfer is started. A     *
@@ -2682,63 +2585,60 @@ typedef union ii_ibia0_u {
  * transfer completes, hardware will clear the Busy bit. The length     *
  * field will also contain the number of cache lines left to be         *
  * transferred.                                                         *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibls1_u {
-       uint64_t        ii_ibls1_regval;
-       struct  {
-               uint64_t        i_length                  :     16;
-               uint64_t        i_error                   :      1;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_busy                    :      1;
-               uint64_t       i_rsvd                    :     43;
+       uint64_t ii_ibls1_regval;
+       struct {
+               uint64_t i_length:16;
+               uint64_t i_error:1;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_busy:1;
+               uint64_t i_rsvd:43;
        } ii_ibls1_fld_s;
 } ii_ibls1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register should be loaded before a transfer is started. The    *
  * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
  * address as described in Section 1.3, Figure2 and Figure3. Since      *
  * the bottom 7 bits of the address are always taken to be zero, BTE    *
  * transfers are always cacheline-aligned.                              *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibsa1_u {
-       uint64_t        ii_ibsa1_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      7;
-               uint64_t        i_addr                    :     33;
-               uint64_t        i_rsvd                    :     24;
+       uint64_t ii_ibsa1_regval;
+       struct {
+               uint64_t i_rsvd_1:7;
+               uint64_t i_addr:33;
+               uint64_t i_rsvd:24;
        } ii_ibsa1_fld_s;
 } ii_ibsa1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register should be loaded before a transfer is started. The    *
  * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
  * address as described in Section 1.3, Figure2 and Figure3. Since      *
  * the bottom 7 bits of the address are always taken to be zero, BTE    *
  * transfers are always cacheline-aligned.                              *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibda1_u {
-       uint64_t        ii_ibda1_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      7;
-               uint64_t        i_addr                    :     33;
-               uint64_t        i_rsvd                    :     24;
+       uint64_t ii_ibda1_regval;
+       struct {
+               uint64_t i_rsvd_1:7;
+               uint64_t i_addr:33;
+               uint64_t i_rsvd:24;
        } ii_ibda1_fld_s;
 } ii_ibda1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  Writing to this register sets up the attributes of the transfer     *
  * and initiates the transfer operation. Reading this register has      *
  * the side effect of terminating any transfer in progress. Note:       *
@@ -2746,61 +2646,58 @@ typedef union ii_ibda1_u {
  * other BTE. If a BTE stream has to be stopped (due to error           *
  * handling for example), both BTE streams should be stopped and        *
  * their transfers discarded.                                           *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibct1_u {
-       uint64_t        ii_ibct1_regval;
-       struct  {
-               uint64_t        i_zerofill                :      1;
-               uint64_t        i_rsvd_2                  :      3;
-               uint64_t        i_notify                  :      1;
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_poison                  :      1;
-               uint64_t        i_rsvd                    :     55;
+       uint64_t ii_ibct1_regval;
+       struct {
+               uint64_t i_zerofill:1;
+               uint64_t i_rsvd_2:3;
+               uint64_t i_notify:1;
+               uint64_t i_rsvd_1:3;
+               uint64_t i_poison:1;
+               uint64_t i_rsvd:55;
        } ii_ibct1_fld_s;
 } ii_ibct1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the address to which the WINV is sent.       *
  * This address has to be cache line aligned.                           *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibna1_u {
-       uint64_t        ii_ibna1_regval;
-       struct  {
-               uint64_t        i_rsvd_1                  :      7;
-               uint64_t        i_addr                    :     33;
-               uint64_t       i_rsvd                    :     24;
+       uint64_t ii_ibna1_regval;
+       struct {
+               uint64_t i_rsvd_1:7;
+               uint64_t i_addr:33;
+               uint64_t i_rsvd:24;
        } ii_ibna1_fld_s;
 } ii_ibna1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register contains the programmable level as well as the node   *
  * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                                *
- *                                                                      *
+ * sent.                                                               *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ibia1_u {
-       uint64_t        ii_ibia1_regval;
-       struct  {
-               uint64_t        i_pi_id                   :      1;
-               uint64_t        i_node_id                 :      8;
-               uint64_t        i_rsvd_1                  :      7;
-               uint64_t        i_level                   :      7;
-               uint64_t        i_rsvd                    :     41;
+       uint64_t ii_ibia1_regval;
+       struct {
+               uint64_t i_pi_id:1;
+               uint64_t i_node_id:8;
+               uint64_t i_rsvd_1:7;
+               uint64_t i_level:7;
+               uint64_t i_rsvd:41;
        } ii_ibia1_fld_s;
 } ii_ibia1_u_t;
 
-
 /************************************************************************
- *                                                                      *
+ *                                                                     *
  *  This register defines the resources that feed information into      *
  * the two performance counters located in the IO Performance           *
  * Profiling Register. There are 17 different quantities that can be    *
@@ -2811,133 +2708,129 @@ typedef union ii_ibia1_u {
  * other is available from the other performance counter. Hence, the    *
  * II supports all 17*16=272 possible combinations of quantities to     *
  * measure.                                                             *
- *                                                                      *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ipcr_u {
-       uint64_t        ii_ipcr_regval;
-       struct  {
-               uint64_t        i_ippr0_c                 :      4;
-               uint64_t        i_ippr1_c                 :      4;
-               uint64_t        i_icct                    :      8;
-               uint64_t       i_rsvd                    :     48;
+       uint64_t ii_ipcr_regval;
+       struct {
+               uint64_t i_ippr0_c:4;
+               uint64_t i_ippr1_c:4;
+               uint64_t i_icct:8;
+               uint64_t i_rsvd:48;
        } ii_ipcr_fld_s;
 } ii_ipcr_u_t;
 
-
 /************************************************************************
- *                                                                      *
- *                                                                      *
- *                                                                      *
+ *                                                                     *
+ *                                                                     *
+ *                                                                     *
  ************************************************************************/
 
 typedef union ii_ippr_u {
-       uint64_t        ii_ippr_regval;
-       struct  {
-               uint64_t        i_ippr0                   :     32;
-               uint64_t        i_ippr1                   :     32;
+       uint64_t ii_ippr_regval;
+       struct {
+               uint64_t i_ippr0:32;
+               uint64_t i_ippr1:32;
        } ii_ippr_fld_s;
 } ii_ippr_u_t;
 
-
-
-/**************************************************************************
- *                                                                        *
- * The following defines which were not formed into structures are        *
- * probably indentical to another register, and the name of the           *
- * register is provided against each of these registers. This             *
- * information needs to be checked carefully                              *
- *                                                                        *
- *           IIO_ICRB1_A                IIO_ICRB0_A                       *
- *           IIO_ICRB1_B                IIO_ICRB0_B                       *
- *           IIO_ICRB1_C                IIO_ICRB0_C                       *
- *           IIO_ICRB1_D                IIO_ICRB0_D                       *
- *           IIO_ICRB1_E                IIO_ICRB0_E                       *
- *           IIO_ICRB2_A                IIO_ICRB0_A                       *
- *           IIO_ICRB2_B                IIO_ICRB0_B                       *
- *           IIO_ICRB2_C                IIO_ICRB0_C                       *
- *           IIO_ICRB2_D                IIO_ICRB0_D                       *
- *           IIO_ICRB2_E                IIO_ICRB0_E                       *
- *           IIO_ICRB3_A                IIO_ICRB0_A                       *
- *           IIO_ICRB3_B                IIO_ICRB0_B                       *
- *           IIO_ICRB3_C                IIO_ICRB0_C                       *
- *           IIO_ICRB3_D                IIO_ICRB0_D                       *
- *           IIO_ICRB3_E                IIO_ICRB0_E                       *
- *           IIO_ICRB4_A                IIO_ICRB0_A                       *
- *           IIO_ICRB4_B                IIO_ICRB0_B                       *
- *           IIO_ICRB4_C                IIO_ICRB0_C                       *
- *           IIO_ICRB4_D                IIO_ICRB0_D                       *
- *           IIO_ICRB4_E                IIO_ICRB0_E                       *
- *           IIO_ICRB5_A                IIO_ICRB0_A                       *
- *           IIO_ICRB5_B                IIO_ICRB0_B                       *
- *           IIO_ICRB5_C                IIO_ICRB0_C                       *
- *           IIO_ICRB5_D                IIO_ICRB0_D                       *
- *           IIO_ICRB5_E                IIO_ICRB0_E                       *
- *           IIO_ICRB6_A                IIO_ICRB0_A                       *
- *           IIO_ICRB6_B                IIO_ICRB0_B                       *
- *           IIO_ICRB6_C                IIO_ICRB0_C                       *
- *           IIO_ICRB6_D                IIO_ICRB0_D                       *
- *           IIO_ICRB6_E                IIO_ICRB0_E                       *
- *           IIO_ICRB7_A                IIO_ICRB0_A                       *
- *           IIO_ICRB7_B                IIO_ICRB0_B                       *
- *           IIO_ICRB7_C                IIO_ICRB0_C                       *
- *           IIO_ICRB7_D                IIO_ICRB0_D                       *
- *           IIO_ICRB7_E                IIO_ICRB0_E                       *
- *           IIO_ICRB8_A                IIO_ICRB0_A                       *
- *           IIO_ICRB8_B                IIO_ICRB0_B                       *
- *           IIO_ICRB8_C                IIO_ICRB0_C                       *
- *           IIO_ICRB8_D                IIO_ICRB0_D                       *
- *           IIO_ICRB8_E                IIO_ICRB0_E                       *
- *           IIO_ICRB9_A                IIO_ICRB0_A                       *
- *           IIO_ICRB9_B                IIO_ICRB0_B                       *
- *           IIO_ICRB9_C                IIO_ICRB0_C                       *
- *           IIO_ICRB9_D                IIO_ICRB0_D                       *
- *           IIO_ICRB9_E                IIO_ICRB0_E                       *
- *           IIO_ICRBA_A                IIO_ICRB0_A                       *
- *           IIO_ICRBA_B                IIO_ICRB0_B                       *
- *           IIO_ICRBA_C                IIO_ICRB0_C                       *
- *           IIO_ICRBA_D                IIO_ICRB0_D                       *
- *           IIO_ICRBA_E                IIO_ICRB0_E                       *
- *           IIO_ICRBB_A                IIO_ICRB0_A                       *
- *           IIO_ICRBB_B                IIO_ICRB0_B                       *
- *           IIO_ICRBB_C                IIO_ICRB0_C                       *
- *           IIO_ICRBB_D                IIO_ICRB0_D                       *
- *           IIO_ICRBB_E                IIO_ICRB0_E                       *
- *           IIO_ICRBC_A                IIO_ICRB0_A                       *
- *           IIO_ICRBC_B                IIO_ICRB0_B                       *
- *           IIO_ICRBC_C                IIO_ICRB0_C                       *
- *           IIO_ICRBC_D                IIO_ICRB0_D                       *
- *           IIO_ICRBC_E                IIO_ICRB0_E                       *
- *           IIO_ICRBD_A                IIO_ICRB0_A                       *
- *           IIO_ICRBD_B                IIO_ICRB0_B                       *
- *           IIO_ICRBD_C                IIO_ICRB0_C                       *
- *           IIO_ICRBD_D                IIO_ICRB0_D                       *
- *           IIO_ICRBD_E                IIO_ICRB0_E                       *
- *           IIO_ICRBE_A                IIO_ICRB0_A                       *
- *           IIO_ICRBE_B                IIO_ICRB0_B                       *
- *           IIO_ICRBE_C                IIO_ICRB0_C                       *
- *           IIO_ICRBE_D                IIO_ICRB0_D                       *
- *           IIO_ICRBE_E                IIO_ICRB0_E                       *
- *                                                                        *
- **************************************************************************/
-
+/************************************************************************
+ *                                                                     *
+ * The following defines which were not formed into structures are     *
+ * probably indentical to another register, and the name of the                *
+ * register is provided against each of these registers. This          *
+ * information needs to be checked carefully                           *
+ *                                                                     *
+ *             IIO_ICRB1_A             IIO_ICRB0_A                     *
+ *             IIO_ICRB1_B             IIO_ICRB0_B                     *
+ *             IIO_ICRB1_C             IIO_ICRB0_C                     *
+ *             IIO_ICRB1_D             IIO_ICRB0_D                     *
+ *             IIO_ICRB1_E             IIO_ICRB0_E                     *
+ *             IIO_ICRB2_A             IIO_ICRB0_A                     *
+ *             IIO_ICRB2_B             IIO_ICRB0_B                     *
+ *             IIO_ICRB2_C             IIO_ICRB0_C                     *
+ *             IIO_ICRB2_D             IIO_ICRB0_D                     *
+ *             IIO_ICRB2_E             IIO_ICRB0_E                     *
+ *             IIO_ICRB3_A             IIO_ICRB0_A                     *
+ *             IIO_ICRB3_B             IIO_ICRB0_B                     *
+ *             IIO_ICRB3_C             IIO_ICRB0_C                     *
+ *             IIO_ICRB3_D             IIO_ICRB0_D                     *
+ *             IIO_ICRB3_E             IIO_ICRB0_E                     *
+ *             IIO_ICRB4_A             IIO_ICRB0_A                     *
+ *             IIO_ICRB4_B             IIO_ICRB0_B                     *
+ *             IIO_ICRB4_C             IIO_ICRB0_C                     *
+ *             IIO_ICRB4_D             IIO_ICRB0_D                     *
+ *             IIO_ICRB4_E             IIO_ICRB0_E                     *
+ *             IIO_ICRB5_A             IIO_ICRB0_A                     *
+ *             IIO_ICRB5_B             IIO_ICRB0_B                     *
+ *             IIO_ICRB5_C             IIO_ICRB0_C                     *
+ *             IIO_ICRB5_D             IIO_ICRB0_D                     *
+ *             IIO_ICRB5_E             IIO_ICRB0_E                     *
+ *             IIO_ICRB6_A             IIO_ICRB0_A                     *
+ *             IIO_ICRB6_B             IIO_ICRB0_B                     *
+ *             IIO_ICRB6_C             IIO_ICRB0_C                     *
+ *             IIO_ICRB6_D             IIO_ICRB0_D                     *
+ *             IIO_ICRB6_E             IIO_ICRB0_E                     *
+ *             IIO_ICRB7_A             IIO_ICRB0_A                     *
+ *             IIO_ICRB7_B             IIO_ICRB0_B                     *
+ *             IIO_ICRB7_C             IIO_ICRB0_C                     *
+ *             IIO_ICRB7_D             IIO_ICRB0_D                     *
+ *             IIO_ICRB7_E             IIO_ICRB0_E                     *
+ *             IIO_ICRB8_A             IIO_ICRB0_A                     *
+ *             IIO_ICRB8_B             IIO_ICRB0_B                     *
+ *             IIO_ICRB8_C             IIO_ICRB0_C                     *
+ *             IIO_ICRB8_D             IIO_ICRB0_D                     *
+ *             IIO_ICRB8_E             IIO_ICRB0_E                     *
+ *             IIO_ICRB9_A             IIO_ICRB0_A                     *
+ *             IIO_ICRB9_B             IIO_ICRB0_B                     *
+ *             IIO_ICRB9_C             IIO_ICRB0_C                     *
+ *             IIO_ICRB9_D             IIO_ICRB0_D                     *
+ *             IIO_ICRB9_E             IIO_ICRB0_E                     *
+ *             IIO_ICRBA_A             IIO_ICRB0_A                     *
+ *             IIO_ICRBA_B             IIO_ICRB0_B                     *
+ *             IIO_ICRBA_C             IIO_ICRB0_C                     *
+ *             IIO_ICRBA_D             IIO_ICRB0_D                     *
+ *             IIO_ICRBA_E             IIO_ICRB0_E                     *
+ *             IIO_ICRBB_A             IIO_ICRB0_A                     *
+ *             IIO_ICRBB_B             IIO_ICRB0_B                     *
+ *             IIO_ICRBB_C             IIO_ICRB0_C                     *
+ *             IIO_ICRBB_D             IIO_ICRB0_D                     *
+ *             IIO_ICRBB_E             IIO_ICRB0_E                     *
+ *             IIO_ICRBC_A             IIO_ICRB0_A                     *
+ *             IIO_ICRBC_B             IIO_ICRB0_B                     *
+ *             IIO_ICRBC_C             IIO_ICRB0_C                     *
+ *             IIO_ICRBC_D             IIO_ICRB0_D                     *
+ *             IIO_ICRBC_E             IIO_ICRB0_E                     *
+ *             IIO_ICRBD_A             IIO_ICRB0_A                     *
+ *             IIO_ICRBD_B             IIO_ICRB0_B                     *
+ *             IIO_ICRBD_C             IIO_ICRB0_C                     *
+ *             IIO_ICRBD_D             IIO_ICRB0_D                     *
+ *             IIO_ICRBD_E             IIO_ICRB0_E                     *
+ *             IIO_ICRBE_A             IIO_ICRB0_A                     *
+ *             IIO_ICRBE_B             IIO_ICRB0_B                     *
+ *             IIO_ICRBE_C             IIO_ICRB0_C                     *
+ *             IIO_ICRBE_D             IIO_ICRB0_D                     *
+ *             IIO_ICRBE_E             IIO_ICRB0_E                     *
+ *                                                                     *
+ ************************************************************************/
 
 /*
  * Slightly friendlier names for some common registers.
  */
-#define IIO_WIDGET              IIO_WID      /* Widget identification */
-#define IIO_WIDGET_STAT         IIO_WSTAT    /* Widget status register */
-#define IIO_WIDGET_CTRL         IIO_WCR      /* Widget control register */
-#define IIO_PROTECT             IIO_ILAPR    /* IO interface protection */
-#define IIO_PROTECT_OVRRD       IIO_ILAPO    /* IO protect override */
-#define IIO_OUTWIDGET_ACCESS    IIO_IOWA     /* Outbound widget access */
-#define IIO_INWIDGET_ACCESS     IIO_IIWA     /* Inbound widget access */
-#define IIO_INDEV_ERR_MASK      IIO_IIDEM    /* Inbound device error mask */
-#define IIO_LLP_CSR             IIO_ILCSR    /* LLP control and status */
-#define IIO_LLP_LOG             IIO_ILLR     /* LLP log */
-#define IIO_XTALKCC_TOUT        IIO_IXCC     /* Xtalk credit count timeout*/
-#define IIO_XTALKTT_TOUT        IIO_IXTT     /* Xtalk tail timeout */
-#define IIO_IO_ERR_CLR          IIO_IECLR    /* IO error clear */
+#define IIO_WIDGET              IIO_WID                /* Widget identification */
+#define IIO_WIDGET_STAT         IIO_WSTAT      /* Widget status register */
+#define IIO_WIDGET_CTRL         IIO_WCR                /* Widget control register */
+#define IIO_PROTECT             IIO_ILAPR      /* IO interface protection */
+#define IIO_PROTECT_OVRRD       IIO_ILAPO      /* IO protect override */
+#define IIO_OUTWIDGET_ACCESS    IIO_IOWA       /* Outbound widget access */
+#define IIO_INWIDGET_ACCESS     IIO_IIWA       /* Inbound widget access */
+#define IIO_INDEV_ERR_MASK      IIO_IIDEM      /* Inbound device error mask */
+#define IIO_LLP_CSR             IIO_ILCSR      /* LLP control and status */
+#define IIO_LLP_LOG             IIO_ILLR       /* LLP log */
+#define IIO_XTALKCC_TOUT        IIO_IXCC       /* Xtalk credit count timeout */
+#define IIO_XTALKTT_TOUT        IIO_IXTT       /* Xtalk tail timeout */
+#define IIO_IO_ERR_CLR          IIO_IECLR      /* IO error clear */
 #define IIO_IGFX_0             IIO_IGFX0
 #define IIO_IGFX_1             IIO_IGFX1
 #define IIO_IBCT_0             IIO_IBCT0
@@ -2957,12 +2850,12 @@ typedef union ii_ippr_u {
 #define IIO_PRTE_A(_x)         (IIO_IPRTE0_A + (8 * (_x)))
 #define IIO_PRTE_B(_x)         (IIO_IPRTE0_B + (8 * (_x)))
 #define IIO_NUM_PRTES          8       /* Total number of PRB table entries */
-#define IIO_WIDPRTE_A(x)       IIO_PRTE_A(((x) - 8)) /* widget ID to its PRTE num */
-#define IIO_WIDPRTE_B(x)       IIO_PRTE_B(((x) - 8)) /* widget ID to its PRTE num */
+#define IIO_WIDPRTE_A(x)       IIO_PRTE_A(((x) - 8))   /* widget ID to its PRTE num */
+#define IIO_WIDPRTE_B(x)       IIO_PRTE_B(((x) - 8))   /* widget ID to its PRTE num */
 
-#define IIO_NUM_IPRBS          (9) 
+#define IIO_NUM_IPRBS          9
 
-#define IIO_LLP_CSR_IS_UP               0x00002000
+#define IIO_LLP_CSR_IS_UP              0x00002000
 #define IIO_LLP_CSR_LLP_STAT_MASK       0x00003000
 #define IIO_LLP_CSR_LLP_STAT_SHFT       12
 
@@ -2970,30 +2863,29 @@ typedef union ii_ippr_u {
 #define IIO_LLP_SN_MAX  0xffff /* in ILLR SN_CNT, Max Sequence Number errors */
 
 /* key to IIO_PROTECT_OVRRD */
-#define IIO_PROTECT_OVRRD_KEY   0x53474972756c6573ull   /* "SGIrules" */
+#define IIO_PROTECT_OVRRD_KEY   0x53474972756c6573ull  /* "SGIrules" */
 
 /* BTE register names */
-#define IIO_BTE_STAT_0          IIO_IBLS_0   /* Also BTE length/status 0 */
-#define IIO_BTE_SRC_0           IIO_IBSA_0   /* Also BTE source address  0 */
-#define IIO_BTE_DEST_0          IIO_IBDA_0   /* Also BTE dest. address 0 */
-#define IIO_BTE_CTRL_0          IIO_IBCT_0   /* Also BTE control/terminate 0 */
-#define IIO_BTE_NOTIFY_0        IIO_IBNA_0   /* Also BTE notification 0 */
-#define IIO_BTE_INT_0           IIO_IBIA_0   /* Also BTE interrupt 0 */
-#define IIO_BTE_OFF_0           0            /* Base offset from BTE 0 regs. */
-#define IIO_BTE_OFF_1          (IIO_IBLS_1 - IIO_IBLS_0) /* Offset from base to BTE 1 */
+#define IIO_BTE_STAT_0          IIO_IBLS_0     /* Also BTE length/status 0 */
+#define IIO_BTE_SRC_0           IIO_IBSA_0     /* Also BTE source address  0 */
+#define IIO_BTE_DEST_0          IIO_IBDA_0     /* Also BTE dest. address 0 */
+#define IIO_BTE_CTRL_0          IIO_IBCT_0     /* Also BTE control/terminate 0 */
+#define IIO_BTE_NOTIFY_0        IIO_IBNA_0     /* Also BTE notification 0 */
+#define IIO_BTE_INT_0           IIO_IBIA_0     /* Also BTE interrupt 0 */
+#define IIO_BTE_OFF_0           0      /* Base offset from BTE 0 regs. */
+#define IIO_BTE_OFF_1          (IIO_IBLS_1 - IIO_IBLS_0)       /* Offset from base to BTE 1 */
 
 /* BTE register offsets from base */
 #define BTEOFF_STAT             0
-#define BTEOFF_SRC              (IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
-#define BTEOFF_DEST             (IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
-#define BTEOFF_CTRL             (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
-#define BTEOFF_NOTIFY           (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
-#define BTEOFF_INT              (IIO_BTE_INT_0 - IIO_BTE_STAT_0)
-
+#define BTEOFF_SRC             (IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
+#define BTEOFF_DEST            (IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
+#define BTEOFF_CTRL            (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
+#define BTEOFF_NOTIFY          (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
+#define BTEOFF_INT             (IIO_BTE_INT_0 - IIO_BTE_STAT_0)
 
 /* names used in shub diags */
-#define IIO_BASE_BTE0   IIO_IBLS_0             
-#define IIO_BASE_BTE1   IIO_IBLS_1             
+#define IIO_BASE_BTE0   IIO_IBLS_0
+#define IIO_BASE_BTE1   IIO_IBLS_1
 
 /*
  * Macro which takes the widget number, and returns the
@@ -3001,10 +2893,9 @@ typedef union ii_ippr_u {
  * value _x is expected to be a widget number in the range
  * 0, 8 - 0xF
  */
-#define IIO_IOPRB(_x)   (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
-                        (_x) : \
-                        (_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
-
+#define IIO_IOPRB(_x)  (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
+                       (_x) : \
+                       (_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
 
 /* GFX Flow Control Node/Widget Register */
 #define IIO_IGFX_W_NUM_BITS    4       /* size of widget num field */
@@ -3025,7 +2916,6 @@ typedef union ii_ippr_u {
        (((node)   & IIO_IGFX_N_NUM_MASK) << IIO_IGFX_N_NUM_SHIFT) |     \
        (((cpu)    & IIO_IGFX_P_NUM_MASK) << IIO_IGFX_P_NUM_SHIFT))
 
-
 /* Scratch registers (all bits available) */
 #define IIO_SCRATCH_REG0        IIO_ISCR0
 #define IIO_SCRATCH_REG1        IIO_ISCR1
@@ -3046,21 +2936,21 @@ typedef union ii_ippr_u {
 #define IIO_SCRATCH_BIT1_0      0x0000000000000001UL
 #define IIO_SCRATCH_BIT1_1      0x0000000000000002UL
 /* IO Translation Table Entries */
-#define IIO_NUM_ITTES   7               /* ITTEs numbered 0..6 */
-                                        /* Hw manuals number them 1..7! */
+#define IIO_NUM_ITTES   7      /* ITTEs numbered 0..6 */
+                                       /* Hw manuals number them 1..7! */
 /*
  * IIO_IMEM Register fields.
  */
-#define IIO_IMEM_W0ESD  0x1UL             /* Widget 0 shut down due to error */
-#define IIO_IMEM_B0ESD  (1UL << 4)        /* BTE 0 shut down due to error */
-#define IIO_IMEM_B1ESD  (1UL << 8)        /* BTE 1 Shut down due to error */
+#define IIO_IMEM_W0ESD  0x1UL  /* Widget 0 shut down due to error */
+#define IIO_IMEM_B0ESD (1UL << 4)      /* BTE 0 shut down due to error */
+#define IIO_IMEM_B1ESD (1UL << 8)      /* BTE 1 Shut down due to error */
 
 /*
  * As a permanent workaround for a bug in the PI side of the shub, we've
  * redefined big window 7 as small window 0.
  XXX does this still apply for SN1??
  */
-#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
+#define HUB_NUM_BIG_WINDOW     (IIO_NUM_ITTES - 1)
 
 /*
  * Use the top big window as a surrogate for the first small window
@@ -3071,11 +2961,11 @@ typedef union ii_ippr_u {
 
 /*
  * CRB manipulation macros
- *      The CRB macros are slightly complicated, since there are up to
- *      four registers associated with each CRB entry.
+ *     The CRB macros are slightly complicated, since there are up to
+ *     four registers associated with each CRB entry.
  */
-#define IIO_NUM_CRBS            15      /* Number of CRBs */
-#define IIO_NUM_PC_CRBS         4       /* Number of partial cache CRBs */
+#define IIO_NUM_CRBS            15     /* Number of CRBs */
+#define IIO_NUM_PC_CRBS         4      /* Number of partial cache CRBs */
 #define IIO_ICRB_OFFSET         8
 #define IIO_ICRB_0              IIO_ICRB0_A
 #define IIO_ICRB_ADDR_SHFT     2       /* Shift to get proper address */
@@ -3083,43 +2973,43 @@ typedef union ii_ippr_u {
         #define IIO_FIRST_PC_ENTRY 12
  */
 
-#define IIO_ICRB_A(_x)  ((u64)(IIO_ICRB_0 + (6 * IIO_ICRB_OFFSET * (_x))))
-#define IIO_ICRB_B(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET))
-#define IIO_ICRB_C(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET))
-#define IIO_ICRB_D(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET))
-#define IIO_ICRB_E(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 4*IIO_ICRB_OFFSET))
+#define IIO_ICRB_A(_x) ((u64)(IIO_ICRB_0 + (6 * IIO_ICRB_OFFSET * (_x))))
+#define IIO_ICRB_B(_x) ((u64)((char *)IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET))
+#define IIO_ICRB_C(_x) ((u64)((char *)IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET))
+#define IIO_ICRB_D(_x) ((u64)((char *)IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET))
+#define IIO_ICRB_E(_x) ((u64)((char *)IIO_ICRB_A(_x) + 4*IIO_ICRB_OFFSET))
 
 #define TNUM_TO_WIDGET_DEV(_tnum)      (_tnum & 0x7)
 
 /*
  * values for "ecode" field
  */
-#define IIO_ICRB_ECODE_DERR     0       /* Directory error due to IIO access */
-#define IIO_ICRB_ECODE_PERR     1       /* Poison error on IO access */
-#define IIO_ICRB_ECODE_WERR     2       /* Write error by IIO access
-                                         * e.g. WINV to a Read only line. */
-#define IIO_ICRB_ECODE_AERR     3       /* Access error caused by IIO access */
-#define IIO_ICRB_ECODE_PWERR    4       /* Error on partial write       */
-#define IIO_ICRB_ECODE_PRERR    5       /* Error on partial read        */
-#define IIO_ICRB_ECODE_TOUT     6       /* CRB timeout before deallocating */
-#define IIO_ICRB_ECODE_XTERR    7       /* Incoming xtalk pkt had error bit */
+#define IIO_ICRB_ECODE_DERR     0      /* Directory error due to IIO access */
+#define IIO_ICRB_ECODE_PERR     1      /* Poison error on IO access */
+#define IIO_ICRB_ECODE_WERR     2      /* Write error by IIO access
+                                        * e.g. WINV to a Read only line. */
+#define IIO_ICRB_ECODE_AERR     3      /* Access error caused by IIO access */
+#define IIO_ICRB_ECODE_PWERR    4      /* Error on partial write */
+#define IIO_ICRB_ECODE_PRERR    5      /* Error on partial read  */
+#define IIO_ICRB_ECODE_TOUT     6      /* CRB timeout before deallocating */
+#define IIO_ICRB_ECODE_XTERR    7      /* Incoming xtalk pkt had error bit */
 
 /*
  * Values for field imsgtype
  */
-#define IIO_ICRB_IMSGT_XTALK    0       /* Incoming Meessage from Xtalk */
-#define IIO_ICRB_IMSGT_BTE      1       /* Incoming message from BTE    */
-#define IIO_ICRB_IMSGT_SN1NET   2       /* Incoming message from SN1 net */
-#define IIO_ICRB_IMSGT_CRB      3       /* Incoming message from CRB ???  */
+#define IIO_ICRB_IMSGT_XTALK    0      /* Incoming Meessage from Xtalk */
+#define IIO_ICRB_IMSGT_BTE      1      /* Incoming message from BTE    */
+#define IIO_ICRB_IMSGT_SN1NET   2      /* Incoming message from SN1 net */
+#define IIO_ICRB_IMSGT_CRB      3      /* Incoming message from CRB ???  */
 
 /*
  * values for field initiator.
  */
-#define IIO_ICRB_INIT_XTALK     0       /* Message originated in xtalk  */
-#define IIO_ICRB_INIT_BTE0      0x1     /* Message originated in BTE 0  */
-#define IIO_ICRB_INIT_SN1NET    0x2     /* Message originated in SN1net */
-#define IIO_ICRB_INIT_CRB       0x3     /* Message originated in CRB ?  */
-#define IIO_ICRB_INIT_BTE1      0x5     /* MEssage originated in BTE 1  */
+#define IIO_ICRB_INIT_XTALK     0      /* Message originated in xtalk  */
+#define IIO_ICRB_INIT_BTE0      0x1    /* Message originated in BTE 0  */
+#define IIO_ICRB_INIT_SN1NET    0x2    /* Message originated in SN1net */
+#define IIO_ICRB_INIT_CRB       0x3    /* Message originated in CRB ?  */
+#define IIO_ICRB_INIT_BTE1      0x5    /* MEssage originated in BTE 1  */
 
 /*
  * Number of credits Hub widget has while sending req/response to
@@ -3127,8 +3017,8 @@ typedef union ii_ippr_u {
  * Value of 3 is required by Xbow 1.1
  * We may be able to increase this to 4 with Xbow 1.2.
  */
-#define       HUBII_XBOW_CREDIT       3
-#define       HUBII_XBOW_REV2_CREDIT  4
+#define                   HUBII_XBOW_CREDIT       3
+#define                   HUBII_XBOW_REV2_CREDIT  4
 
 /*
  * Number of credits that xtalk devices should use when communicating
@@ -3159,28 +3049,28 @@ typedef union ii_ippr_u {
  */
 
 #define IIO_ICMR_CRB_VLD_SHFT   20
-#define IIO_ICMR_CRB_VLD_MASK   (0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
+#define IIO_ICMR_CRB_VLD_MASK  (0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
 
 #define IIO_ICMR_FC_CNT_SHFT    16
-#define IIO_ICMR_FC_CNT_MASK    (0xf << IIO_ICMR_FC_CNT_SHFT)
+#define IIO_ICMR_FC_CNT_MASK   (0xf << IIO_ICMR_FC_CNT_SHFT)
 
 #define IIO_ICMR_C_CNT_SHFT     4
-#define IIO_ICMR_C_CNT_MASK     (0xf << IIO_ICMR_C_CNT_SHFT)
+#define IIO_ICMR_C_CNT_MASK    (0xf << IIO_ICMR_C_CNT_SHFT)
 
-#define IIO_ICMR_PRECISE        (1UL << 52)
-#define IIO_ICMR_CLR_RPPD       (1UL << 13)
-#define IIO_ICMR_CLR_RQPD       (1UL << 12)
+#define IIO_ICMR_PRECISE       (1UL << 52)
+#define IIO_ICMR_CLR_RPPD      (1UL << 13)
+#define IIO_ICMR_CLR_RQPD      (1UL << 12)
 
 /*
  * IIO PIO Deallocation register field masks : (IIO_IPDR)
  XXX present but not needed in bedrock?  See the manual.
  */
-#define IIO_IPDR_PND    (1 << 4)
+#define IIO_IPDR_PND           (1 << 4)
 
 /*
  * IIO CRB deallocation register field masks: (IIO_ICDR)
  */
-#define IIO_ICDR_PND    (1 << 4)
+#define IIO_ICDR_PND           (1 << 4)
 
 /* 
  * IO BTE Length/Status (IIO_IBLS) register bit field definitions
@@ -3223,35 +3113,35 @@ typedef union ii_ippr_u {
 /*
  * IO Error Clear register bit field definitions
  */
-#define IECLR_PI1_FWD_INT      (1UL << 31)  /* clear PI1_FORWARD_INT in iidsr */
-#define IECLR_PI0_FWD_INT      (1UL << 30)  /* clear PI0_FORWARD_INT in iidsr */
-#define IECLR_SPUR_RD_HDR      (1UL << 29)  /* clear valid bit in ixss reg */
-#define IECLR_BTE1             (1UL << 18)  /* clear bte error 1 */
-#define IECLR_BTE0             (1UL << 17)  /* clear bte error 0 */
-#define IECLR_CRAZY            (1UL << 16)  /* clear crazy bit in wstat reg */
-#define IECLR_PRB_F            (1UL << 15)  /* clear err bit in PRB_F reg */
-#define IECLR_PRB_E            (1UL << 14)  /* clear err bit in PRB_E reg */
-#define IECLR_PRB_D            (1UL << 13)  /* clear err bit in PRB_D reg */
-#define IECLR_PRB_C            (1UL << 12)  /* clear err bit in PRB_C reg */
-#define IECLR_PRB_B            (1UL << 11)  /* clear err bit in PRB_B reg */
-#define IECLR_PRB_A            (1UL << 10)  /* clear err bit in PRB_A reg */
-#define IECLR_PRB_9            (1UL << 9)   /* clear err bit in PRB_9 reg */
-#define IECLR_PRB_8            (1UL << 8)   /* clear err bit in PRB_8 reg */
-#define IECLR_PRB_0            (1UL << 0)   /* clear err bit in PRB_0 reg */
+#define IECLR_PI1_FWD_INT      (1UL << 31)     /* clear PI1_FORWARD_INT in iidsr */
+#define IECLR_PI0_FWD_INT      (1UL << 30)     /* clear PI0_FORWARD_INT in iidsr */
+#define IECLR_SPUR_RD_HDR      (1UL << 29)     /* clear valid bit in ixss reg */
+#define IECLR_BTE1             (1UL << 18)     /* clear bte error 1 */
+#define IECLR_BTE0             (1UL << 17)     /* clear bte error 0 */
+#define IECLR_CRAZY            (1UL << 16)     /* clear crazy bit in wstat reg */
+#define IECLR_PRB_F            (1UL << 15)     /* clear err bit in PRB_F reg */
+#define IECLR_PRB_E            (1UL << 14)     /* clear err bit in PRB_E reg */
+#define IECLR_PRB_D            (1UL << 13)     /* clear err bit in PRB_D reg */
+#define IECLR_PRB_C            (1UL << 12)     /* clear err bit in PRB_C reg */
+#define IECLR_PRB_B            (1UL << 11)     /* clear err bit in PRB_B reg */
+#define IECLR_PRB_A            (1UL << 10)     /* clear err bit in PRB_A reg */
+#define IECLR_PRB_9            (1UL << 9)      /* clear err bit in PRB_9 reg */
+#define IECLR_PRB_8            (1UL << 8)      /* clear err bit in PRB_8 reg */
+#define IECLR_PRB_0            (1UL << 0)      /* clear err bit in PRB_0 reg */
 
 /*
  * IIO CRB control register Fields: IIO_ICCR 
  */
-#define        IIO_ICCR_PENDING        (0x10000)
-#define        IIO_ICCR_CMD_MASK       (0xFF)
-#define        IIO_ICCR_CMD_SHFT       (7)
-#define        IIO_ICCR_CMD_NOP        (0x0)   /* No Op */
-#define        IIO_ICCR_CMD_WAKE       (0x100) /* Reactivate CRB entry and process */
-#define        IIO_ICCR_CMD_TIMEOUT    (0x200) /* Make CRB timeout & mark invalid */
-#define        IIO_ICCR_CMD_EJECT      (0x400) /* Contents of entry written to memory 
+#define        IIO_ICCR_PENDING        0x10000
+#define        IIO_ICCR_CMD_MASK       0xFF
+#define        IIO_ICCR_CMD_SHFT       7
+#define        IIO_ICCR_CMD_NOP        0x0     /* No Op */
+#define        IIO_ICCR_CMD_WAKE       0x100   /* Reactivate CRB entry and process */
+#define        IIO_ICCR_CMD_TIMEOUT    0x200   /* Make CRB timeout & mark invalid */
+#define        IIO_ICCR_CMD_EJECT      0x400   /* Contents of entry written to memory
                                         * via a WB
                                         */
-#define        IIO_ICCR_CMD_FLUSH      (0x800)
+#define        IIO_ICCR_CMD_FLUSH      0x800
 
 /*
  *
@@ -3283,8 +3173,8 @@ typedef union ii_ippr_u {
  * Easy access macros for CRBs, all 5 registers (A-E)
  */
 typedef ii_icrb0_a_u_t icrba_t;
-#define a_sidn          ii_icrb0_a_fld_s.ia_sidn
-#define a_tnum          ii_icrb0_a_fld_s.ia_tnum
+#define a_sidn         ii_icrb0_a_fld_s.ia_sidn
+#define a_tnum         ii_icrb0_a_fld_s.ia_tnum
 #define a_addr          ii_icrb0_a_fld_s.ia_addr
 #define a_valid         ii_icrb0_a_fld_s.ia_vld
 #define a_iow           ii_icrb0_a_fld_s.ia_iow
@@ -3324,14 +3214,13 @@ typedef ii_icrb0_c_u_t icrbc_t;
 #define c_source        ii_icrb0_c_fld_s.ic_source
 #define c_regvalue     ii_icrb0_c_regval
 
-
 typedef ii_icrb0_d_u_t icrbd_t;
 #define d_sleep         ii_icrb0_d_fld_s.id_sleep
 #define d_pricnt        ii_icrb0_d_fld_s.id_pr_cnt
 #define d_pripsc        ii_icrb0_d_fld_s.id_pr_psc
 #define d_bteop         ii_icrb0_d_fld_s.id_bte_op
-#define d_bteaddr       ii_icrb0_d_fld_s.id_pa_be /* ic_pa_be fld has 2 names*/
-#define d_benable       ii_icrb0_d_fld_s.id_pa_be /* ic_pa_be fld has 2 names*/
+#define d_bteaddr       ii_icrb0_d_fld_s.id_pa_be      /* ic_pa_be fld has 2 names */
+#define d_benable       ii_icrb0_d_fld_s.id_pa_be      /* ic_pa_be fld has 2 names */
 #define d_regvalue     ii_icrb0_d_regval
 
 typedef ii_icrb0_e_u_t icrbe_t;
@@ -3341,7 +3230,6 @@ typedef ii_icrb0_e_u_t icrbe_t;
 #define icrbe_timeout   ii_icrb0_e_fld_s.ie_timeout
 #define e_regvalue     ii_icrb0_e_regval
 
-
 /* Number of widgets supported by shub */
 #define HUB_NUM_WIDGET          9
 #define HUB_WIDGET_ID_MIN       0x8
@@ -3367,27 +3255,27 @@ typedef ii_icrb0_e_u_t icrbe_t;
 
 #define LNK_STAT_WORKING        0x2            /* LLP is working */
 
-#define IIO_WSTAT_ECRAZY        (1ULL << 32)    /* Hub gone crazy */
-#define IIO_WSTAT_TXRETRY       (1ULL << 9)     /* Hub Tx Retry timeout */
-#define IIO_WSTAT_TXRETRY_MASK  (0x7F)   /* should be 0xFF?? */
-#define IIO_WSTAT_TXRETRY_SHFT  (16)
-#define IIO_WSTAT_TXRETRY_CNT(w)        (((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
-                                          IIO_WSTAT_TXRETRY_MASK)
+#define IIO_WSTAT_ECRAZY       (1ULL << 32)    /* Hub gone crazy */
+#define IIO_WSTAT_TXRETRY      (1ULL << 9)     /* Hub Tx Retry timeout */
+#define IIO_WSTAT_TXRETRY_MASK  0x7F           /* should be 0xFF?? */
+#define IIO_WSTAT_TXRETRY_SHFT  16
+#define IIO_WSTAT_TXRETRY_CNT(w)       (((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
+                                       IIO_WSTAT_TXRETRY_MASK)
 
 /* Number of II perf. counters we can multiplex at once */
 
 #define IO_PERF_SETS   32
 
 /* Bit for the widget in inbound access register */
-#define IIO_IIWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
+#define IIO_IIWA_WIDGET(_w)    ((uint64_t)(1ULL << _w))
 /* Bit for the widget in outbound access register */
-#define IIO_IOWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
+#define IIO_IOWA_WIDGET(_w)    ((uint64_t)(1ULL << _w))
 
 /* NOTE: The following define assumes that we are going to get
  * widget numbers from 8 thru F and the device numbers within
  * widget from 0 thru 7.
  */
-#define IIO_IIDEM_WIDGETDEV_MASK(w, d)  ((uint64_t)(1ULL << (8 * ((w) - 8) + (d))))
+#define IIO_IIDEM_WIDGETDEV_MASK(w, d) ((uint64_t)(1ULL << (8 * ((w) - 8) + (d))))
 
 /* IO Interrupt Destination Register */
 #define IIO_IIDSR_SENT_SHIFT    28
@@ -3402,11 +3290,11 @@ typedef ii_icrb0_e_u_t icrbe_t;
 #define IIO_IIDSR_LVL_MASK      0x000000ff
 
 /* Xtalk timeout threshhold register (IIO_IXTT) */
-#define IXTT_RRSP_TO_SHFT      55         /* read response timeout */
+#define IXTT_RRSP_TO_SHFT      55      /* read response timeout */
 #define IXTT_RRSP_TO_MASK      (0x1FULL << IXTT_RRSP_TO_SHFT)
-#define IXTT_RRSP_PS_SHFT      32         /* read responsed TO prescalar */
+#define IXTT_RRSP_PS_SHFT      32      /* read responsed TO prescalar */
 #define IXTT_RRSP_PS_MASK      (0x7FFFFFULL << IXTT_RRSP_PS_SHFT)
-#define IXTT_TAIL_TO_SHFT      0          /* tail timeout counter threshold */
+#define IXTT_TAIL_TO_SHFT      0       /* tail timeout counter threshold */
 #define IXTT_TAIL_TO_MASK      (0x3FFFFFFULL << IXTT_TAIL_TO_SHFT)
 
 /*
@@ -3414,17 +3302,17 @@ typedef ii_icrb0_e_u_t icrbe_t;
  */
 
 typedef union hubii_wcr_u {
-        uint64_t      wcr_reg_value;
-        struct {
-         uint64_t      wcr_widget_id:   4,     /* LLP crossbar credit */
-                       wcr_tag_mode:    1,     /* Tag mode */
-                       wcr_rsvd1:       8,     /* Reserved */
-                       wcr_xbar_crd:    3,     /* LLP crossbar credit */
-                       wcr_f_bad_pkt:   1,     /* Force bad llp pkt enable */
-                       wcr_dir_con:     1,     /* widget direct connect */
-                       wcr_e_thresh:    5,     /* elasticity threshold */
-                       wcr_rsvd:       41;     /* unused */
-        } wcr_fields_s;
+       uint64_t wcr_reg_value;
+       struct {
+               uint64_t wcr_widget_id:4,       /* LLP crossbar credit */
+                wcr_tag_mode:1,        /* Tag mode */
+                wcr_rsvd1:8,   /* Reserved */
+                wcr_xbar_crd:3,        /* LLP crossbar credit */
+                wcr_f_bad_pkt:1,       /* Force bad llp pkt enable */
+                wcr_dir_con:1, /* widget direct connect */
+                wcr_e_thresh:5,        /* elasticity threshold */
+                wcr_rsvd:41;   /* unused */
+       } wcr_fields_s;
 } hubii_wcr_t;
 
 #define iwcr_dir_con    wcr_fields_s.wcr_dir_con
@@ -3436,41 +3324,35 @@ performance registers */
    performed */
 
 typedef union io_perf_sel {
-        uint64_t perf_sel_reg;
-        struct {
-               uint64_t        perf_ippr0 :  4,
-                               perf_ippr1 :  4,
-                               perf_icct  :  8,
-                               perf_rsvd  : 48;
-        } perf_sel_bits;
+       uint64_t perf_sel_reg;
+       struct {
+               uint64_t perf_ippr0:4, perf_ippr1:4, perf_icct:8, perf_rsvd:48;
+       } perf_sel_bits;
 } io_perf_sel_t;
 
 /* io_perf_cnt is to extract the count from the shub registers. Due to
    hardware problems there is only one counter, not two. */
 
 typedef union io_perf_cnt {
-        uint64_t      perf_cnt;
-        struct {
-               uint64_t        perf_cnt   : 20,
-                               perf_rsvd2 : 12,
-                               perf_rsvd1 : 32;
-        } perf_cnt_bits;
+       uint64_t perf_cnt;
+       struct {
+               uint64_t perf_cnt:20, perf_rsvd2:12, perf_rsvd1:32;
+       } perf_cnt_bits;
 
 } io_perf_cnt_t;
 
 typedef union iprte_a {
-       uint64_t        entry;
-       struct {
-               uint64_t        i_rsvd_1                  :      3;
-               uint64_t        i_addr                    :     38;
-               uint64_t        i_init                    :      3;
-               uint64_t        i_source                  :      8;
-               uint64_t        i_rsvd                    :      2;
-               uint64_t        i_widget                  :      4;
-               uint64_t        i_to_cnt                  :      5;
-               uint64_t       i_vld                     :      1;
+       uint64_t entry;
+       struct {
+               uint64_t i_rsvd_1:3;
+               uint64_t i_addr:38;
+               uint64_t i_init:3;
+               uint64_t i_source:8;
+               uint64_t i_rsvd:2;
+               uint64_t i_widget:4;
+               uint64_t i_to_cnt:5;
+               uint64_t i_vld:1;
        } iprte_fields;
 } iprte_a_t;
 
-#endif /* _ASM_IA64_SN_SHUBIO_H */
-
+#endif                         /* _ASM_IA64_SN_SHUBIO_H */
index 685435af170d8d543fdf74b73d269325153e6e70..20b3001876698992860772fcef3edfc6f62040d3 100644 (file)
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
  */
 
 
  * NOTE: on non-MP systems, only cpuid 0 exists
  */
 
-extern short physical_node_map[];                      /* indexed by nasid to get cnode */
+extern short physical_node_map[];      /* indexed by nasid to get cnode */
 
 /*
  * Macros for retrieving info about current cpu
  */
-#define get_nasid()                    (nodepda->phys_cpuid[smp_processor_id()].nasid)
-#define get_subnode()                  (nodepda->phys_cpuid[smp_processor_id()].subnode)
-#define get_slice()                    (nodepda->phys_cpuid[smp_processor_id()].slice)
-#define get_cnode()                    (nodepda->phys_cpuid[smp_processor_id()].cnode)
-#define get_sapicid()                  ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
+#define get_nasid()    (sn_nodepda->phys_cpuid[smp_processor_id()].nasid)
+#define get_subnode()  (sn_nodepda->phys_cpuid[smp_processor_id()].subnode)
+#define get_slice()    (sn_nodepda->phys_cpuid[smp_processor_id()].slice)
+#define get_cnode()    (sn_nodepda->phys_cpuid[smp_processor_id()].cnode)
+#define get_sapicid()  ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
 
 /*
  * Macros for retrieving info about an arbitrary cpu
  *     cpuid - logical cpu id
  */
-#define cpuid_to_nasid(cpuid)          (nodepda->phys_cpuid[cpuid].nasid)
-#define cpuid_to_subnode(cpuid)                (nodepda->phys_cpuid[cpuid].subnode)
-#define cpuid_to_slice(cpuid)          (nodepda->phys_cpuid[cpuid].slice)
+#define cpuid_to_nasid(cpuid)          (sn_nodepda->phys_cpuid[cpuid].nasid)
+#define cpuid_to_subnode(cpuid)                (sn_nodepda->phys_cpuid[cpuid].subnode)
+#define cpuid_to_slice(cpuid)          (sn_nodepda->phys_cpuid[cpuid].slice)
 #define cpuid_to_cnodeid(cpuid)                (physical_node_map[cpuid_to_nasid(cpuid)])
 
 
@@ -123,11 +123,8 @@ extern int nasid_slice_to_cpuid(int, int);
 
 /*
  * cnodeid_to_nasid - convert a cnodeid to a NASID
- *     Macro relies on pg_data for a node being on the node itself.
- *     Just extract the NASID from the pointer.
- *
  */
-#define cnodeid_to_nasid(cnodeid)      pda->cnodeid_to_nasid_table[cnodeid]
+#define cnodeid_to_nasid(cnodeid)      (sn_cnodeid_to_nasid[cnodeid])
  
 /*
  * nasid_to_cnodeid - convert a NASID to a cnodeid
diff --git a/include/asm-ia64/sn/sn_fru.h b/include/asm-ia64/sn/sn_fru.h
deleted file mode 100644 (file)
index 8c21ac3..0000000
+++ /dev/null
@@ -1,44 +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) 1992-1997,1999-2004 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN_FRU_H
-#define _ASM_IA64_SN_SN_FRU_H
-
-#define MAX_DIMMS                      8        /* max # of dimm banks */
-#define MAX_PCIDEV                     8        /* max # of pci devices on a pci bus */
-
-typedef unsigned char confidence_t;
-
-typedef struct kf_mem_s {
-       confidence_t km_confidence; /* confidence level that the memory is bad
-                                    * is this necessary ?
-                                    */
-       confidence_t km_dimm[MAX_DIMMS];
-                                   /* confidence level that dimm[i] is bad
-                                    *I think this is the right number
-                                    */
-
-} kf_mem_t;
-
-typedef struct kf_cpu_s {
-       confidence_t    kc_confidence; /* confidence level that cpu is bad */
-       confidence_t    kc_icache; /* confidence level that instr. cache is bad */
-       confidence_t    kc_dcache; /* confidence level that data   cache is bad */
-       confidence_t    kc_scache; /* confidence level that sec.   cache is bad */
-       confidence_t    kc_sysbus; /* confidence level that sysad/cmd/state bus is bad */
-} kf_cpu_t;
-
-
-typedef struct kf_pci_bus_s {
-       confidence_t    kpb_belief;     /* confidence level  that the  pci bus is bad */
-       confidence_t    kpb_pcidev_belief[MAX_PCIDEV];
-                                       /* confidence level that the pci dev is bad */
-} kf_pci_bus_t;
-
-
-#endif /* _ASM_IA64_SN_SN_FRU_H */
-
index f914f6da077c62852dbe981e93c2024305ad9e9a..eb0395ad0d6a68c1a93e98d86ac045c76928ce51 100644 (file)
 #define SAL_IROUTER_INTR_XMIT  SAL_CONSOLE_INTR_XMIT
 #define SAL_IROUTER_INTR_RECV  SAL_CONSOLE_INTR_RECV
 
+/*
+ * Error Handling Features
+ */
+#define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV    0x1
+#define SAL_ERR_FEAT_LOG_SBES                  0x2
+#define SAL_ERR_FEAT_MFR_OVERRIDE              0x4
+#define SAL_ERR_FEAT_SBE_THRESHOLD             0xffff0000
 
 /*
  * SAL Error Codes
@@ -341,6 +348,25 @@ ia64_sn_plat_cpei_handler(void)
        return ret_stuff.status;
 }
 
+/*
+ * Set Error Handling Features
+ */
+static inline u64
+ia64_sn_plat_set_error_handling_features(void)
+{
+       struct ia64_sal_retval ret_stuff;
+
+       ret_stuff.status = 0;
+       ret_stuff.v0 = 0;
+       ret_stuff.v1 = 0;
+       ret_stuff.v2 = 0;
+       SAL_CALL_REENTRANT(ret_stuff, SN_SAL_SET_ERROR_HANDLING_FEATURES,
+               (SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV | SAL_ERR_FEAT_LOG_SBES),
+               0, 0, 0, 0, 0, 0);
+
+       return ret_stuff.status;
+}
+
 /*
  * Checks for console input.
  */
@@ -472,7 +498,7 @@ static inline u64
 ia64_sn_pod_mode(void)
 {
        struct ia64_sal_retval isrv;
-       SAL_CALL(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0);
+       SAL_CALL_REENTRANT(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0);
        if (isrv.status)
                return 0;
        return isrv.v0;
@@ -557,7 +583,8 @@ static inline u64
 ia64_sn_partition_serial_get(void)
 {
        struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0, 0, 0, 0, 0, 0, 0);
+       ia64_sal_oemcall_reentrant(&ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0,
+                                  0, 0, 0, 0, 0, 0);
        if (ret_stuff.status != 0)
            return 0;
        return ret_stuff.v0;
@@ -565,11 +592,10 @@ ia64_sn_partition_serial_get(void)
 
 static inline u64
 sn_partition_serial_number_val(void) {
-       if (sn_partition_serial_number) {
-               return(sn_partition_serial_number);
-       } else {
-               return(sn_partition_serial_number = ia64_sn_partition_serial_get());
+       if (unlikely(sn_partition_serial_number == 0)) {
+               sn_partition_serial_number = ia64_sn_partition_serial_get();
        }
+       return sn_partition_serial_number;
 }
 
 /*
@@ -580,8 +606,8 @@ static inline partid_t
 ia64_sn_sysctl_partition_get(nasid_t nasid)
 {
        struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
-                0, 0, 0, 0, 0, 0);
+       ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
+                               0, 0, 0, 0, 0, 0);
        if (ret_stuff.status != 0)
            return INVALID_PARTID;
        return ((partid_t)ret_stuff.v0);
@@ -595,11 +621,38 @@ extern partid_t sn_partid;
 
 static inline partid_t
 sn_local_partid(void) {
-       if (sn_partid < 0) {
-               return (sn_partid = ia64_sn_sysctl_partition_get(cpuid_to_nasid(smp_processor_id())));
-       } else {
-               return sn_partid;
+       if (unlikely(sn_partid < 0)) {
+               sn_partid = ia64_sn_sysctl_partition_get(cpuid_to_nasid(smp_processor_id()));
        }
+       return sn_partid;
+}
+
+/*
+ * Returns the physical address of the partition's reserved page through
+ * an iterative number of calls.
+ *
+ * On first call, 'cookie' and 'len' should be set to 0, and 'addr'
+ * set to the nasid of the partition whose reserved page's address is
+ * being sought.
+ * On subsequent calls, pass the values, that were passed back on the
+ * previous call.
+ *
+ * While the return status equals SALRET_MORE_PASSES, keep calling
+ * this function after first copying 'len' bytes starting at 'addr'
+ * into 'buf'. Once the return status equals SALRET_OK, 'addr' will
+ * be the physical address of the partition's reserved page. If the
+ * return status equals neither of these, an error as occurred.
+ */
+static inline s64
+sn_partition_reserved_page_pa(u64 buf, u64 *cookie, u64 *addr, u64 *len)
+{
+       struct ia64_sal_retval rv;
+       ia64_sal_oemcall_reentrant(&rv, SN_SAL_GET_PARTITION_ADDR, *cookie,
+                                  *addr, buf, *len, 0, 0, 0);
+       *cookie = rv.v0;
+       *addr = rv.v1;
+       *len = rv.v2;
+       return rv.status;
 }
 
 /*
@@ -621,8 +674,8 @@ static inline int
 sn_register_xp_addr_region(u64 paddr, u64 len, int operation)
 {
        struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len, (u64)operation,
-                0, 0, 0, 0);
+       ia64_sal_oemcall(&ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len,
+                        (u64)operation, 0, 0, 0, 0);
        return ret_stuff.status;
 }
 
@@ -646,8 +699,8 @@ sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
        } else {
                call = SN_SAL_NO_FAULT_ZONE_PHYSICAL;
        }
-       SAL_CALL(ret_stuff, call, start_addr, end_addr, return_addr, (u64)1,
-                0, 0, 0);
+       ia64_sal_oemcall(&ret_stuff, call, start_addr, end_addr, return_addr,
+                        (u64)1, 0, 0, 0);
        return ret_stuff.status;
 }
 
@@ -668,8 +721,8 @@ static inline int
 sn_change_coherence(u64 *new_domain, u64 *old_domain)
 {
        struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_COHERENCE, new_domain, old_domain, 0, 0,
-                0, 0, 0);
+       ia64_sal_oemcall(&ret_stuff, SN_SAL_COHERENCE, (u64)new_domain,
+                        (u64)old_domain, 0, 0, 0, 0, 0);
        return ret_stuff.status;
 }
 
@@ -688,8 +741,8 @@ sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
        cnodeid = nasid_to_cnodeid(get_node_number(paddr));
        // spin_lock(&NODEPDA(cnodeid)->bist_lock);
        local_irq_save(irq_flags);
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_MEMPROTECT, paddr, len, nasid_array,
-                perms, 0, 0, 0);
+       ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len,
+                               (u64)nasid_array, perms, 0, 0, 0);
        local_irq_restore(irq_flags);
        // spin_unlock(&NODEPDA(cnodeid)->bist_lock);
        return ret_stuff.status;
diff --git a/include/asm-ia64/sn/sndrv.h b/include/asm-ia64/sn/sndrv.h
deleted file mode 100644 (file)
index aa00d42..0000000
+++ /dev/null
@@ -1,47 +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) 2002-2004 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#ifndef _ASM_IA64_SN_SNDRV_H
-#define _ASM_IA64_SN_SNDRV_H
-
-/* ioctl commands */
-#define SNDRV_GET_ROUTERINFO           1
-#define SNDRV_GET_INFOSIZE             2
-#define SNDRV_GET_HUBINFO              3
-#define SNDRV_GET_FLASHLOGSIZE         4
-#define SNDRV_SET_FLASHSYNC            5
-#define SNDRV_GET_FLASHLOGDATA         6
-#define SNDRV_GET_FLASHLOGALL          7
-
-#define SNDRV_SET_HISTOGRAM_TYPE       14
-
-#define SNDRV_ELSC_COMMAND             19
-#define        SNDRV_CLEAR_LOG                 20
-#define        SNDRV_INIT_LOG                  21
-#define        SNDRV_GET_PIMM_PSC              22
-#define SNDRV_SET_PARTITION            23
-#define SNDRV_GET_PARTITION            24
-
-/* see synergy_perf_ioctl() */
-#define SNDRV_GET_SYNERGY_VERSION      30
-#define SNDRV_GET_SYNERGY_STATUS       31
-#define SNDRV_GET_SYNERGYINFO          32
-#define SNDRV_SYNERGY_APPEND           33
-#define SNDRV_SYNERGY_ENABLE           34
-#define SNDRV_SYNERGY_FREQ             35
-
-/* Devices */
-#define SNDRV_UKNOWN_DEVICE            -1
-#define SNDRV_ROUTER_DEVICE            1
-#define SNDRV_HUB_DEVICE               2
-#define SNDRV_ELSC_NVRAM_DEVICE                3
-#define SNDRV_ELSC_CONTROLLER_DEVICE   4
-#define SNDRV_SYSCTL_SUBCH             5
-#define SNDRV_SYNERGY_DEVICE           6
-
-#endif /* _ASM_IA64_SN_SNDRV_H */
diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h
new file mode 100644 (file)
index 0000000..9902185
--- /dev/null
@@ -0,0 +1,436 @@
+/*
+ * 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-2005 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+/*
+ * External Cross Partition (XP) structures and defines.
+ */
+
+
+#ifndef _ASM_IA64_SN_XP_H
+#define _ASM_IA64_SN_XP_H
+
+
+#include <linux/version.h>
+#include <linux/cache.h>
+#include <linux/hardirq.h>
+#include <asm/sn/types.h>
+#include <asm/sn/bte.h>
+
+
+#ifdef USE_DBUG_ON
+#define DBUG_ON(condition)     BUG_ON(condition)
+#else
+#define DBUG_ON(condition)
+#endif
+
+
+/*
+ * Define the maximum number of logically defined partitions the system
+ * can support. It is constrained by the maximum number of hardware
+ * partitionable regions. The term 'region' in this context refers to the
+ * minimum number of nodes that can comprise an access protection grouping.
+ * The access protection is in regards to memory, IPI and IOI.
+ *
+ * The maximum number of hardware partitionable regions is equal to the
+ * maximum number of nodes in the entire system divided by the minimum number
+ * of nodes that comprise an access protection grouping.
+ */
+#define XP_MAX_PARTITIONS      64
+
+
+/*
+ * Define the number of u64s required to represent all the C-brick nasids
+ * as a bitmap.  The cross-partition kernel modules deal only with
+ * C-brick nasids, thus the need for bitmaps which don't account for
+ * odd-numbered (non C-brick) nasids.
+ */
+#define XP_MAX_PHYSNODE_ID     (MAX_PHYSNODE_ID / 2)
+#define XP_NASID_MASK_BYTES    ((XP_MAX_PHYSNODE_ID + 7) / 8)
+#define XP_NASID_MASK_WORDS    ((XP_MAX_PHYSNODE_ID + 63) / 64)
+
+
+/*
+ * Wrapper for bte_copy() that should it return a failure status will retry
+ * the bte_copy() once in the hope that the failure was due to a temporary
+ * aberration (i.e., the link going down temporarily).
+ *
+ * See bte_copy for definition of the input parameters.
+ *
+ * Note: xp_bte_copy() should never be called while holding a spinlock.
+ */
+static inline bte_result_t
+xp_bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
+{
+       bte_result_t ret;
+
+
+       ret = bte_copy(src, dest, len, mode, notification);
+
+       if (ret != BTE_SUCCESS) {
+               if (!in_interrupt()) {
+                       cond_resched();
+               }
+               ret = bte_copy(src, dest, len, mode, notification);
+       }
+
+       return ret;
+}
+
+
+/*
+ * XPC establishes channel connections between the local partition and any
+ * other partition that is currently up. Over these channels, kernel-level
+ * `users' can communicate with their counterparts on the other partitions.
+ *
+ * The maxinum number of channels is limited to eight. For performance reasons,
+ * the internal cross partition structures require sixteen bytes per channel,
+ * and eight allows all of this interface-shared info to fit in one cache line.
+ *
+ * XPC_NCHANNELS reflects the total number of channels currently defined.
+ * If the need for additional channels arises, one can simply increase
+ * XPC_NCHANNELS accordingly. If the day should come where that number
+ * exceeds the MAXIMUM number of channels allowed (eight), then one will need
+ * to make changes to the XPC code to allow for this.
+ */
+#define XPC_MEM_CHANNEL                0       /* memory channel number */
+#define        XPC_NET_CHANNEL         1       /* network channel number */
+
+#define        XPC_NCHANNELS           2       /* #of defined channels */
+#define XPC_MAX_NCHANNELS      8       /* max #of channels allowed */
+
+#if XPC_NCHANNELS > XPC_MAX_NCHANNELS
+#error XPC_NCHANNELS exceeds MAXIMUM allowed.
+#endif
+
+
+/*
+ * The format of an XPC message is as follows:
+ *
+ *      +-------+--------------------------------+
+ *      | flags |////////////////////////////////|
+ *      +-------+--------------------------------+
+ *      |             message #                  |
+ *      +----------------------------------------+
+ *      |     payload (user-defined message)     |
+ *      |                                        |
+ *                     :
+ *      |                                        |
+ *      +----------------------------------------+
+ *
+ * The size of the payload is defined by the user via xpc_connect(). A user-
+ * defined message resides in the payload area.
+ *
+ * The user should have no dealings with the message header, but only the
+ * message's payload. When a message entry is allocated (via xpc_allocate())
+ * a pointer to the payload area is returned and not the actual beginning of
+ * the XPC message. The user then constructs a message in the payload area
+ * and passes that pointer as an argument on xpc_send() or xpc_send_notify().
+ *
+ * The size of a message entry (within a message queue) must be a cacheline
+ * sized multiple in order to facilitate the BTE transfer of messages from one
+ * message queue to another. A macro, XPC_MSG_SIZE(), is provided for the user
+ * that wants to fit as many msg entries as possible in a given memory size
+ * (e.g. a memory page).
+ */
+struct xpc_msg {
+       u8 flags;               /* FOR XPC INTERNAL USE ONLY */
+       u8 reserved[7];         /* FOR XPC INTERNAL USE ONLY */
+       s64 number;             /* FOR XPC INTERNAL USE ONLY */
+
+       u64 payload;            /* user defined portion of message */
+};
+
+
+#define XPC_MSG_PAYLOAD_OFFSET (u64) (&((struct xpc_msg *)0)->payload)
+#define XPC_MSG_SIZE(_payload_size) \
+               L1_CACHE_ALIGN(XPC_MSG_PAYLOAD_OFFSET + (_payload_size))
+
+
+/*
+ * Define the return values and values passed to user's callout functions.
+ * (It is important to add new value codes at the end just preceding
+ * xpcUnknownReason, which must have the highest numerical value.)
+ */
+enum xpc_retval {
+       xpcSuccess = 0,
+
+       xpcNotConnected,        /*  1: channel is not connected */
+       xpcConnected,           /*  2: channel connected (opened) */
+       xpcRETIRED1,            /*  3: (formerly xpcDisconnected) */
+
+       xpcMsgReceived,         /*  4: message received */
+       xpcMsgDelivered,        /*  5: message delivered and acknowledged */
+
+       xpcRETIRED2,            /*  6: (formerly xpcTransferFailed) */
+
+       xpcNoWait,              /*  7: operation would require wait */
+       xpcRetry,               /*  8: retry operation */
+       xpcTimeout,             /*  9: timeout in xpc_allocate_msg_wait() */
+       xpcInterrupted,         /* 10: interrupted wait */
+
+       xpcUnequalMsgSizes,     /* 11: message size disparity between sides */
+       xpcInvalidAddress,      /* 12: invalid address */
+
+       xpcNoMemory,            /* 13: no memory available for XPC structures */
+       xpcLackOfResources,     /* 14: insufficient resources for operation */
+       xpcUnregistered,        /* 15: channel is not registered */
+       xpcAlreadyRegistered,   /* 16: channel is already registered */
+
+       xpcPartitionDown,       /* 17: remote partition is down */
+       xpcNotLoaded,           /* 18: XPC module is not loaded */
+       xpcUnloading,           /* 19: this side is unloading XPC module */
+
+       xpcBadMagic,            /* 20: XPC MAGIC string not found */
+
+       xpcReactivating,        /* 21: remote partition was reactivated */
+
+       xpcUnregistering,       /* 22: this side is unregistering channel */
+       xpcOtherUnregistering,  /* 23: other side is unregistering channel */
+
+       xpcCloneKThread,        /* 24: cloning kernel thread */
+       xpcCloneKThreadFailed,  /* 25: cloning kernel thread failed */
+
+       xpcNoHeartbeat,         /* 26: remote partition has no heartbeat */
+
+       xpcPioReadError,        /* 27: PIO read error */
+       xpcPhysAddrRegFailed,   /* 28: registration of phys addr range failed */
+
+       xpcBteDirectoryError,   /* 29: maps to BTEFAIL_DIR */
+       xpcBtePoisonError,      /* 30: maps to BTEFAIL_POISON */
+       xpcBteWriteError,       /* 31: maps to BTEFAIL_WERR */
+       xpcBteAccessError,      /* 32: maps to BTEFAIL_ACCESS */
+       xpcBtePWriteError,      /* 33: maps to BTEFAIL_PWERR */
+       xpcBtePReadError,       /* 34: maps to BTEFAIL_PRERR */
+       xpcBteTimeOutError,     /* 35: maps to BTEFAIL_TOUT */
+       xpcBteXtalkError,       /* 36: maps to BTEFAIL_XTERR */
+       xpcBteNotAvailable,     /* 37: maps to BTEFAIL_NOTAVAIL */
+       xpcBteUnmappedError,    /* 38: unmapped BTEFAIL_ error */
+
+       xpcBadVersion,          /* 39: bad version number */
+       xpcVarsNotSet,          /* 40: the XPC variables are not set up */
+       xpcNoRsvdPageAddr,      /* 41: unable to get rsvd page's phys addr */
+       xpcInvalidPartid,       /* 42: invalid partition ID */
+       xpcLocalPartid,         /* 43: local partition ID */
+
+       xpcUnknownReason        /* 44: unknown reason -- must be last in list */
+};
+
+
+/*
+ * Define the callout function types used by XPC to update the user on
+ * connection activity and state changes (via the user function registered by
+ * xpc_connect()) and to notify them of messages received and delivered (via
+ * the user function registered by xpc_send_notify()).
+ *
+ * The two function types are xpc_channel_func and xpc_notify_func and
+ * both share the following arguments, with the exception of "data", which
+ * only xpc_channel_func has.
+ *
+ * Arguments:
+ *
+ *     reason - reason code. (See following table.)
+ *     partid - partition ID associated with condition.
+ *     ch_number - channel # associated with condition.
+ *     data - pointer to optional data. (See following table.)
+ *     key - pointer to optional user-defined value provided as the "key"
+ *           argument to xpc_connect() or xpc_send_notify().
+ *
+ * In the following table the "Optional Data" column applies to callouts made
+ * to functions registered by xpc_connect(). A "NA" in that column indicates
+ * that this reason code can be passed to functions registered by
+ * xpc_send_notify() (i.e. they don't have data arguments).
+ *
+ * Also, the first three reason codes in the following table indicate
+ * success, whereas the others indicate failure. When a failure reason code
+ * is received, one can assume that the channel is not connected.
+ *
+ *
+ * Reason Code          | Cause                          | Optional Data
+ * =====================+================================+=====================
+ * xpcConnected         | connection has been established| max #of entries
+ *                      | to the specified partition on  | allowed in message
+ *                      | the specified channel          | queue
+ * ---------------------+--------------------------------+---------------------
+ * xpcMsgReceived       | an XPC message arrived from    | address of payload
+ *                      | the specified partition on the |
+ *                      | specified channel              | [the user must call
+ *                      |                                | xpc_received() when
+ *                      |                                | finished with the
+ *                      |                                | payload]
+ * ---------------------+--------------------------------+---------------------
+ * xpcMsgDelivered      | notification that the message  | NA
+ *                      | was delivered to the intended  |
+ *                      | recipient and that they have   |
+ *                      | acknowledged its receipt by    |
+ *                      | calling xpc_received()         |
+ * =====================+================================+=====================
+ * xpcUnequalMsgSizes   | can't connect to the specified | NULL
+ *                      | partition on the specified     |
+ *                      | channel because of mismatched  |
+ *                      | message sizes                  |
+ * ---------------------+--------------------------------+---------------------
+ * xpcNoMemory          | insufficient memory avaiable   | NULL
+ *                      | to allocate message queue      |
+ * ---------------------+--------------------------------+---------------------
+ * xpcLackOfResources   | lack of resources to create    | NULL
+ *                      | the necessary kthreads to      |
+ *                      | support the channel            |
+ * ---------------------+--------------------------------+---------------------
+ * xpcUnregistering     | this side's user has           | NULL or NA
+ *                      | unregistered by calling        |
+ *                      | xpc_disconnect()               |
+ * ---------------------+--------------------------------+---------------------
+ * xpcOtherUnregistering| the other side's user has      | NULL or NA
+ *                      | unregistered by calling        |
+ *                      | xpc_disconnect()               |
+ * ---------------------+--------------------------------+---------------------
+ * xpcNoHeartbeat       | the other side's XPC is no     | NULL or NA
+ *                      | longer heartbeating            |
+ *                      |                                |
+ * ---------------------+--------------------------------+---------------------
+ * xpcUnloading         | this side's XPC module is      | NULL or NA
+ *                      | being unloaded                 |
+ *                      |                                |
+ * ---------------------+--------------------------------+---------------------
+ * xpcOtherUnloading    | the other side's XPC module is | NULL or NA
+ *                      | is being unloaded              |
+ *                      |                                |
+ * ---------------------+--------------------------------+---------------------
+ * xpcPioReadError      | xp_nofault_PIOR() returned an  | NULL or NA
+ *                      | error while sending an IPI     |
+ *                      |                                |
+ * ---------------------+--------------------------------+---------------------
+ * xpcInvalidAddress    | the address either received or | NULL or NA
+ *                      | sent by the specified partition|
+ *                      | is invalid                     |
+ * ---------------------+--------------------------------+---------------------
+ * xpcBteNotAvailable   | attempt to pull data from the  | NULL or NA
+ * xpcBtePoisonError    | specified partition over the   |
+ * xpcBteWriteError     | specified channel via a        |
+ * xpcBteAccessError    | bte_copy() failed              |
+ * xpcBteTimeOutError   |                                |
+ * xpcBteXtalkError     |                                |
+ * xpcBteDirectoryError |                                |
+ * xpcBteGenericError   |                                |
+ * xpcBteUnmappedError  |                                |
+ * ---------------------+--------------------------------+---------------------
+ * xpcUnknownReason     | the specified channel to the   | NULL or NA
+ *                      | specified partition was        |
+ *                      | unavailable for unknown reasons|
+ * =====================+================================+=====================
+ */
+
+typedef void (*xpc_channel_func)(enum xpc_retval reason, partid_t partid,
+               int ch_number, void *data, void *key);
+
+typedef void (*xpc_notify_func)(enum xpc_retval reason, partid_t partid,
+               int ch_number, void *key);
+
+
+/*
+ * The following is a registration entry. There is a global array of these,
+ * one per channel. It is used to record the connection registration made
+ * by the users of XPC. As long as a registration entry exists, for any
+ * partition that comes up, XPC will attempt to establish a connection on
+ * that channel. Notification that a connection has been made will occur via
+ * the xpc_channel_func function.
+ *
+ * The 'func' field points to the function to call when aynchronous
+ * notification is required for such events as: a connection established/lost,
+ * or an incomming message received, or an error condition encountered. A
+ * non-NULL 'func' field indicates that there is an active registration for
+ * the channel.
+ */
+struct xpc_registration {
+       struct semaphore sema;
+       xpc_channel_func func;          /* function to call */
+       void *key;                      /* pointer to user's key */
+       u16 nentries;                   /* #of msg entries in local msg queue */
+       u16 msg_size;                   /* message queue's message size */
+       u32 assigned_limit;             /* limit on #of assigned kthreads */
+       u32 idle_limit;                 /* limit on #of idle kthreads */
+} ____cacheline_aligned;
+
+
+#define XPC_CHANNEL_REGISTERED(_c)     (xpc_registrations[_c].func != NULL)
+
+
+/* the following are valid xpc_allocate() flags */
+#define XPC_WAIT       0               /* wait flag */
+#define XPC_NOWAIT     1               /* no wait flag */
+
+
+struct xpc_interface {
+       void (*connect)(int);
+       void (*disconnect)(int);
+       enum xpc_retval (*allocate)(partid_t, int, u32, void **);
+       enum xpc_retval (*send)(partid_t, int, void *);
+       enum xpc_retval (*send_notify)(partid_t, int, void *,
+                                               xpc_notify_func, void *);
+       void (*received)(partid_t, int, void *);
+       enum xpc_retval (*partid_to_nasids)(partid_t, void *);
+};
+
+
+extern struct xpc_interface xpc_interface;
+
+extern void xpc_set_interface(void (*)(int),
+               void (*)(int),
+               enum xpc_retval (*)(partid_t, int, u32, void **),
+               enum xpc_retval (*)(partid_t, int, void *),
+               enum xpc_retval (*)(partid_t, int, void *, xpc_notify_func,
+                                                               void *),
+               void (*)(partid_t, int, void *),
+               enum xpc_retval (*)(partid_t, void *));
+extern void xpc_clear_interface(void);
+
+
+extern enum xpc_retval xpc_connect(int, xpc_channel_func, void *, u16,
+                                               u16, u32, u32);
+extern void xpc_disconnect(int);
+
+static inline enum xpc_retval
+xpc_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
+{
+       return xpc_interface.allocate(partid, ch_number, flags, payload);
+}
+
+static inline enum xpc_retval
+xpc_send(partid_t partid, int ch_number, void *payload)
+{
+       return xpc_interface.send(partid, ch_number, payload);
+}
+
+static inline enum xpc_retval
+xpc_send_notify(partid_t partid, int ch_number, void *payload,
+                       xpc_notify_func func, void *key)
+{
+       return xpc_interface.send_notify(partid, ch_number, payload, func, key);
+}
+
+static inline void
+xpc_received(partid_t partid, int ch_number, void *payload)
+{
+       return xpc_interface.received(partid, ch_number, payload);
+}
+
+static inline enum xpc_retval
+xpc_partid_to_nasids(partid_t partid, void *nasids)
+{
+       return xpc_interface.partid_to_nasids(partid, nasids);
+}
+
+
+extern u64 xp_nofault_PIOR_target;
+extern int xp_nofault_PIOR(void *);
+extern int xp_error_PIOR(void);
+
+
+#endif /* _ASM_IA64_SN_XP_H */
+
index 6e55fd421883c74624c18ab251b8bfefea8ed313..95f69b1919537c0972a6486b9e53377e8573e830 100644 (file)
@@ -114,20 +114,7 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void __signalfn_t(int);
-typedef __signalfn_t __user *__sighandler_t;
-
-typedef void __restorefn_t(void);
-typedef __restorefn_t __user *__sigrestore_t;
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index 1d016e9f19bf2787ed71091711ad88b91e324eef..a0cdf908237244d598f2a63104822ea5bba3bb51 100644 (file)
@@ -105,29 +105,20 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
        __sighandler_t sa_handler;
        old_sigset_t sa_mask;
        unsigned long sa_flags;
-       void (*sa_restorer)(void);
+       __sigrestore_t sa_restorer;
 };
 
 struct sigaction {
        __sighandler_t sa_handler;
        unsigned long sa_flags;
-       void (*sa_restorer)(void);
+       __sigrestore_t sa_restorer;
        sigset_t sa_mask;               /* mask last for extensibility */
 };
 
index 37c9c8a024ba0bc8f3cff435c922b2ba1af46769..1d13187f60629885185bbfaf4757c2796e706655 100644 (file)
@@ -105,16 +105,7 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index d81356731eb6abee8e54e5d28d3c27832e7f2ef9..f2c470f1d369d1228aee9132f39d4c49bfac4460 100644 (file)
@@ -103,14 +103,7 @@ typedef unsigned long old_sigset_t;                /* at least 32 bits */
 #define SIG_SETMASK    3       /* for setting the signal mask */
 #define SIG_SETMASK32  256     /* Goodie from SGI for BSD compatibility:
                                   set only the low 32 bit of the sigset.  */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-/* Fake signal functions */
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 struct sigaction {
        unsigned int    sa_flags;
index 47f53df2cef556ec7e22e9745c19e6869f993306..ca3aed768cdc1a8d3a528790bf073401f38acc19 100644 (file)
@@ -235,7 +235,7 @@ static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
        return 0;
 }
 
-struct fd_routine_l {
+static struct fd_routine_l {
        int (*_request_dma)(unsigned int dmanr, const char * device_id);
        void (*_free_dma)(unsigned int dmanr);
        int (*_get_dma_residue)(unsigned int dummy);
index be27cfa8c5b0a3ccc5e5d91c240f65966f324e2a..ca9e423307f4c881f177260b83b390cebb61a1ff 100644 (file)
 #define flush_agp_mappings()
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+
 #endif
index 42fd1068cf2a4100f468f439f69c2da3c0fe5b38..c5883dbed63f8bbf84d8d1eeb11d6f77a93a62ac 100644 (file)
@@ -1039,6 +1039,52 @@ typedef struct im_idma {
 #define CMXSCR_TS4CS_CLK7  0x00000006   /* SCC4 Tx Clock Source is CLK7 */
 #define CMXSCR_TS4CS_CLK8  0x00000007   /* SCC4 Tx Clock Source is CLK8 */
 
+/*-----------------------------------------------------------------------
+ * SIUMCR - SIU Module Configuration Register                           4-31
+ */
+#define SIUMCR_BBD     0x80000000      /* Bus Busy Disable             */
+#define SIUMCR_ESE     0x40000000      /* External Snoop Enable        */
+#define SIUMCR_PBSE    0x20000000      /* Parity Byte Select Enable    */
+#define SIUMCR_CDIS    0x10000000      /* Core Disable                 */
+#define SIUMCR_DPPC00  0x00000000      /* Data Parity Pins Configuration*/
+#define SIUMCR_DPPC01  0x04000000      /* - " -                        */
+#define SIUMCR_DPPC10  0x08000000      /* - " -                        */
+#define SIUMCR_DPPC11  0x0c000000      /* - " -                        */
+#define SIUMCR_L2CPC00 0x00000000      /* L2 Cache Pins Configuration  */
+#define SIUMCR_L2CPC01 0x01000000      /* - " -                        */
+#define SIUMCR_L2CPC10 0x02000000      /* - " -                        */
+#define SIUMCR_L2CPC11 0x03000000      /* - " -                        */
+#define SIUMCR_LBPC00  0x00000000      /* Local Bus Pins Configuration */
+#define SIUMCR_LBPC01  0x00400000      /* - " -                        */
+#define SIUMCR_LBPC10  0x00800000      /* - " -                        */
+#define SIUMCR_LBPC11  0x00c00000      /* - " -                        */
+#define SIUMCR_APPC00  0x00000000      /* Address Parity Pins Configuration*/
+#define SIUMCR_APPC01  0x00100000      /* - " -                        */
+#define SIUMCR_APPC10  0x00200000      /* - " -                        */
+#define SIUMCR_APPC11  0x00300000      /* - " -                        */
+#define SIUMCR_CS10PC00        0x00000000      /* CS10 Pin Configuration       */
+#define SIUMCR_CS10PC01        0x00040000      /* - " -                        */
+#define SIUMCR_CS10PC10        0x00080000      /* - " -                        */
+#define SIUMCR_CS10PC11        0x000c0000      /* - " -                        */
+#define SIUMCR_BCTLC00 0x00000000      /* Buffer Control Configuration */
+#define SIUMCR_BCTLC01 0x00010000      /* - " -                        */
+#define SIUMCR_BCTLC10 0x00020000      /* - " -                        */
+#define SIUMCR_BCTLC11 0x00030000      /* - " -                        */
+#define SIUMCR_MMR00   0x00000000      /* Mask Masters Requests        */
+#define SIUMCR_MMR01   0x00004000      /* - " -                        */
+#define SIUMCR_MMR10   0x00008000      /* - " -                        */
+#define SIUMCR_MMR11   0x0000c000      /* - " -                        */
+#define SIUMCR_LPBSE   0x00002000      /* LocalBus Parity Byte Select Enable*/
+
+/*-----------------------------------------------------------------------
+ * SCCR - System Clock Control Register                                         9-8
+*/
+#define SCCR_PCI_MODE  0x00000100      /* PCI Mode     */
+#define SCCR_PCI_MODCK 0x00000080      /* Value of PCI_MODCK pin       */
+#define SCCR_PCIDF_MSK 0x00000078      /* PCI division factor  */
+#define SCCR_PCIDF_SHIFT 3
+
+
 #endif /* __CPM2__ */
 #endif /* __KERNEL__ */
 
index 163a6b91d5b2ffe0c49f9d9814a65a5bc23d0cd0..bf9e05dd54b5243d256f12c5e5df70f6b5a6c128 100644 (file)
@@ -19,6 +19,7 @@
  * Define the vendor/device ID for the MPC8265.
  */
 #define        PCI_DEVICE_ID_MPC8265   ((0x18C0 << 16) | PCI_VENDOR_ID_MOTOROLA)
+#define        PCI_DEVICE_ID_MPC8272   ((0x18C1 << 16) | PCI_VENDOR_ID_MOTOROLA)
 
 #define M8265_PCIBR0   0x101ac
 #define M8265_PCIBR1   0x101b0
index d820894e59916a4c491b8bdd0312830acec228a9..89eb8a2ac6934552eeaf74d5ed222690ed504732 100644 (file)
@@ -41,7 +41,7 @@
 #endif
 
 #ifdef CONFIG_PCI_8260
-#include <syslib/m8260_pci.h>
+#include <syslib/m82xx_pci.h>
 #endif
 
 /* Make sure the memory translation stuff is there if PCI not used.
index f82dcccdee1e974c770b9dfe8c7aeb20ce144872..b7a417e0a9217c758384d4227975b7580a33902b 100644 (file)
@@ -2,7 +2,7 @@
 #define _ASM_PPC_SIGCONTEXT_H
 
 #include <asm/ptrace.h>
-
+#include <linux/compiler.h>
 
 struct sigcontext {
        unsigned long   _unused[4];
index d890dabd5a69ba983719f73518604db667652707..caf6ede3710f7a7b1e71b9923ff5f24c5c75e70a 100644 (file)
@@ -100,20 +100,7 @@ typedef struct {
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void __signalfn_t(int);
-typedef __signalfn_t __user *__sighandler_t;
-
-typedef void __restorefn_t(void);
-typedef __restorefn_t __user *__sigrestore_t;
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 struct old_sigaction {
        __sighandler_t sa_handler;
index be27cfa8c5b0a3ccc5e5d91c240f65966f324e2a..ca9e423307f4c881f177260b83b390cebb61a1ff 100644 (file)
 #define flush_agp_mappings()
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+
 #endif
index 6c42d61bedd13447e219150362a0dbc7e058734a..085eedb956fe02f7a0f34c1cbea0895e476b00ee 100644 (file)
@@ -221,9 +221,7 @@ do {                                                                \
                set_thread_flag(TIF_ABI_PENDING);               \
        else                                                    \
                clear_thread_flag(TIF_ABI_PENDING);             \
-       if (ibcs2)                                              \
-               set_personality(PER_SVR4);                      \
-       else if (current->personality != PER_LINUX32)           \
+       if (personality(current->personality) != PER_LINUX32)   \
                set_personality(PER_LINUX);                     \
 } while (0)
 
index 2e59a8e15a0b57848a61299684380c1951cea40a..db333e1ee216aaac2887b9818fcda48068ec65ff 100644 (file)
@@ -52,6 +52,7 @@ extern void mf_clear_src(void);
 extern void mf_init(void);
 
 extern int mf_get_rtc(struct rtc_time *tm);
+extern int mf_get_boot_rtc(struct rtc_time *tm);
 extern int mf_set_rtc(struct rtc_time *tm);
 
 #endif /* _ASM_PPC64_ISERIES_MF_H */
diff --git a/include/asm-ppc64/imalloc.h b/include/asm-ppc64/imalloc.h
new file mode 100644 (file)
index 0000000..3a45e91
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _PPC64_IMALLOC_H
+#define _PPC64_IMALLOC_H
+
+/*
+ * Define the address range of the imalloc VM area.
+ */
+#define PHBS_IO_BASE     IOREGIONBASE
+#define IMALLOC_BASE      (IOREGIONBASE + 0x80000000ul)        /* Reserve 2 gigs for PHBs */
+#define IMALLOC_END       (IOREGIONBASE + EADDR_MASK)
+
+
+/* imalloc region types */
+#define IM_REGION_UNUSED       0x1
+#define IM_REGION_SUBSET       0x2
+#define IM_REGION_EXISTS       0x4
+#define IM_REGION_OVERLAP      0x8
+#define IM_REGION_SUPERSET     0x10
+
+extern struct vm_struct * im_get_free_area(unsigned long size);
+extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
+                       int region_type);
+unsigned long im_free(void *addr);
+
+#endif /* _PPC64_IMALLOC_H */
index 188987e9d9d4ed524d4664d862e7e1a4fe2d815d..c78282a67d8ede88df9cafb7b3f7090fb2ffa3a7 100644 (file)
 
 #include <linux/config.h>
 #include <asm/page.h>
-#include <linux/stringify.h>
 
-#ifndef __ASSEMBLY__
-
-/* Time to allow for more things here */
-typedef unsigned long mm_context_id_t;
-typedef struct {
-       mm_context_id_t id;
-#ifdef CONFIG_HUGETLB_PAGE
-       pgd_t *huge_pgdir;
-       u16 htlb_segs; /* bitmask */
-#endif
-} mm_context_t;
+/*
+ * Segment table
+ */
 
 #define STE_ESID_V     0x80
 #define STE_ESID_KS    0x20
@@ -36,15 +27,48 @@ typedef struct {
 
 #define STE_VSID_SHIFT 12
 
-struct stab_entry {
-       unsigned long esid_data;
-       unsigned long vsid_data;
-};
+/* Location of cpu0's segment table */
+#define STAB0_PAGE     0x9
+#define STAB0_PHYS_ADDR        (STAB0_PAGE<<PAGE_SHIFT)
+#define STAB0_VIRT_ADDR        (KERNELBASE+STAB0_PHYS_ADDR)
+
+/*
+ * SLB
+ */
 
-/* Hardware Page Table Entry */
+#define SLB_NUM_BOLTED         3
+#define SLB_CACHE_ENTRIES      8
+
+/* Bits in the SLB ESID word */
+#define SLB_ESID_V             ASM_CONST(0x0000000008000000) /* valid */
+
+/* Bits in the SLB VSID word */
+#define SLB_VSID_SHIFT         12
+#define SLB_VSID_KS            ASM_CONST(0x0000000000000800)
+#define SLB_VSID_KP            ASM_CONST(0x0000000000000400)
+#define SLB_VSID_N             ASM_CONST(0x0000000000000200) /* no-execute */
+#define SLB_VSID_L             ASM_CONST(0x0000000000000100) /* largepage 16M */
+#define SLB_VSID_C             ASM_CONST(0x0000000000000080) /* class */
+
+#define SLB_VSID_KERNEL                (SLB_VSID_KP|SLB_VSID_C)
+#define SLB_VSID_USER          (SLB_VSID_KP|SLB_VSID_KS)
+
+/*
+ * Hash table
+ */
 
 #define HPTES_PER_GROUP 8
 
+/* Values for PP (assumes Ks=0, Kp=1) */
+/* pp0 will always be 0 for linux     */
+#define PP_RWXX        0       /* Supervisor read/write, User none */
+#define PP_RWRX 1      /* Supervisor read/write, User read */
+#define PP_RWRW 2      /* Supervisor read/write, User read/write */
+#define PP_RXRX 3      /* Supervisor read,       User read */
+
+#ifndef __ASSEMBLY__
+
+/* Hardware Page Table Entry */
 typedef struct {
        unsigned long avpn:57; /* vsid | api == avpn  */
        unsigned long :     2; /* Software use */
@@ -90,14 +114,6 @@ typedef struct {
        } dw1;
 } HPTE; 
 
-/* Values for PP (assumes Ks=0, Kp=1) */
-/* pp0 will always be 0 for linux     */
-#define PP_RWXX        0       /* Supervisor read/write, User none */
-#define PP_RWRX 1      /* Supervisor read/write, User read */
-#define PP_RWRW 2      /* Supervisor read/write, User read/write */
-#define PP_RXRX 3      /* Supervisor read,       User read */
-
-
 extern HPTE *          htab_address;
 extern unsigned long   htab_hash_mask;
 
@@ -174,31 +190,70 @@ extern int __hash_page(unsigned long ea, unsigned long access,
 
 extern void htab_finish_init(void);
 
+extern void hpte_init_native(void);
+extern void hpte_init_lpar(void);
+extern void hpte_init_iSeries(void);
+
+extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
+                                    unsigned long va, unsigned long prpn,
+                                    int secondary, unsigned long hpteflags,
+                                    int bolted, int large);
+extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
+                              unsigned long prpn, int secondary,
+                              unsigned long hpteflags, int bolted, int large);
+
 #endif /* __ASSEMBLY__ */
 
 /*
- * Location of cpu0's segment table
+ * VSID allocation
+ *
+ * We first generate a 36-bit "proto-VSID".  For kernel addresses this
+ * is equal to the ESID, for user addresses it is:
+ *     (context << 15) | (esid & 0x7fff)
+ *
+ * The two forms are distinguishable because the top bit is 0 for user
+ * addresses, whereas the top two bits are 1 for kernel addresses.
+ * Proto-VSIDs with the top two bits equal to 0b10 are reserved for
+ * now.
+ *
+ * The proto-VSIDs are then scrambled into real VSIDs with the
+ * multiplicative hash:
+ *
+ *     VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS
+ *     where   VSID_MULTIPLIER = 268435399 = 0xFFFFFC7
+ *             VSID_MODULUS = 2^36-1 = 0xFFFFFFFFF
+ *
+ * This scramble is only well defined for proto-VSIDs below
+ * 0xFFFFFFFFF, so both proto-VSID and actual VSID 0xFFFFFFFFF are
+ * reserved.  VSID_MULTIPLIER is prime, so in particular it is
+ * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
+ * Because the modulus is 2^n-1 we can compute it efficiently without
+ * a divide or extra multiply (see below).
+ *
+ * This scheme has several advantages over older methods:
+ *
+ *     - We have VSIDs allocated for every kernel address
+ * (i.e. everything above 0xC000000000000000), except the very top
+ * segment, which simplifies several things.
+ *
+ *     - We allow for 15 significant bits of ESID and 20 bits of
+ * context for user addresses.  i.e. 8T (43 bits) of address space for
+ * up to 1M contexts (although the page table structure and context
+ * allocation will need changes to take advantage of this).
+ *
+ *     - The scramble function gives robust scattering in the hash
+ * table (at least based on some initial results).  The previous
+ * method was more susceptible to pathological cases giving excessive
+ * hash collisions.
+ */
+/*
+ * WARNING - If you change these you must make sure the asm
+ * implementations in slb_allocate (slb_low.S), do_stab_bolted
+ * (head.S) and ASM_VSID_SCRAMBLE (below) are changed accordingly.
+ *
+ * You'll also need to change the precomputed VSID values in head.S
+ * which are used by the iSeries firmware.
  */
-#define STAB0_PAGE     0x9
-#define STAB0_PHYS_ADDR        (STAB0_PAGE<<PAGE_SHIFT)
-#define STAB0_VIRT_ADDR        (KERNELBASE+STAB0_PHYS_ADDR)
-
-#define SLB_NUM_BOLTED         3
-#define SLB_CACHE_ENTRIES      8
-
-/* Bits in the SLB ESID word */
-#define SLB_ESID_V             0x0000000008000000      /* entry is valid */
-
-/* Bits in the SLB VSID word */
-#define SLB_VSID_SHIFT         12
-#define SLB_VSID_KS            0x0000000000000800
-#define SLB_VSID_KP            0x0000000000000400
-#define SLB_VSID_N             0x0000000000000200      /* no-execute */
-#define SLB_VSID_L             0x0000000000000100      /* largepage (4M) */
-#define SLB_VSID_C             0x0000000000000080      /* class */
-
-#define SLB_VSID_KERNEL                (SLB_VSID_KP|SLB_VSID_C)
-#define SLB_VSID_USER          (SLB_VSID_KP|SLB_VSID_KS)
 
 #define VSID_MULTIPLIER        ASM_CONST(200730139)    /* 28-bit prime */
 #define VSID_BITS      36
@@ -239,4 +294,50 @@ extern void htab_finish_init(void);
        srdi    rx,rx,VSID_BITS;        /* extract 2^36 bit */          \
        add     rt,rt,rx
 
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long mm_context_id_t;
+
+typedef struct {
+       mm_context_id_t id;
+#ifdef CONFIG_HUGETLB_PAGE
+       pgd_t *huge_pgdir;
+       u16 htlb_segs; /* bitmask */
+#endif
+} mm_context_t;
+
+
+static inline unsigned long vsid_scramble(unsigned long protovsid)
+{
+#if 0
+       /* The code below is equivalent to this function for arguments
+        * < 2^VSID_BITS, which is all this should ever be called
+        * with.  However gcc is not clever enough to compute the
+        * modulus (2^n-1) without a second multiply. */
+       return ((protovsid * VSID_MULTIPLIER) % VSID_MODULUS);
+#else /* 1 */
+       unsigned long x;
+
+       x = protovsid * VSID_MULTIPLIER;
+       x = (x >> VSID_BITS) + (x & VSID_MODULUS);
+       return (x + ((x+1) >> VSID_BITS)) & VSID_MODULUS;
+#endif /* 1 */
+}
+
+/* This is only valid for addresses >= KERNELBASE */
+static inline unsigned long get_kernel_vsid(unsigned long ea)
+{
+       return vsid_scramble(ea >> SID_SHIFT);
+}
+
+/* This is only valid for user addresses (which are below 2^41) */
+static inline unsigned long get_vsid(unsigned long context, unsigned long ea)
+{
+       return vsid_scramble((context << USER_ESID_BITS)
+                            | (ea >> SID_SHIFT));
+}
+
+#endif /* __ASSEMBLY */
+
 #endif /* _PPC64_MMU_H_ */
index c2e8e046638308653f7f7b8a7c2f5a66a98318ab..77a743402db40c1e7710fc22d7e4d304955c7da8 100644 (file)
@@ -84,86 +84,4 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
        local_irq_restore(flags);
 }
 
-/* VSID allocation
- * ===============
- *
- * We first generate a 36-bit "proto-VSID".  For kernel addresses this
- * is equal to the ESID, for user addresses it is:
- *     (context << 15) | (esid & 0x7fff)
- *
- * The two forms are distinguishable because the top bit is 0 for user
- * addresses, whereas the top two bits are 1 for kernel addresses.
- * Proto-VSIDs with the top two bits equal to 0b10 are reserved for
- * now.
- *
- * The proto-VSIDs are then scrambled into real VSIDs with the
- * multiplicative hash:
- *
- *     VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS
- *     where   VSID_MULTIPLIER = 268435399 = 0xFFFFFC7
- *             VSID_MODULUS = 2^36-1 = 0xFFFFFFFFF
- *
- * This scramble is only well defined for proto-VSIDs below
- * 0xFFFFFFFFF, so both proto-VSID and actual VSID 0xFFFFFFFFF are
- * reserved.  VSID_MULTIPLIER is prime, so in particular it is
- * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
- * Because the modulus is 2^n-1 we can compute it efficiently without
- * a divide or extra multiply (see below).
- *
- * This scheme has several advantages over older methods:
- *
- *     - We have VSIDs allocated for every kernel address
- * (i.e. everything above 0xC000000000000000), except the very top
- * segment, which simplifies several things.
- *
- *     - We allow for 15 significant bits of ESID and 20 bits of
- * context for user addresses.  i.e. 8T (43 bits) of address space for
- * up to 1M contexts (although the page table structure and context
- * allocation will need changes to take advantage of this).
- *
- *     - The scramble function gives robust scattering in the hash
- * table (at least based on some initial results).  The previous
- * method was more susceptible to pathological cases giving excessive
- * hash collisions.
- */
-
-/*
- * WARNING - If you change these you must make sure the asm
- * implementations in slb_allocate(), do_stab_bolted and mmu.h
- * (ASM_VSID_SCRAMBLE macro) are changed accordingly.
- *
- * You'll also need to change the precomputed VSID values in head.S
- * which are used by the iSeries firmware.
- */
-
-static inline unsigned long vsid_scramble(unsigned long protovsid)
-{
-#if 0
-       /* The code below is equivalent to this function for arguments
-        * < 2^VSID_BITS, which is all this should ever be called
-        * with.  However gcc is not clever enough to compute the
-        * modulus (2^n-1) without a second multiply. */
-       return ((protovsid * VSID_MULTIPLIER) % VSID_MODULUS);
-#else /* 1 */
-       unsigned long x;
-
-       x = protovsid * VSID_MULTIPLIER;
-       x = (x >> VSID_BITS) + (x & VSID_MODULUS);
-       return (x + ((x+1) >> VSID_BITS)) & VSID_MODULUS;
-#endif /* 1 */
-}
-
-/* This is only valid for addresses >= KERNELBASE */
-static inline unsigned long get_kernel_vsid(unsigned long ea)
-{
-       return vsid_scramble(ea >> SID_SHIFT);
-}
-
-/* This is only valid for user addresses (which are below 2^41) */
-static inline unsigned long get_vsid(unsigned long context, unsigned long ea)
-{
-       return vsid_scramble((context << USER_ESID_BITS)
-                            | (ea >> SID_SHIFT));
-}
-
 #endif /* __PPC64_MMU_CONTEXT_H */
index 86219574c1a53cdf5f940a64bade4e4ea3073255..bcd21789d3b7816e2e53e85dac6515b347c101cd 100644 (file)
@@ -23,7 +23,6 @@
 #define PAGE_SHIFT     12
 #define PAGE_SIZE      (ASM_CONST(1) << PAGE_SHIFT)
 #define PAGE_MASK      (~(PAGE_SIZE-1))
-#define PAGE_OFFSET_MASK (PAGE_SIZE-1)
 
 #define SID_SHIFT       28
 #define SID_MASK        0xfffffffffUL
@@ -85,9 +84,6 @@
 /* align addr on a size boundary - adjust address up if needed */
 #define _ALIGN(addr,size)     _ALIGN_UP(addr,size)
 
-/* to align the pointer to the (next) double word boundary */
-#define DOUBLEWORD_ALIGN(addr) _ALIGN(addr,sizeof(unsigned long))
-
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)       _ALIGN(addr, PAGE_SIZE)
 
 #define REGION_SIZE   4UL
 #define REGION_SHIFT  60UL
 #define REGION_MASK   (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
-#define REGION_STRIDE (1UL << REGION_SHIFT)
 
 static __inline__ void clear_page(void *addr)
 {
@@ -209,13 +204,13 @@ extern u64 ppc64_pft_size;                /* Log 2 of page table size */
 #define VMALLOCBASE     ASM_CONST(0xD000000000000000)
 #define IOREGIONBASE    ASM_CONST(0xE000000000000000)
 
-#define IO_REGION_ID       (IOREGIONBASE>>REGION_SHIFT)
-#define VMALLOC_REGION_ID  (VMALLOCBASE>>REGION_SHIFT)
-#define KERNEL_REGION_ID   (KERNELBASE>>REGION_SHIFT)
+#define IO_REGION_ID       (IOREGIONBASE >> REGION_SHIFT)
+#define VMALLOC_REGION_ID  (VMALLOCBASE >> REGION_SHIFT)
+#define KERNEL_REGION_ID   (KERNELBASE >> REGION_SHIFT)
 #define USER_REGION_ID     (0UL)
-#define REGION_ID(X)      (((unsigned long)(X))>>REGION_SHIFT)
+#define REGION_ID(ea)     (((unsigned long)(ea)) >> REGION_SHIFT)
 
-#define __bpn_to_ba(x) ((((unsigned long)(x))<<PAGE_SHIFT) + KERNELBASE)
+#define __bpn_to_ba(x) ((((unsigned long)(x)) << PAGE_SHIFT) + KERNELBASE)
 #define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT)
 
 #define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
index b984e2747e0cf362c667d07f6621a1545b8017a2..264c4f7993be3557a6b5932bf8dcf943b7c8fd8e 100644 (file)
 
 #include <asm-generic/pgtable-nopud.h>
 
-/* PMD_SHIFT determines what a second-level page table entry can map */
-#define PMD_SHIFT      (PAGE_SHIFT + PAGE_SHIFT - 3)
-#define PMD_SIZE       (1UL << PMD_SHIFT)
-#define PMD_MASK       (~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT    (PAGE_SHIFT + (PAGE_SHIFT - 3) + (PAGE_SHIFT - 2))
-#define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK     (~(PGDIR_SIZE-1))
-
 /*
  * Entries per page directory level.  The PTE level must use a 64b record
  * for each page table entry.  The PMD and PGD level use a 32b record for 
 #define PTRS_PER_PMD   (1 << PMD_INDEX_SIZE)
 #define PTRS_PER_PGD   (1 << PGD_INDEX_SIZE)
 
-#define USER_PTRS_PER_PGD      (1024)
-#define FIRST_USER_ADDRESS     0
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT      (PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE       (1UL << PMD_SHIFT)
+#define PMD_MASK       (~(PMD_SIZE-1))
 
-#define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
-                    PGD_INDEX_SIZE + PAGE_SHIFT) 
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT    (PMD_SHIFT + PMD_INDEX_SIZE)
+#define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK     (~(PGDIR_SIZE-1))
+
+#define FIRST_USER_ADDRESS     0
 
 /*
  * Size of EA range mapped by our pagetables.
  */
-#define PGTABLE_EA_BITS        41
-#define PGTABLE_EA_MASK        ((1UL<<PGTABLE_EA_BITS)-1)
+#define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
+                    PGD_INDEX_SIZE + PAGE_SHIFT)
+#define EADDR_MASK ((1UL << EADDR_SIZE) - 1)
 
 /*
  * Define the address range of the vmalloc VM area.
  */
 #define VMALLOC_START (0xD000000000000000ul)
-#define VMALLOC_END   (VMALLOC_START + PGTABLE_EA_MASK)
-
-/*
- * Define the address range of the imalloc VM area.
- * (used for ioremap)
- */
-#define IMALLOC_START     (ioremap_bot)
-#define IMALLOC_VMADDR(x) ((unsigned long)(x))
-#define PHBS_IO_BASE     (0xE000000000000000ul)        /* Reserve 2 gigs for PHBs */
-#define IMALLOC_BASE      (0xE000000080000000ul)  
-#define IMALLOC_END       (IMALLOC_BASE + PGTABLE_EA_MASK)
-
-/*
- * Define the user address range
- */
-#define USER_START (0UL)
-#define USER_END   (USER_START + PGTABLE_EA_MASK)
-
+#define VMALLOC_END   (VMALLOC_START + EADDR_MASK)
 
 /*
  * Bits in a linux-style PTE.  These match the bits in the
@@ -168,10 +148,6 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
 /* shift to put page number into pte */
 #define PTE_SHIFT (17)
 
-/* We allow 2^41 bytes of real memory, so we need 29 bits in the PMD
- * to give the PTE page number.  The bottom two bits are for flags. */
-#define PMD_TO_PTEPAGE_SHIFT (2)
-
 #ifdef CONFIG_HUGETLB_PAGE
 
 #ifndef __ASSEMBLY__
@@ -200,13 +176,14 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm);
  */
 #define mk_pte(page, pgprot)   pfn_pte(page_to_pfn(page), (pgprot))
 
-#define pfn_pte(pfn,pgprot)                                            \
-({                                                                     \
-       pte_t pte;                                                      \
-       pte_val(pte) = ((unsigned long)(pfn) << PTE_SHIFT) |            \
-                        pgprot_val(pgprot);                            \
-       pte;                                                            \
-})
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
+{
+       pte_t pte;
+
+
+       pte_val(pte) = (pfn << PTE_SHIFT) | pgprot_val(pgprot);
+       return pte;
+}
 
 #define pte_modify(_pte, newprot) \
   (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
@@ -220,13 +197,12 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm);
 #define pte_page(x)            pfn_to_page(pte_pfn(x))
 
 #define pmd_set(pmdp, ptep)    \
-       (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep) << PMD_TO_PTEPAGE_SHIFT))
+       (pmd_val(*(pmdp)) = __ba_to_bpn(ptep))
 #define pmd_none(pmd)          (!pmd_val(pmd))
 #define        pmd_bad(pmd)            (pmd_val(pmd) == 0)
 #define        pmd_present(pmd)        (pmd_val(pmd) != 0)
 #define        pmd_clear(pmdp)         (pmd_val(*(pmdp)) = 0)
-#define pmd_page_kernel(pmd)   \
-       (__bpn_to_ba(pmd_val(pmd) >> PMD_TO_PTEPAGE_SHIFT))
+#define pmd_page_kernel(pmd)   (__bpn_to_ba(pmd_val(pmd)))
 #define pmd_page(pmd)          virt_to_page(pmd_page_kernel(pmd))
 
 #define pud_set(pudp, pmdp)    (pud_val(*(pudp)) = (__ba_to_bpn(pmdp)))
@@ -266,8 +242,6 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm);
 /* to find an entry in the ioremap page-table-directory */
 #define pgd_offset_i(address) (ioremap_pgd + pgd_index(address))
 
-#define pages_to_mb(x)         ((x) >> (20-PAGE_SHIFT))
-
 /*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
@@ -442,7 +416,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
                pte_clear(mm, addr, ptep);
                flush_tlb_pending();
        }
-       *ptep = __pte(pte_val(pte)) & ~_PAGE_HPTEFLAGS;
+       *ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
 }
 
 /* Set the dirty and/or accessed bits atomically in a linux PTE, this
@@ -487,18 +461,13 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr,
 
 extern unsigned long ioremap_bot, ioremap_base;
 
-#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
-#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
-
-#define pte_ERROR(e) \
-       printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
 #define pmd_ERROR(e) \
        printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e))
 #define pgd_ERROR(e) \
        printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e))
 
-extern pgd_t swapper_pg_dir[1024];
-extern pgd_t ioremap_dir[1024];
+extern pgd_t swapper_pg_dir[];
+extern pgd_t ioremap_dir[];
 
 extern void paging_init(void);
 
@@ -540,43 +509,11 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
  */
 #define kern_addr_valid(addr)  (1)
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)             \
-               remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)                \
                remap_pfn_range(vma, vaddr, pfn, size, prot)
 
-#define MK_IOSPACE_PFN(space, pfn)     (pfn)
-#define GET_IOSPACE(pfn)               0
-#define GET_PFN(pfn)                   (pfn)
-
 void pgtable_cache_init(void);
 
-extern void hpte_init_native(void);
-extern void hpte_init_lpar(void);
-extern void hpte_init_iSeries(void);
-
-/* imalloc region types */
-#define IM_REGION_UNUSED       0x1
-#define IM_REGION_SUBSET       0x2
-#define IM_REGION_EXISTS       0x4
-#define IM_REGION_OVERLAP      0x8
-#define IM_REGION_SUPERSET     0x10
-
-extern struct vm_struct * im_get_free_area(unsigned long size);
-extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
-                       int region_type);
-unsigned long im_free(void *addr);
-
-extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
-                                    unsigned long va, unsigned long prpn,
-                                    int secondary, unsigned long hpteflags,
-                                    int bolted, int large);
-
-extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
-                              unsigned long prpn, int secondary,
-                              unsigned long hpteflags, int bolted, int large);
-
 /*
  * find_linux_pte returns the address of a linux pte for a given 
  * effective address and directory.  If not found, it returns zero.
index 0035efe2db2ba7591fce0f6be861e6f23b7ecfd6..809c634ba1dfa03e41078b737a3f0be4945f7314 100644 (file)
 
 /* Special Purpose Registers (SPRNs)*/
 
-#define        SPRN_CDBCR      0x3D7   /* Cache Debug Control Register */
 #define        SPRN_CTR        0x009   /* Count Register */
 #define        SPRN_DABR       0x3F5   /* Data Address Breakpoint Register */
-#define        SPRN_DAC1       0x3F6   /* Data Address Compare 1 */
-#define        SPRN_DAC2       0x3F7   /* Data Address Compare 2 */
+#define   DABR_TRANSLATION     (1UL << 2)
 #define        SPRN_DAR        0x013   /* Data Address Register */
-#define        SPRN_DBCR       0x3F2   /* Debug Control Regsiter */
-#define          DBCR_EDM      0x80000000
-#define          DBCR_IDM      0x40000000
-#define          DBCR_RST(x)   (((x) & 0x3) << 28)
-#define            DBCR_RST_NONE               0
-#define            DBCR_RST_CORE               1
-#define            DBCR_RST_CHIP               2
-#define            DBCR_RST_SYSTEM             3
-#define          DBCR_IC       0x08000000      /* Instruction Completion Debug Evnt */
-#define          DBCR_BT       0x04000000      /* Branch Taken Debug Event */
-#define          DBCR_EDE      0x02000000      /* Exception Debug Event */
-#define          DBCR_TDE      0x01000000      /* TRAP Debug Event */
-#define          DBCR_FER      0x00F80000      /* First Events Remaining Mask */
-#define          DBCR_FT       0x00040000      /* Freeze Timers on Debug Event */
-#define          DBCR_IA1      0x00020000      /* Instr. Addr. Compare 1 Enable */
-#define          DBCR_IA2      0x00010000      /* Instr. Addr. Compare 2 Enable */
-#define          DBCR_D1R      0x00008000      /* Data Addr. Compare 1 Read Enable */
-#define          DBCR_D1W      0x00004000      /* Data Addr. Compare 1 Write Enable */
-#define          DBCR_D1S(x)   (((x) & 0x3) << 12)     /* Data Adrr. Compare 1 Size */
-#define            DAC_BYTE    0
-#define            DAC_HALF    1
-#define            DAC_WORD    2
-#define            DAC_QUAD    3
-#define          DBCR_D2R      0x00000800      /* Data Addr. Compare 2 Read Enable */
-#define          DBCR_D2W      0x00000400      /* Data Addr. Compare 2 Write Enable */
-#define          DBCR_D2S(x)   (((x) & 0x3) << 8)      /* Data Addr. Compare 2 Size */
-#define          DBCR_SBT      0x00000040      /* Second Branch Taken Debug Event */
-#define          DBCR_SED      0x00000020      /* Second Exception Debug Event */
-#define          DBCR_STD      0x00000010      /* Second Trap Debug Event */
-#define          DBCR_SIA      0x00000008      /* Second IAC Enable */
-#define          DBCR_SDA      0x00000004      /* Second DAC Enable */
-#define          DBCR_JOI      0x00000002      /* JTAG Serial Outbound Int. Enable */
-#define          DBCR_JII      0x00000001      /* JTAG Serial Inbound Int. Enable */
-#define        SPRN_DBCR0      0x3F2   /* Debug Control Register 0 */
-#define        SPRN_DBCR1      0x3BD   /* Debug Control Register 1 */
-#define        SPRN_DBSR       0x3F0   /* Debug Status Register */
-#define        SPRN_DCCR       0x3FA   /* Data Cache Cacheability Register */
-#define          DCCR_NOCACHE          0       /* Noncacheable */
-#define          DCCR_CACHE            1       /* Cacheable */
-#define        SPRN_DCMP       0x3D1   /* Data TLB Compare Register */
-#define        SPRN_DCWR       0x3BA   /* Data Cache Write-thru Register */
-#define          DCWR_COPY             0       /* Copy-back */
-#define          DCWR_WRITE            1       /* Write-through */
-#define        SPRN_DEAR       0x3D5   /* Data Error Address Register */
 #define        SPRN_DEC        0x016   /* Decrement Register */
-#define        SPRN_DMISS      0x3D0   /* Data TLB Miss Register */
 #define        SPRN_DSISR      0x012   /* Data Storage Interrupt Status Register */
 #define   DSISR_NOHPTE         0x40000000      /* no translation found */
 #define   DSISR_PROTFAULT      0x08000000      /* protection fault */
 #define   DSISR_ISSTORE                0x02000000      /* access was a store */
 #define   DSISR_DABRMATCH      0x00400000      /* hit data breakpoint */
 #define   DSISR_NOSEGMENT      0x00200000      /* STAB/SLB miss */
-#define        SPRN_EAR        0x11A   /* External Address Register */
-#define        SPRN_ESR        0x3D4   /* Exception Syndrome Register */
-#define          ESR_IMCP      0x80000000      /* Instr. Machine Check - Protection */
-#define          ESR_IMCN      0x40000000      /* Instr. Machine Check - Non-config */
-#define          ESR_IMCB      0x20000000      /* Instr. Machine Check - Bus error */
-#define          ESR_IMCT      0x10000000      /* Instr. Machine Check - Timeout */
-#define          ESR_PIL       0x08000000      /* Program Exception - Illegal */
-#define          ESR_PPR       0x04000000      /* Program Exception - Priveleged */
-#define          ESR_PTR       0x02000000      /* Program Exception - Trap */
-#define          ESR_DST       0x00800000      /* Storage Exception - Data miss */
-#define          ESR_DIZ       0x00400000      /* Storage Exception - Zone fault */
-#define        SPRN_EVPR       0x3D6   /* Exception Vector Prefix Register */
-#define        SPRN_HASH1      0x3D2   /* Primary Hash Address Register */
-#define        SPRN_HASH2      0x3D3   /* Secondary Hash Address Resgister */
 #define        SPRN_HID0       0x3F0   /* Hardware Implementation Register 0 */
-#define          HID0_EMCP     (1<<31)         /* Enable Machine Check pin */
-#define          HID0_EBA      (1<<29)         /* Enable Bus Address Parity */
-#define          HID0_EBD      (1<<28)         /* Enable Bus Data Parity */
-#define          HID0_SBCLK    (1<<27)
-#define          HID0_EICE     (1<<26)
-#define          HID0_ECLK     (1<<25)
-#define          HID0_PAR      (1<<24)
-#define          HID0_DOZE     (1<<23)
-#define          HID0_NAP      (1<<22)
-#define          HID0_SLEEP    (1<<21)
-#define          HID0_DPM      (1<<20)
-#define          HID0_ICE      (1<<15)         /* Instruction Cache Enable */
-#define          HID0_DCE      (1<<14)         /* Data Cache Enable */
-#define          HID0_ILOCK    (1<<13)         /* Instruction Cache Lock */
-#define          HID0_DLOCK    (1<<12)         /* Data Cache Lock */
-#define          HID0_ICFI     (1<<11)         /* Instr. Cache Flash Invalidate */
-#define          HID0_DCI      (1<<10)         /* Data Cache Invalidate */
-#define   HID0_SPD     (1<<9)          /* Speculative disable */
-#define   HID0_SGE     (1<<7)          /* Store Gathering Enable */
-#define          HID0_SIED     (1<<7)          /* Serial Instr. Execution [Disable] */
-#define   HID0_BTIC    (1<<5)          /* Branch Target Instruction Cache Enable */
-#define   HID0_ABE     (1<<3)          /* Address Broadcast Enable */
-#define          HID0_BHTE     (1<<2)          /* Branch History Table Enable */
-#define          HID0_BTCD     (1<<1)          /* Branch target cache disable */
 #define        SPRN_MSRDORM    0x3F1   /* Hardware Implementation Register 1 */
 #define SPRN_HID1      0x3F1   /* Hardware Implementation Register 1 */
 #define        SPRN_IABR       0x3F2   /* Instruction Address Breakpoint Register */
 #define SPRN_HID5      0x3F6   /* 970 HID5 */
 #define        SPRN_TSC        0x3FD   /* Thread switch control */
 #define        SPRN_TST        0x3FC   /* Thread switch timeout */
-#define        SPRN_IAC1       0x3F4   /* Instruction Address Compare 1 */
-#define        SPRN_IAC2       0x3F5   /* Instruction Address Compare 2 */
-#define        SPRN_ICCR       0x3FB   /* Instruction Cache Cacheability Register */
-#define          ICCR_NOCACHE          0       /* Noncacheable */
-#define          ICCR_CACHE            1       /* Cacheable */
-#define        SPRN_ICDBDR     0x3D3   /* Instruction Cache Debug Data Register */
-#define        SPRN_ICMP       0x3D5   /* Instruction TLB Compare Register */
-#define        SPRN_ICTC       0x3FB   /* Instruction Cache Throttling Control Reg */
-#define        SPRN_IMISS      0x3D4   /* Instruction TLB Miss Register */
-#define        SPRN_IMMR       0x27E   /* Internal Memory Map Register */
 #define        SPRN_L2CR       0x3F9   /* Level 2 Cache Control Regsiter */
 #define        SPRN_LR         0x008   /* Link Register */
-#define        SPRN_PBL1       0x3FC   /* Protection Bound Lower 1 */
-#define        SPRN_PBL2       0x3FE   /* Protection Bound Lower 2 */
-#define        SPRN_PBU1       0x3FD   /* Protection Bound Upper 1 */
-#define        SPRN_PBU2       0x3FF   /* Protection Bound Upper 2 */
-#define        SPRN_PID        0x3B1   /* Process ID */
 #define        SPRN_PIR        0x3FF   /* Processor Identification Register */
 #define        SPRN_PIT        0x3DB   /* Programmable Interval Timer */
 #define        SPRN_PURR       0x135   /* Processor Utilization of Resources Register */
 #define        SPRN_RPA        0x3D6   /* Required Physical Address Register */
 #define        SPRN_SDA        0x3BF   /* Sampled Data Address Register */
 #define        SPRN_SDR1       0x019   /* MMU Hash Base Register */
-#define        SPRN_SGR        0x3B9   /* Storage Guarded Register */
-#define          SGR_NORMAL            0
-#define          SGR_GUARDED           1
 #define        SPRN_SIA        0x3BB   /* Sampled Instruction Address Register */
 #define        SPRN_SPRG0      0x110   /* Special Purpose Register General 0 */
 #define        SPRN_SPRG1      0x111   /* Special Purpose Register General 1 */
 #define        SPRN_TBWL       0x11C   /* Time Base Lower Register (super, W/O) */
 #define        SPRN_TBWU       0x11D   /* Time Base Write Upper Register (super, W/O) */
 #define SPRN_HIOR      0x137   /* 970 Hypervisor interrupt offset */
-#define        SPRN_TCR        0x3DA   /* Timer Control Register */
-#define          TCR_WP(x)             (((x)&0x3)<<30) /* WDT Period */
-#define            WP_2_17             0               /* 2^17 clocks */
-#define            WP_2_21             1               /* 2^21 clocks */
-#define            WP_2_25             2               /* 2^25 clocks */
-#define            WP_2_29             3               /* 2^29 clocks */
-#define          TCR_WRC(x)            (((x)&0x3)<<28) /* WDT Reset Control */
-#define            WRC_NONE            0               /* No reset will occur */
-#define            WRC_CORE            1               /* Core reset will occur */
-#define            WRC_CHIP            2               /* Chip reset will occur */
-#define            WRC_SYSTEM          3               /* System reset will occur */
-#define          TCR_WIE               0x08000000      /* WDT Interrupt Enable */
-#define          TCR_PIE               0x04000000      /* PIT Interrupt Enable */
-#define          TCR_FP(x)             (((x)&0x3)<<24) /* FIT Period */
-#define            FP_2_9              0               /* 2^9 clocks */
-#define            FP_2_13             1               /* 2^13 clocks */
-#define            FP_2_17             2               /* 2^17 clocks */
-#define            FP_2_21             3               /* 2^21 clocks */
-#define          TCR_FIE               0x00800000      /* FIT Interrupt Enable */
-#define          TCR_ARE               0x00400000      /* Auto Reload Enable */
-#define        SPRN_THRM1      0x3FC   /* Thermal Management Register 1 */
-#define          THRM1_TIN             (1<<0)
-#define          THRM1_TIV             (1<<1)
-#define          THRM1_THRES           (0x7f<<2)
-#define          THRM1_TID             (1<<29)
-#define          THRM1_TIE             (1<<30)
-#define          THRM1_V               (1<<31)
-#define        SPRN_THRM2      0x3FD   /* Thermal Management Register 2 */
-#define        SPRN_THRM3      0x3FE   /* Thermal Management Register 3 */
-#define          THRM3_E               (1<<31)
-#define        SPRN_TSR        0x3D8   /* Timer Status Register */
-#define          TSR_ENW               0x80000000      /* Enable Next Watchdog */
-#define          TSR_WIS               0x40000000      /* WDT Interrupt Status */
-#define          TSR_WRS(x)            (((x)&0x3)<<28) /* WDT Reset Status */
-#define            WRS_NONE            0               /* No WDT reset occurred */
-#define            WRS_CORE            1               /* WDT forced core reset */
-#define            WRS_CHIP            2               /* WDT forced chip reset */
-#define            WRS_SYSTEM          3               /* WDT forced system reset */
-#define          TSR_PIS               0x08000000      /* PIT Interrupt Status */
-#define          TSR_FIS               0x04000000      /* FIT Interrupt Status */
 #define        SPRN_USIA       0x3AB   /* User Sampled Instruction Address Register */
 #define        SPRN_XER        0x001   /* Fixed Point Exception Register */
-#define        SPRN_ZPR        0x3B0   /* Zone Protection Register */
 #define SPRN_VRSAVE     0x100   /* Vector save */
+#define SPRN_CTRLF     0x088
+#define SPRN_CTRLT     0x098
+#define   CTRL_RUNLATCH        0x1
 
 /* Performance monitor SPRs */
 #define SPRN_SIAR      780
 #define        CTR     SPRN_CTR        /* Counter Register */
 #define        DAR     SPRN_DAR        /* Data Address Register */
 #define        DABR    SPRN_DABR       /* Data Address Breakpoint Register */
-#define        DCMP    SPRN_DCMP       /* Data TLB Compare Register */
 #define        DEC     SPRN_DEC        /* Decrement Register */
-#define        DMISS   SPRN_DMISS      /* Data TLB Miss Register */
 #define        DSISR   SPRN_DSISR      /* Data Storage Interrupt Status Register */
-#define        EAR     SPRN_EAR        /* External Address Register */
-#define        HASH1   SPRN_HASH1      /* Primary Hash Address Register */
-#define        HASH2   SPRN_HASH2      /* Secondary Hash Address Register */
 #define        HID0    SPRN_HID0       /* Hardware Implementation Register 0 */
 #define        MSRDORM SPRN_MSRDORM    /* MSR Dormant Register */
 #define        NIADORM SPRN_NIADORM    /* NIA Dormant Register */
 #define        TSC     SPRN_TSC        /* Thread switch control */
 #define        TST     SPRN_TST        /* Thread switch timeout */
 #define        IABR    SPRN_IABR       /* Instruction Address Breakpoint Register */
-#define        ICMP    SPRN_ICMP       /* Instruction TLB Compare Register */
-#define        IMISS   SPRN_IMISS      /* Instruction TLB Miss Register */
-#define        IMMR    SPRN_IMMR       /* PPC 860/821 Internal Memory Map Register */
 #define        L2CR    SPRN_L2CR       /* PPC 750 L2 control register */
 #define        __LR    SPRN_LR
 #define        PVR     SPRN_PVR        /* Processor Version */
 #define        PIR     SPRN_PIR        /* Processor ID */
 #define        PURR    SPRN_PURR       /* Processor Utilization of Resource Register */
-//#define      RPA     SPRN_RPA        /* Required Physical Address Register */
 #define        SDR1    SPRN_SDR1       /* MMU hash base register */
 #define        SPR0    SPRN_SPRG0      /* Supervisor Private Registers */
 #define        SPR1    SPRN_SPRG1
 #define        TBRU    SPRN_TBRU       /* Time Base Read Upper Register */
 #define        TBWL    SPRN_TBWL       /* Time Base Write Lower Register */
 #define        TBWU    SPRN_TBWU       /* Time Base Write Upper Register */
-#define ICTC   1019
-#define        THRM1   SPRN_THRM1      /* Thermal Management Register 1 */
-#define        THRM2   SPRN_THRM2      /* Thermal Management Register 2 */
-#define        THRM3   SPRN_THRM3      /* Thermal Management Register 3 */
 #define        XER     SPRN_XER
 
 /* Processor Version Register (PVR) field extraction */
 #define XGLUE(a,b) a##b
 #define GLUE(a,b) XGLUE(a,b)
 
-/* iSeries CTRL register (for runlatch) */
-
-#define CTRLT          0x098
-#define CTRLF          0x088
-#define RUNLATCH       0x0001
-
 #ifdef __ASSEMBLY__
 
 #define _GLOBAL(name) \
@@ -656,6 +496,24 @@ static inline void prefetchw(const void *x)
 
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
+static inline void ppc64_runlatch_on(void)
+{
+       unsigned long ctrl;
+
+       ctrl = mfspr(SPRN_CTRLF);
+       ctrl |= CTRL_RUNLATCH;
+       mtspr(SPRN_CTRLT, ctrl);
+}
+
+static inline void ppc64_runlatch_off(void)
+{
+       unsigned long ctrl;
+
+       ctrl = mfspr(SPRN_CTRLF);
+       ctrl &= ~CTRL_RUNLATCH;
+       mtspr(SPRN_CTRLT, ctrl);
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
index 2440a2c90ae9a889e1fc81b4c34b61b171fb6c7d..04b1a84f7ca390c5f6c3ad6f5ea9bb22f44f2d40 100644 (file)
@@ -147,9 +147,7 @@ struct device_node {
        struct  device_node *sibling;
        struct  device_node *next;      /* next device of same type */
        struct  device_node *allnext;   /* next in list of all nodes */
-       struct  proc_dir_entry *pde;       /* this node's proc directory */
-       struct  proc_dir_entry *name_link; /* name symlink */
-       struct  proc_dir_entry *addr_link; /* addr symlink */
+       struct  proc_dir_entry *pde;    /* this node's proc directory */
        struct  kref kref;
        unsigned long _flags;
 };
@@ -174,15 +172,6 @@ static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_e
        dn->pde = de;
 }
 
-static void inline set_node_name_link(struct device_node *dn, struct proc_dir_entry *de)
-{
-       dn->name_link = de;
-}
-
-static void inline set_node_addr_link(struct device_node *dn, struct proc_dir_entry *de)
-{
-       dn->addr_link = de;
-}
 
 /* OBSOLETE: Old stlye node lookup */
 extern struct device_node *find_devices(const char *name);
index a2d7bbb4befdc3c9160c2b71db834cea29a3f247..432df7dd355d86651eccf4e6d27f63da7e6f8699 100644 (file)
@@ -97,33 +97,19 @@ typedef struct {
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void __sigfunction(int);
-typedef __sigfunction __user * __sighandler_t;
-
-/* Type of the restorer function */
-typedef void __sigrestorer(void);
-typedef __sigrestorer __user * __sigrestorer_t;
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 struct old_sigaction {
        __sighandler_t sa_handler;
        old_sigset_t sa_mask;
        unsigned long sa_flags;
-       __sigrestorer_t sa_restorer;
+       __sigrestore_t sa_restorer;
 };
 
 struct sigaction {
        __sighandler_t sa_handler;
        unsigned long sa_flags;
-       __sigrestorer_t sa_restorer;
+       __sigrestore_t sa_restorer;
        sigset_t sa_mask;               /* mask last for extensibility */
 };
 
index 037b5e06083c0c58ca8f2c624c7edd3b6c12df3a..48b7900e90ec2db801de1a22fe50c2b4ff429c33 100644 (file)
@@ -96,7 +96,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_POLLING_NRFLAG     4       /* true if poll_idle() is polling
                                           TIF_NEED_RESCHED */
 #define TIF_32BIT              5       /* 32 bit binary */
-#define TIF_RUN_LIGHT          6       /* iSeries run light */
+/* #define SPARE               6 */
 #define TIF_ABI_PENDING                7       /* 32/64 bit switch needed */
 #define TIF_SYSCALL_AUDIT      8       /* syscall auditing active */
 #define TIF_SINGLESTEP         9       /* singlestepping active */
@@ -110,7 +110,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_32BIT             (1<<TIF_32BIT)
-#define _TIF_RUN_LIGHT         (1<<TIF_RUN_LIGHT)
+/* #define _SPARE              (1<<SPARE) */
 #define _TIF_ABI_PENDING       (1<<TIF_ABI_PENDING)
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
index 0027da4364ac5c96a61e1ba86c9a9ea85d627b43..fdec5e7a7af6cd177e324648bbeeb29da3fb8c4a 100644 (file)
@@ -30,7 +30,4 @@ struct xics_ipi_struct {
 
 extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
 
-extern unsigned int default_distrib_server;
-extern unsigned int interrupt_server_size;
-
 #endif /* _PPC64_KERNEL_XICS_H */
index bfed83a818ccd3f21d662f96b7fe67c0349bc9fc..3d6e11c6c1fdd94a4568e1bd230bbdfb25733f3b 100644 (file)
@@ -117,16 +117,7 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ     2048
 #define SIGSTKSZ        8192
 
-#define SIG_BLOCK          0    /* for blocking signals */
-#define SIG_UNBLOCK        1    /* for unblocking signals */
-#define SIG_SETMASK        2    /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index c64f8c181df39b6f8d3890be531645efab24026d..1dc74baf03c4c16027d1811bfd32bf4be00c21b9 100644 (file)
@@ -10,7 +10,7 @@
 #define _S390_USER_H
 
 #include <asm/page.h>
-#include <linux/ptrace.h>
+#include <asm/ptrace.h>
 /* Core file format: The core file is written in such a way that gdb
    can understand it and provide useful information to the user (under
    linux we use the 'trad-core' bfd).  There are quite a number of
index f030ca08052bf5e3628121a82354429f64c7c8ce..38d7a2942476dff07e61e396cf2175778df08c6a 100644 (file)
@@ -227,7 +227,7 @@ static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
        return 0;
 }
 
-struct fd_routine_l {
+static struct fd_routine_l {
        int (*_request_dma)(unsigned int dmanr, const char * device_id);
        void (*_free_dma)(unsigned int dmanr);
        int (*_get_dma_residue)(unsigned int dummy);
index 29f1ac1bf4dfe7fe888c7d3fb8330fc944053e80..d6e8eb0e65c71c5394b37578ce991c29798e76ba 100644 (file)
@@ -108,16 +108,7 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index d82f883d8e6d3b68fe571b724103a528eb7f4fbc..4bbbd9f3c37e91ad5524133b182d8d3ff3cf5197 100644 (file)
@@ -27,7 +27,7 @@ struct thread_info {
 
 #endif
 
-#define PREEMPT_ACTIVE         0x4000000
+#define PREEMPT_ACTIVE         0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
index 864c94ecc98cadfde65f0be9051f6e519aa25d74..2400dc688a657d477d4209c1487c81f6a2979353 100644 (file)
@@ -107,16 +107,7 @@ typedef struct {
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       THREAD_SIZE
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct old_sigaction {
index e65f394da472a7c4adfcf6a79f7da692a2d42cbb..8a32d6bd0b793b947deab7c6f311b3e6c49d5106 100644 (file)
@@ -73,7 +73,7 @@ static inline struct thread_info *current_thread_info(void)
 
 #define THREAD_SIZE  8192
 
-#define PREEMPT_ACTIVE         0x4000000
+#define PREEMPT_ACTIVE         0x10000000
 
 /* thread information flags */
 #define TIF_SYSCALL_TRACE      0       /* syscall trace active */
index 780ee7ff9dc3d866a9e1665544b317b45365e086..caf926116506a2d0980e1e13b30c6c600b02b120 100644 (file)
@@ -227,7 +227,7 @@ static __inline__ void sun_fd_disable_dma(void)
        doing_pdma = 0;
        if (pdma_base) {
                mmu_unlockarea(pdma_base, pdma_areasize);
-               pdma_base = 0;
+               pdma_base = NULL;
        }
 }
 
index f792e10e704f6eee4a9b4645d86d813c306dcc56..aa9960ad0ca9d2d4039767ffbdf33a80d3bef832 100644 (file)
@@ -174,16 +174,7 @@ struct sigstack {
 #define SA_STATIC_ALLOC                0x80
 #endif
 
-/* Type of a signal handler.  */
-#ifdef __KERNEL__
-typedef void (*__sighandler_t)(int, int, struct sigcontext *, char *);
-#else
-typedef void (*__sighandler_t)(int);
-#endif
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 struct __new_sigaction {
index f461144067eea33924e44f9223002ef7e723200e..0a780e84a12b749fd6f1e4381407f34affcb895b 100644 (file)
  * No one can read/write anything from userland in the kernel space by setting
  * large size and address near to PAGE_OFFSET - a fault will break his intentions.
  */
-#define __user_ok(addr,size) ((addr) < STACK_TOP)
+#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
-#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+#define access_ok(type, addr, size)                                    \
+       ({ (void)(type); __access_ok((unsigned long)(addr), size); })
 
 /* this function will go away soon - use access_ok() instead */
 static inline int __deprecated verify_area(int type, const void __user * addr, unsigned long size)
index ba05bdf9a211db17909d773b559738167ea826b5..58f8cb6ae767d536769a8a43ab46564a5665b96b 100644 (file)
@@ -8,4 +8,14 @@
 #define flush_agp_mappings() 
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+
 #endif
index 5fd16e42a0455b00de9434ea020314de8973df55..0de7a3da79cd7e94b462be4076793d13244a3f95 100644 (file)
@@ -16,4 +16,6 @@
 #define IOPTE_CACHE   0x0000000000000010UL /* Cached (in UPA E-cache)         */
 #define IOPTE_WRITE   0x0000000000000002UL /* Writeable                       */
 
+#define IOMMU_NUM_CTXS 4096
+
 #endif /* !(_SPARC_IOMMU_H) */
index ab88349ddadc71e39a72e7fa6b32baeb32bb2362..b7e635544cecce868e1e5fdc7cf328528b934c3d 100644 (file)
 
 #define PARPORT_PC_MAX_PORTS   PARPORT_MAX
 
+/*
+ * While sparc64 doesn't have an ISA DMA API, we provide something that looks
+ * close enough to make parport_pc happy
+ */
+#define HAS_DMA
+
 static struct sparc_ebus_info {
        struct ebus_dma_info info;
        unsigned int addr;
index 92999631c81966a7a310d6b718955b83fd378fbe..4c15610a2bac188a8f408396d207bd0ff570ab6a 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/oplib.h>
+#include <asm/iommu.h>
 
 /* The abstraction used here is that there are PCI controllers,
  * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules
@@ -40,9 +41,6 @@ struct pci_iommu {
         */
        spinlock_t      lock;
 
-       /* Context allocator. */
-       unsigned int    iommu_cur_ctx;
-
        /* IOMMU page table, a linear array of ioptes. */
        iopte_t         *page_table;            /* The page table itself. */
        int             page_table_sz_bits;     /* log2 of ow many pages does it map? */
@@ -87,6 +85,10 @@ struct pci_iommu {
                u16     flush;
        } alloc_info[PBM_NCLUSTERS];
 
+       /* CTX allocation. */
+       unsigned long ctx_lowest_free;
+       unsigned long ctx_bitmap[IOMMU_NUM_CTXS / (sizeof(unsigned long) * 8)];
+
        /* Here a PCI controller driver describes the areas of
         * PCI memory space where DMA to/from physical memory
         * are addressed.  Drivers interrogate the PCI layer
index 2c28e1f605b76504eb7df4e4bc77f5e836399de1..b9b1914aae6331e8fe3e493ee317e19b11ec63c6 100644 (file)
@@ -122,17 +122,12 @@ static __inline__ void free_pmd_slow(pmd_t *pmd)
 #define pmd_populate(MM,PMD,PTE_PAGE)          \
        pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE))
 
-extern pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address);
-
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
-{
-       return __pte_alloc_one_kernel(mm, address);
-}
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address);
 
 static inline struct page *
 pte_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-       pte_t *pte = __pte_alloc_one_kernel(mm, addr);
+       pte_t *pte = pte_alloc_one_kernel(mm, addr);
 
        if (pte)
                return virt_to_page(pte);
index 466d021d703832bf656d954a6dd000353383a210..becdf1bc59245fd7f8f5d8c5866ce7d2f159ca90 100644 (file)
@@ -177,21 +177,7 @@ struct sigstack {
 #define SA_STATIC_ALLOC                0x80
 #endif
 
-/* Type of a signal handler.  */
-#ifdef __KERNEL__
-typedef void __signalfn_t(int);
-typedef __signalfn_t __user *__sighandler_t;
-
-typedef void __restorefn_t(void);
-typedef __restorefn_t __user *__sigrestore_t;
-#else
-typedef void (*__sighandler_t)(int);
-typedef void (*__sigrestore_t)(void);
-#endif
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+#include <asm-generic/signal.h>
 
 struct __new_sigaction {
        __sighandler_t          sa_handler;
index ad78ce64d69ee8f04f35e03301826b74c42b5298..9d7613eea8129a58dbbcca8dbaef05f2228f6d66 100644 (file)
@@ -48,6 +48,9 @@ enum ultra_tlb_layout {
 
 extern enum ultra_tlb_layout tlb_type;
 
+extern int cheetah_pcache_forced_on;
+extern void cheetah_enable_pcache(void);
+
 #define sparc64_highest_locked_tlbent()        \
        (tlb_type == spitfire ? \
         SPITFIRE_HIGHEST_LOCKED_TLBENT : \
diff --git a/include/asm-um/arch-signal-i386.h b/include/asm-um/arch-signal-i386.h
deleted file mode 100644 (file)
index 99a9de4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __UM_ARCH_SIGNAL_I386_H
-#define __UM_ARCH_SIGNAL_I386_H
-
-struct arch_signal_context {
-       unsigned long extrasigs[_NSIG_WORDS];
-};
-
-#endif
-
-/*
- * 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-file-style: "linux"
- * End:
- */
index 6f78de5b621b821a6af95cc200799ad7cba1721a..49e89b8d7e588354d47a896a824f4e25c3970e7c 100644 (file)
@@ -6,143 +6,6 @@
 #ifndef __UM_ARCHPARAM_I386_H
 #define __UM_ARCHPARAM_I386_H
 
-/********* Bits for asm-um/elf.h ************/
-
-#include <asm/user.h>
-
-extern char * elf_aux_platform;
-#define ELF_PLATFORM (elf_aux_platform)
-
-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
-
-typedef struct user_i387_struct elf_fpregset_t;
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-#define ELF_DATA        ELFDATA2LSB
-#define ELF_ARCH        EM_386
-
-#define ELF_PLAT_INIT(regs, load_addr) do { \
-       PT_REGS_EBX(regs) = 0; \
-       PT_REGS_ECX(regs) = 0; \
-       PT_REGS_EDX(regs) = 0; \
-       PT_REGS_ESI(regs) = 0; \
-       PT_REGS_EDI(regs) = 0; \
-       PT_REGS_EBP(regs) = 0; \
-       PT_REGS_EAX(regs) = 0; \
-} while(0)
-
-/* Shamelessly stolen from include/asm-i386/elf.h */
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs) do {  \
-       pr_reg[0] = PT_REGS_EBX(regs);          \
-       pr_reg[1] = PT_REGS_ECX(regs);          \
-       pr_reg[2] = PT_REGS_EDX(regs);          \
-       pr_reg[3] = PT_REGS_ESI(regs);          \
-       pr_reg[4] = PT_REGS_EDI(regs);          \
-       pr_reg[5] = PT_REGS_EBP(regs);          \
-       pr_reg[6] = PT_REGS_EAX(regs);          \
-       pr_reg[7] = PT_REGS_DS(regs);           \
-       pr_reg[8] = PT_REGS_ES(regs);           \
-       /* fake once used fs and gs selectors? */       \
-       pr_reg[9] = PT_REGS_DS(regs);           \
-       pr_reg[10] = PT_REGS_DS(regs);          \
-       pr_reg[11] = PT_REGS_SYSCALL_NR(regs);  \
-       pr_reg[12] = PT_REGS_IP(regs);          \
-       pr_reg[13] = PT_REGS_CS(regs);          \
-       pr_reg[14] = PT_REGS_EFLAGS(regs);      \
-       pr_reg[15] = PT_REGS_SP(regs);          \
-       pr_reg[16] = PT_REGS_SS(regs);          \
-} while(0);
-
-
-extern unsigned long vsyscall_ehdr;
-extern unsigned long vsyscall_end;
-extern unsigned long __kernel_vsyscall;
-
-#define VSYSCALL_BASE vsyscall_ehdr
-#define VSYSCALL_END vsyscall_end
-
-/*
- * This is the range that is readable by user mode, and things
- * acting like user mode such as get_user_pages.
- */
-#define FIXADDR_USER_START      VSYSCALL_BASE
-#define FIXADDR_USER_END        VSYSCALL_END
-
-/*
- * Architecture-neutral AT_ values in 0-17, leave some room
- * for more of them, start the x86-specific ones at 32.
- */
-#define AT_SYSINFO             32
-#define AT_SYSINFO_EHDR                33
-
-#define ARCH_DLINFO                                            \
-do {                                                           \
-       if ( vsyscall_ehdr ) {                                  \
-               NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall);     \
-               NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr);    \
-       }                                                       \
-} while (0)
-
-/*
- * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
- * extra segments containing the vsyscall DSO contents.  Dumping its
- * contents makes post-mortem fully interpretable later without matching up
- * the same kernel and hardware config to see what PC values meant.
- * Dumping its extra ELF program headers includes all the other information
- * a debugger needs to easily find how the vsyscall DSO was being used.
- */
-#define ELF_CORE_EXTRA_PHDRS                                                 \
-       (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
-
-#define ELF_CORE_WRITE_EXTRA_PHDRS                                           \
-if ( vsyscall_ehdr ) {                                                       \
-       const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
-       const struct elf_phdr *const phdrp =                                  \
-               (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
-       int i;                                                                \
-       Elf32_Off ofs = 0;                                                    \
-       for (i = 0; i < ehdrp->e_phnum; ++i) {                                \
-               struct elf_phdr phdr = phdrp[i];                              \
-               if (phdr.p_type == PT_LOAD) {                                 \
-                       ofs = phdr.p_offset = offset;                         \
-                       offset += phdr.p_filesz;                              \
-               }                                                             \
-               else                                                          \
-                       phdr.p_offset += ofs;                                 \
-               phdr.p_paddr = 0; /* match other core phdrs */                \
-               DUMP_WRITE(&phdr, sizeof(phdr));                              \
-       }                                                                     \
-}
-#define ELF_CORE_WRITE_EXTRA_DATA                                            \
-if ( vsyscall_ehdr ) {                                                       \
-       const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
-       const struct elf_phdr *const phdrp =                                  \
-               (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
-       int i;                                                                \
-       for (i = 0; i < ehdrp->e_phnum; ++i) {                                \
-               if (phdrp[i].p_type == PT_LOAD)                               \
-                       DUMP_WRITE((void *) phdrp[i].p_vaddr,                 \
-                                  phdrp[i].p_filesz);                        \
-       }                                                                     \
-}
-
-#define R_386_NONE     0
-#define R_386_32       1
-#define R_386_PC32     2
-#define R_386_GOT32    3
-#define R_386_PLT32    4
-#define R_386_COPY     5
-#define R_386_GLOB_DAT 6
-#define R_386_JMP_SLOT 7
-#define R_386_RELATIVE 8
-#define R_386_GOTOFF   9
-#define R_386_GOTPC    10
-#define R_386_NUM      11
-
 /********* Nothing for asm-um/hardirq.h **********/
 
 /********* Nothing for asm-um/hw_irq.h **********/
index 0ebced92a7625d1ddc580ad55139b5dad9841b0b..172cd6ffacc4a28c5eceb9b40b97dc86d3019d38 100644 (file)
@@ -1,26 +1,6 @@
 #ifndef __UM_ARCHPARAM_PPC_H
 #define __UM_ARCHPARAM_PPC_H
 
-/********* Bits for asm-um/elf.h ************/
-
-#define ELF_PLATFORM (0)
-
-#define ELF_ET_DYN_BASE (0x08000000)
-
-/* the following stolen from asm-ppc/elf.h */
-#define ELF_NGREG      48      /* includes nip, msr, lr, etc. */
-#define ELF_NFPREG     33      /* includes fpscr */
-/* General registers */
-typedef unsigned long elf_greg_t;
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-/* Floating point registers */
-typedef double elf_fpreg_t;
-typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-
-#define ELF_DATA        ELFDATA2MSB
-#define ELF_ARCH       EM_PPC
-
 /********* Bits for asm-um/hw_irq.h **********/
 
 struct hw_interrupt_type;
index 96321c4892f16b9ea8d2c8c9e4c5ec17d7735186..270ed9586b68542563e3d94cf8dc49d9d7a99256 100644 (file)
@@ -7,42 +7,6 @@
 #ifndef __UM_ARCHPARAM_X86_64_H
 #define __UM_ARCHPARAM_X86_64_H
 
-#include <asm/user.h>
-
-#define ELF_PLATFORM "x86_64"
-
-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
-
-typedef unsigned long elf_greg_t;
-typedef struct { } elf_fpregset_t;
-
-#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-#define ELF_DATA        ELFDATA2LSB
-#define ELF_ARCH        EM_X86_64
-
-#define ELF_PLAT_INIT(regs, load_addr)    do { \
-       PT_REGS_RBX(regs) = 0; \
-       PT_REGS_RCX(regs) = 0; \
-       PT_REGS_RDX(regs) = 0; \
-       PT_REGS_RSI(regs) = 0; \
-       PT_REGS_RDI(regs) = 0; \
-       PT_REGS_RBP(regs) = 0; \
-       PT_REGS_RAX(regs) = 0; \
-       PT_REGS_R8(regs) = 0; \
-       PT_REGS_R9(regs) = 0; \
-       PT_REGS_R10(regs) = 0; \
-       PT_REGS_R11(regs) = 0; \
-       PT_REGS_R12(regs) = 0; \
-       PT_REGS_R13(regs) = 0; \
-       PT_REGS_R14(regs) = 0; \
-       PT_REGS_R15(regs) = 0; \
-} while (0)
-
-#ifdef TIF_IA32 /* XXX */
-        clear_thread_flag(TIF_IA32);
-#endif
 
 /* No user-accessible fixmap addresses, i.e. vsyscall */
 #define FIXADDR_USER_START     0
index 40695576ca6002d7b102a8676d1dfeb9d7a938ac..0985bda66750b9ec2e989703c2e6ff078729a742 100644 (file)
@@ -4,4 +4,6 @@
 #include "asm/arch/delay.h"
 #include "asm/archparam.h"
 
+#define MILLION 1000000
+
 #endif
diff --git a/include/asm-um/elf-i386.h b/include/asm-um/elf-i386.h
new file mode 100644 (file)
index 0000000..9bab712
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+#ifndef __UM_ELF_I386_H
+#define __UM_ELF_I386_H
+
+#include <asm/user.h>
+
+#define R_386_NONE     0
+#define R_386_32       1
+#define R_386_PC32     2
+#define R_386_GOT32    3
+#define R_386_PLT32    4
+#define R_386_COPY     5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF   9
+#define R_386_GOTPC    10
+#define R_386_NUM      11
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_i387_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) \
+       (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
+
+#define ELF_CLASS      ELFCLASS32
+#define ELF_DATA        ELFDATA2LSB
+#define ELF_ARCH        EM_386
+
+#define ELF_PLAT_INIT(regs, load_addr) do { \
+       PT_REGS_EBX(regs) = 0; \
+       PT_REGS_ECX(regs) = 0; \
+       PT_REGS_EDX(regs) = 0; \
+       PT_REGS_ESI(regs) = 0; \
+       PT_REGS_EDI(regs) = 0; \
+       PT_REGS_EBP(regs) = 0; \
+       PT_REGS_EAX(regs) = 0; \
+} while(0)
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
+
+/* Shamelessly stolen from include/asm-i386/elf.h */
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs) do {  \
+       pr_reg[0] = PT_REGS_EBX(regs);          \
+       pr_reg[1] = PT_REGS_ECX(regs);          \
+       pr_reg[2] = PT_REGS_EDX(regs);          \
+       pr_reg[3] = PT_REGS_ESI(regs);          \
+       pr_reg[4] = PT_REGS_EDI(regs);          \
+       pr_reg[5] = PT_REGS_EBP(regs);          \
+       pr_reg[6] = PT_REGS_EAX(regs);          \
+       pr_reg[7] = PT_REGS_DS(regs);           \
+       pr_reg[8] = PT_REGS_ES(regs);           \
+       /* fake once used fs and gs selectors? */       \
+       pr_reg[9] = PT_REGS_DS(regs);           \
+       pr_reg[10] = PT_REGS_DS(regs);          \
+       pr_reg[11] = PT_REGS_SYSCALL_NR(regs);  \
+       pr_reg[12] = PT_REGS_IP(regs);          \
+       pr_reg[13] = PT_REGS_CS(regs);          \
+       pr_reg[14] = PT_REGS_EFLAGS(regs);      \
+       pr_reg[15] = PT_REGS_SP(regs);          \
+       pr_reg[16] = PT_REGS_SS(regs);          \
+} while(0);
+
+extern long elf_aux_hwcap;
+#define ELF_HWCAP (elf_aux_hwcap)
+
+extern char * elf_aux_platform;
+#define ELF_PLATFORM (elf_aux_platform)
+
+#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
+
+extern unsigned long vsyscall_ehdr;
+extern unsigned long vsyscall_end;
+extern unsigned long __kernel_vsyscall;
+
+#define VSYSCALL_BASE vsyscall_ehdr
+#define VSYSCALL_END vsyscall_end
+
+/*
+ * This is the range that is readable by user mode, and things
+ * acting like user mode such as get_user_pages.
+ */
+#define FIXADDR_USER_START      VSYSCALL_BASE
+#define FIXADDR_USER_END        VSYSCALL_END
+
+/*
+ * Architecture-neutral AT_ values in 0-17, leave some room
+ * for more of them, start the x86-specific ones at 32.
+ */
+#define AT_SYSINFO             32
+#define AT_SYSINFO_EHDR                33
+
+#define ARCH_DLINFO                                            \
+do {                                                           \
+       if ( vsyscall_ehdr ) {                                  \
+               NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall);     \
+               NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr);    \
+       }                                                       \
+} while (0)
+
+/*
+ * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
+ * extra segments containing the vsyscall DSO contents.  Dumping its
+ * contents makes post-mortem fully interpretable later without matching up
+ * the same kernel and hardware config to see what PC values meant.
+ * Dumping its extra ELF program headers includes all the other information
+ * a debugger needs to easily find how the vsyscall DSO was being used.
+ */
+#define ELF_CORE_EXTRA_PHDRS                                                 \
+       (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
+
+#define ELF_CORE_WRITE_EXTRA_PHDRS                                           \
+if ( vsyscall_ehdr ) {                                                       \
+       const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
+       const struct elf_phdr *const phdrp =                                  \
+               (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
+       int i;                                                                \
+       Elf32_Off ofs = 0;                                                    \
+       for (i = 0; i < ehdrp->e_phnum; ++i) {                                \
+               struct elf_phdr phdr = phdrp[i];                              \
+               if (phdr.p_type == PT_LOAD) {                                 \
+                       ofs = phdr.p_offset = offset;                         \
+                       offset += phdr.p_filesz;                              \
+               }                                                             \
+               else                                                          \
+                       phdr.p_offset += ofs;                                 \
+               phdr.p_paddr = 0; /* match other core phdrs */                \
+               DUMP_WRITE(&phdr, sizeof(phdr));                              \
+       }                                                                     \
+}
+#define ELF_CORE_WRITE_EXTRA_DATA                                            \
+if ( vsyscall_ehdr ) {                                                       \
+       const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
+       const struct elf_phdr *const phdrp =                                  \
+               (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
+       int i;                                                                \
+       for (i = 0; i < ehdrp->e_phnum; ++i) {                                \
+               if (phdrp[i].p_type == PT_LOAD)                               \
+                       DUMP_WRITE((void *) phdrp[i].p_vaddr,                 \
+                                  phdrp[i].p_filesz);                        \
+       }                                                                     \
+}
+
+#endif
+
+/*
+ * 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-file-style: "linux"
+ * End:
+ */
diff --git a/include/asm-um/elf-ppc.h b/include/asm-um/elf-ppc.h
new file mode 100644 (file)
index 0000000..2998cf9
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef __UM_ELF_PPC_H
+#define __UM_ELF_PPC_H
+
+#include "linux/config.h"
+
+extern long elf_aux_hwcap;
+#define ELF_HWCAP (elf_aux_hwcap)
+
+#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
+
+#define ELF_EXEC_PAGESIZE 4096
+
+#define elf_check_arch(x) (1)
+
+#ifdef CONFIG_64_BIT
+#define ELF_CLASS ELFCLASS64
+#else
+#define ELF_CLASS ELFCLASS32
+#endif
+
+#define USE_ELF_CORE_DUMP
+
+#define R_386_NONE     0
+#define R_386_32       1
+#define R_386_PC32     2
+#define R_386_GOT32    3
+#define R_386_PLT32    4
+#define R_386_COPY     5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF   9
+#define R_386_GOTPC    10
+#define R_386_NUM      11
+
+#define ELF_PLATFORM (0)
+
+#define ELF_ET_DYN_BASE (0x08000000)
+
+/* the following stolen from asm-ppc/elf.h */
+#define ELF_NGREG      48      /* includes nip, msr, lr, etc. */
+#define ELF_NFPREG     33      /* includes fpscr */
+/* General registers */
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* Floating point registers */
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+#define ELF_DATA        ELFDATA2MSB
+#define ELF_ARCH       EM_PPC
+
+#endif
diff --git a/include/asm-um/elf-x86_64.h b/include/asm-um/elf-x86_64.h
new file mode 100644 (file)
index 0000000..8a8246d
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+#ifndef __UM_ELF_X86_64_H
+#define __UM_ELF_X86_64_H
+
+#include <asm/user.h>
+
+/* x86-64 relocation types, taken from asm-x86_64/elf.h */
+#define R_X86_64_NONE          0       /* No reloc */
+#define R_X86_64_64            1       /* Direct 64 bit  */
+#define R_X86_64_PC32          2       /* PC relative 32 bit signed */
+#define R_X86_64_GOT32         3       /* 32 bit GOT entry */
+#define R_X86_64_PLT32         4       /* 32 bit PLT address */
+#define R_X86_64_COPY          5       /* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT      6       /* Create GOT entry */
+#define R_X86_64_JUMP_SLOT     7       /* Create PLT entry */
+#define R_X86_64_RELATIVE      8       /* Adjust by program base */
+#define R_X86_64_GOTPCREL      9       /* 32 bit signed pc relative
+                                          offset to GOT */
+#define R_X86_64_32            10      /* Direct 32 bit zero extended */
+#define R_X86_64_32S           11      /* Direct 32 bit sign extended */
+#define R_X86_64_16            12      /* Direct 16 bit zero extended */
+#define R_X86_64_PC16          13      /* 16 bit sign extended pc relative */
+#define R_X86_64_8             14      /* Direct 8 bit sign extended  */
+#define R_X86_64_PC8           15      /* 8 bit sign extended pc relative */
+
+#define R_X86_64_NUM           16
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct { } elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) \
+       ((x)->e_machine == EM_X86_64)
+
+#define ELF_CLASS      ELFCLASS64
+#define ELF_DATA        ELFDATA2LSB
+#define ELF_ARCH        EM_X86_64
+
+#define ELF_PLAT_INIT(regs, load_addr)    do { \
+       PT_REGS_RBX(regs) = 0; \
+       PT_REGS_RCX(regs) = 0; \
+       PT_REGS_RDX(regs) = 0; \
+       PT_REGS_RSI(regs) = 0; \
+       PT_REGS_RDI(regs) = 0; \
+       PT_REGS_RBP(regs) = 0; \
+       PT_REGS_RAX(regs) = 0; \
+       PT_REGS_R8(regs) = 0; \
+       PT_REGS_R9(regs) = 0; \
+       PT_REGS_R10(regs) = 0; \
+       PT_REGS_R11(regs) = 0; \
+       PT_REGS_R12(regs) = 0; \
+       PT_REGS_R13(regs) = 0; \
+       PT_REGS_R14(regs) = 0; \
+       PT_REGS_R15(regs) = 0; \
+} while (0)
+
+#ifdef TIF_IA32 /* XXX */
+#error XXX, indeed
+        clear_thread_flag(TIF_IA32);
+#endif
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
+
+extern long elf_aux_hwcap;
+#define ELF_HWCAP (elf_aux_hwcap)
+
+#define ELF_PLATFORM "x86_64"
+
+#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
+
+#endif
+
+/*
+ * 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-file-style: "linux"
+ * End:
+ */
diff --git a/include/asm-um/elf.h b/include/asm-um/elf.h
deleted file mode 100644 (file)
index 7908f8f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __UM_ELF_H
-#define __UM_ELF_H
-
-#include "linux/config.h"
-#include "asm/archparam.h"
-
-extern long elf_aux_hwcap;
-#define ELF_HWCAP (elf_aux_hwcap)
-
-#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
-
-#define ELF_EXEC_PAGESIZE 4096
-
-#define elf_check_arch(x) (1)
-
-#ifdef CONFIG_64BIT
-#define ELF_CLASS ELFCLASS64
-#else
-#define ELF_CLASS ELFCLASS32
-#endif
-
-#define USE_ELF_CORE_DUMP
-
-#define R_386_NONE     0
-#define R_386_32       1
-#define R_386_PC32     2
-#define R_386_GOT32    3
-#define R_386_PLT32    4
-#define R_386_COPY     5
-#define R_386_GLOB_DAT 6
-#define R_386_JMP_SLOT 7
-#define R_386_RELATIVE 8
-#define R_386_GOTOFF   9
-#define R_386_GOTPC    10
-#define R_386_NUM      11
-
-#endif
index 900f3fbb9fabb3bd4ba1362598fd403e163b7c96..ae0ca3932d5086f208e8e8b2903260af599e8d2c 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <asm/kmap_types.h>
 #include <asm/archparam.h>
+#include <asm/elf.h>
 
 /*
  * Here we define all the compile-time 'special' virtual
index e2ddc47f3e52639bc7dffc235c7b67505589573e..a46e3d9c2a3fc176772d1b6b7726a977bb585cab 100644 (file)
@@ -1,6 +1 @@
-#ifndef __UM_IPC_H
-#define __UM_IPC_H
-
-#include "asm/arch/ipc.h"
-
-#endif
+#include <asm-generic/ipc.h>
index 27011652b01510f5a17c68a761c7e7ee668a191e..7dfce37adc8be83424c4463e50a635acfa72650a 100644 (file)
@@ -1,7 +1,6 @@
-#ifndef __ASM_LINKAGE_H
-#define __ASM_LINKAGE_H
+#ifndef __ASM_UM_LINKAGE_H
+#define __ASM_UM_LINKAGE_H
 
-#define FASTCALL(x)    x __attribute__((regparm(3)))
-#define fastcall        __attribute__((regparm(3)))
+#include "asm/arch/linkage.h"
 
 #endif
index 102eb3df1aafad05f3b216a148cfdcac208acdcb..5afee8a8cdf39ea0ec3135feab5b45c269daccdd 100644 (file)
@@ -45,6 +45,9 @@ typedef struct { unsigned long pgd; } pgd_t;
        ({ (pte).pte_high = (phys) >> 32; \
           (pte).pte_low = (phys) | pgprot_val(prot); })
 
+#define pmd_val(x)     ((x).pmd)
+#define __pmd(x) ((pmd_t) { (x) } )
+
 typedef unsigned long long pfn_t;
 typedef unsigned long long phys_t;
 
@@ -95,7 +98,13 @@ extern unsigned long uml_physmem;
 
 extern unsigned long to_phys(void *virt);
 extern void *to_virt(unsigned long phys);
-#define __pa(virt) to_phys((void *) virt)
+
+/* Cast to unsigned long before casting to void * to avoid a warning from
+ * mmap_kmem about cutting a long long down to a void *.  Not sure that
+ * casting is the right thing, but 32-bit UML can't have 64-bit virtual
+ * addresses
+ */
+#define __pa(virt) to_phys((void *) (unsigned long) virt)
 #define __va(phys) to_virt((unsigned long) phys)
 
 #define page_to_pfn(page) ((page) - mem_map)
index d309f3a9e6f65920dd85c50ef806810e55b7c997..65e8bfc55fc415440e8021650b2b8fd39ecc87b1 100644 (file)
@@ -149,7 +149,7 @@ static inline pmd_t pfn_pmd(pfn_t page_nr, pgprot_t pgprot)
 
 #define pte_to_pgoff(p) ((p).pte >> 32)
 
-#define pgoff_to_pte(off) ((pte_t) { ((off) < 32) | _PAGE_FILE })
+#define pgoff_to_pte(off) ((pte_t) { ((off) << 32) | _PAGE_FILE })
 
 #else
 
index 71f9c0c78c0cb2f377d4458747930c69d07b45c6..a88040920311e7e7333d65e3610fe574b8ce4259 100644 (file)
@@ -106,7 +106,7 @@ extern unsigned long end_iomem;
 /*
  * Define this if things work differently on an i386 and an i486:
  * it will (on an i486) warn about kernel memory accesses that are
- * done without a 'verify_area(VERIFY_WRITE,..)'
+ * done without a 'access_ok(VERIFY_WRITE,..)'
  */
 #undef TEST_VERIFY_AREA
 
@@ -114,17 +114,9 @@ extern unsigned long end_iomem;
 extern unsigned long pg0[1024];
 
 /*
- * BAD_PAGETABLE is used when we need a bogus page-table, while
- * BAD_PAGE is used for a bogus page.
- *
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
  */
-extern pte_t __bad_page(void);
-extern pte_t * __bad_pagetable(void);
-
-#define BAD_PAGETABLE __bad_pagetable()
-#define BAD_PAGE __bad_page()
 
 #define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
 
index b953b1ad3b020ac8e9866d8f4d0655b38dfb9ac1..b2fc94fbc2d90292ecfa53b64a8f97161d4deabf 100644 (file)
@@ -24,9 +24,6 @@ struct thread_struct {
        int forking;
        int nsyscalls;
        struct pt_regs regs;
-       unsigned long cr2;
-       int err;
-       unsigned long trap_no;
        int singlestep_syscall;
        void *fault_addr;
        void *fault_catcher;
@@ -74,8 +71,6 @@ struct thread_struct {
        .forking                = 0, \
        .nsyscalls              = 0, \
         .regs                  = EMPTY_REGS, \
-       .cr2                    = 0, \
-       .err                    = 0, \
        .fault_addr             = NULL, \
        .prev_sched             = NULL, \
        .temp_stack             = 0, \
index 2deb8f1adbf12dc2094687617b1e638adaf3c104..431bad3ae9d7cf33f72ec43cdd779e58cec12bb2 100644 (file)
@@ -9,13 +9,18 @@
 extern int host_has_xmm;
 extern int host_has_cmov;
 
+/* include faultinfo structure */
+#include "sysdep/faultinfo.h"
+
 struct arch_thread {
        unsigned long debugregs[8];
        int debugregs_seq;
+       struct faultinfo faultinfo;
 };
 
 #define INIT_ARCH_THREAD { .debugregs                  = { [ 0 ... 7 ] = 0 }, \
-                           .debugregs_seq      = 0 }
+                           .debugregs_seq      = 0, \
+                           .faultinfo          = { 0, 0, 0 } }
 
 #include "asm/arch/user.h"
 
index a1ae3a4cd93810ecc1dd07538ba1910ed148c096..0beb9a42ae05b5cf1afe8fd45d3e914837b6ad0f 100644 (file)
@@ -7,9 +7,13 @@
 #ifndef __UM_PROCESSOR_X86_64_H
 #define __UM_PROCESSOR_X86_64_H
 
-#include "asm/arch/user.h"
+/* include faultinfo structure */
+#include "sysdep/faultinfo.h"
 
 struct arch_thread {
+        unsigned long debugregs[8];
+        int debugregs_seq;
+        struct faultinfo faultinfo;
 };
 
 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
@@ -20,7 +24,11 @@ extern inline void rep_nop(void)
 
 #define cpu_relax()   rep_nop()
 
-#define INIT_ARCH_THREAD { }
+#define INIT_ARCH_THREAD { .debugregs                  = { [ 0 ... 7 ] = 0 }, \
+                           .debugregs_seq      = 0, \
+                           .faultinfo          = { 0, 0, 0 } }
+
+#include "asm/arch/user.h"
 
 #define current_text_addr() \
        ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; })
index 9e47590ec293b7c9e444f8fd02e0ffd9f3f3b942..04222f35c43e2cd0a64b9b28e390be9953104ee6 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef __UM_PTRACE_I386_H
 #define __UM_PTRACE_I386_H
 
+#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
+
 #include "sysdep/ptrace.h"
 #include "asm/ptrace-generic.h"
 
index c34be39b78b2262277b6abdf2c38dd5e30afb6af..be51219a8ffe468a600dc8727f9a9b83e90c0f3d 100644 (file)
@@ -14,6 +14,8 @@
 #include "asm/ptrace-generic.h"
 #undef signal_fault
 
+#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
+
 void signal_fault(struct pt_regs_subarch *regs, void *frame, char *where);
 
 #define FS_BASE (21 * sizeof(unsigned long))
index c85252e803c130923698b9b3e71fb28c3cecf76f..99f086301f4cba151466532eb41b56f4a2f07fc1 100644 (file)
@@ -2,7 +2,8 @@
 #define SETUP_H_INCLUDED
 
 /* POSIX mandated with _POSIX_ARG_MAX that we can rely on 4096 chars in the
- * command line, so this choice is ok.*/
+ * command line, so this choice is ok.
+ */
 
 #define COMMAND_LINE_SIZE 4096
 
index bffb577bc54e3b88b1706a0c9e49d489e05bcd87..1feaaf148ef12670314f17e8e5072ecec9469363 100644 (file)
@@ -41,18 +41,17 @@ struct thread_info {
 #define init_thread_info       (init_thread_union.thread_info)
 #define init_stack             (init_thread_union.stack)
 
+#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
 /* how to get the thread information struct from C */
 static inline struct thread_info *current_thread_info(void)
 {
        struct thread_info *ti;
-       unsigned long mask = PAGE_SIZE *
-               (1 << CONFIG_KERNEL_STACK_ORDER) - 1;
-        ti = (struct thread_info *) (((unsigned long) &ti) & ~mask);
+       unsigned long mask = THREAD_SIZE - 1;
+       ti = (struct thread_info *) (((unsigned long) &ti) & ~mask);
        return ti;
 }
 
 /* thread information allocation */
-#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
 #define alloc_thread_info(tsk) \
        ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
 #define free_thread_info(ti) kfree(ti)
@@ -62,7 +61,7 @@ static inline struct thread_info *current_thread_info(void)
 
 #endif
 
-#define PREEMPT_ACTIVE         0x4000000
+#define PREEMPT_ACTIVE         0x10000000
 
 #define TIF_SYSCALL_TRACE      0       /* syscall trace active */
 #define TIF_SIGPENDING         1       /* signal pending */
@@ -72,12 +71,14 @@ static inline struct thread_info *current_thread_info(void)
                                         */
 #define TIF_RESTART_BLOCK      4
 #define TIF_MEMDIE             5
+#define TIF_SYSCALL_AUDIT      6
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
-#define _TIF_RESTART_BLOCK     (1 << TIF_RESTART_BLOCK)
+#define _TIF_MEMDIE            (1 << TIF_MEMDIE)
+#define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 
 #endif
 
index ec3566c875d9ed21f903736cd179495040225940..cb52caa69925b4ae669675c605456df4bfd02a3a 100644 (file)
@@ -110,17 +110,7 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
-
-/* Type of a signal handler.  */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
-
+#include <asm-generic/signal.h>
 
 #ifdef __KERNEL__
 
index 0bb9019d58aae5283f79df1ae1b957dca6409a53..06c52ee9c06b3b398b79e30a213f134d457e18e2 100644 (file)
@@ -19,4 +19,14 @@ int unmap_page_from_agp(struct page *page);
    worth it. Would need a page for it. */
 #define flush_agp_cache() asm volatile("wbinvd":::"memory")
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+
 #endif
index 3d7627ffe67d8d0ca5c76d23f1cdcd810ef58b3f..bfebdb6906547182cb1c328d208518a300f1eabf 100644 (file)
 
 #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
 
-#define MAX_IO_APICS 32
+#define MAX_IO_APICS 128
 
 /*
  * All x86-64 systems are xAPIC compatible.
index bdbf66eab6eebb310193f7368361460ee731552b..3d2a666a5dd536f95239f2637c1ee87c4bb48376 100644 (file)
@@ -21,6 +21,8 @@ struct bug_frame {
        asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \
                     "i"(__LINE__), "i" (__stringify(__FILE__)))
 void out_of_line_bug(void);
+#else
+static inline void out_of_line_bug(void) { }
 #endif
 
 #include <asm-generic/bug.h>
index bca9b28a1a0aaac1102b175c68eefd51dcb5612f..af7ded63b51737f4b3874ed9601a189b3cd58465 100644 (file)
@@ -223,7 +223,7 @@ static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
        return 0;
 }
 
-struct fd_routine_l {
+static struct fd_routine_l {
        int (*_request_dma)(unsigned int dmanr, const char * device_id);
        void (*_free_dma)(unsigned int dmanr);
        int (*_get_dma_residue)(unsigned int dummy);
index 7efc932e8f0b360ac8bce66e5099f1b55987b043..32573749004c7cbd2ea95ac37e78006d11ca9649 100644 (file)
@@ -202,7 +202,6 @@ extern int skip_ioapic_setup;
 #define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)
 
 #ifdef CONFIG_ACPI_BOOT
-extern int io_apic_get_unique_id (int ioapic, int apic_id);
 extern int io_apic_get_version (int ioapic);
 extern int io_apic_get_redir_entries (int ioapic);
 extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int);
diff --git a/include/asm-x86_64/ioctl32.h b/include/asm-x86_64/ioctl32.h
deleted file mode 100644 (file)
index d0d227f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <linux/ioctl32.h>
index 21d56b086b9d4951f426a52f2587c5c7c35d9c7a..d3abfc6a8fd50f7f5b3d9e1c992c7b9530263126 100644 (file)
@@ -53,5 +53,7 @@ extern void die_nmi(char *str, struct pt_regs *regs);
 
 extern int panic_on_timeout;
 extern int unknown_nmi_panic;
+
+extern int check_nmi_watchdog(void);
  
 #endif /* ASM_NMI_H */
index f0581c35628e8fa2abf8385c514824c015c4a652..d641b19f6da5d7aa9324ffcc17b1b24d023806b3 100644 (file)
@@ -62,7 +62,6 @@ struct cpuinfo_x86 {
        int     x86_tlbsize;    /* number of 4K pages in DTLB/ITLB combined(in pages)*/
         __u8    x86_virt_bits, x86_phys_bits;
        __u8    x86_num_cores;
-       __u8    x86_apicid;
         __u32   x86_power;     
        __u32   extended_cpuid_level;   /* Max extended CPUID function supported */
        unsigned long loops_per_jiffy;
@@ -159,9 +158,9 @@ static inline void clear_in_cr4 (unsigned long mask)
 
 
 /*
- * User space process size. 47bits.
+ * User space process size. 47bits minus one guard page.
  */
-#define TASK_SIZE      (0x800000000000UL)
+#define TASK_SIZE      (0x800000000000UL - 4096)
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
index d0f8f8b4c3944011da8a295517bf30a58d5eb93a..f2f073642d6295fdeaa97ce94f7c9fee4510f797 100644 (file)
@@ -30,6 +30,11 @@ extern void ia32_syscall(void);
 extern void iommu_hole_init(void);
 
 extern void time_init_gtod(void);
+extern int pmtimer_mark_offset(void);
+extern unsigned int do_gettimeoffset_pm(void);
+extern u32 pmtmr_ioport;
+extern unsigned long long monotonic_base;
+extern int sysctl_vsyscall;
 
 extern void do_softirq_thunk(void);
 
index 4987ad8082ba05a9e739164847c95f440b9c1ca3..fe9b96d94815f688091d6c1318e1905d8c995ac8 100644 (file)
@@ -116,21 +116,9 @@ typedef unsigned long sigset_t;
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
-#define SIG_BLOCK          0   /* for blocking signals */
-#define SIG_UNBLOCK        1   /* for unblocking signals */
-#define SIG_SETMASK        2   /* for setting the signal mask */
+#include <asm-generic/signal.h>
 
 #ifndef __ASSEMBLY__
-/* Type of a signal handler.  */
-typedef void __signalfn_t(int);
-typedef __signalfn_t __user *__sighandler_t;
-
-typedef void __restorefn_t(void);
-typedef __restorefn_t __user *__sigrestore_t;
-
-#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
-#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
-#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
 
 struct sigaction {
        __sighandler_t sa_handler;
index b0c8d43399064c7c68a5741f017c1ca643173b96..2872da23fc7ea5990feb03c110278e012aea7d15 100644 (file)
@@ -25,6 +25,7 @@ enum vsyscall_num {
 
 #define VXTIME_TSC     1
 #define VXTIME_HPET    2
+#define VXTIME_PMTMR   3
 
 struct vxtime_data {
        long hpet_address;      /* HPET base address */
@@ -54,6 +55,8 @@ extern struct timezone sys_tz;
 extern int sysctl_vsyscall;
 extern seqlock_t xtime_lock;
 
+extern int sysctl_vsyscall;
+
 #define ARCH_HAVE_XTIME_LOCK 1
 
 #endif /* __KERNEL__ */
index aefe6d051ace16fbcf13fe2c0d86e6fda90729e8..b123cc08773d30fccf89c1d0a0aa4e79fcaa2512 100644 (file)
 #ifndef _LINUX_ACPI_H
 #define _LINUX_ACPI_H
 
+#include <linux/config.h>
+
+#ifdef CONFIG_ACPI
+
 #ifndef _LINUX
 #define _LINUX
 #endif
@@ -533,4 +537,5 @@ static inline int acpi_get_pxm(acpi_handle handle)
 
 extern int pnpacpi_disabled;
 
-#endif /*_LINUX_ACPI_H*/
+#endif /* CONFIG_ACPI */
+#endif /*_LINUX_ACPI_H*/
index 3628f7cfb1789c16ff9e5f6d20e76e9b6d69672e..19f04b04979878ffcfa2706a9acb98421537226d 100644 (file)
@@ -1,4 +1,4 @@
-/* audit.h -- Auditing support -*- linux-c -*-
+/* audit.h -- Auditing support
  *
  * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
  * All Rights Reserved.
@@ -24,6 +24,9 @@
 #ifndef _LINUX_AUDIT_H_
 #define _LINUX_AUDIT_H_
 
+#include <linux/sched.h>
+#include <linux/elf.h>
+
 /* Request and reply types */
 #define AUDIT_GET      1000    /* Get status */
 #define AUDIT_SET      1001    /* Set status (enable/disable/auditd) */
@@ -67,6 +70,7 @@
 #define AUDIT_FSGID    8
 #define AUDIT_LOGINUID 9
 #define AUDIT_PERS     10
+#define AUDIT_ARCH     11
 
                                /* These are ONLY useful when checking
                                 * at syscall exit time (AUDIT_AT_EXIT). */
 #define AUDIT_FAIL_PRINTK      1
 #define AUDIT_FAIL_PANIC       2
 
+/* distinguish syscall tables */
+#define __AUDIT_ARCH_64BIT 0x80000000
+#define __AUDIT_ARCH_LE           0x40000000
+#define AUDIT_ARCH_ALPHA       (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_ARM         (EM_ARM|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_ARMEB       (EM_ARM)
+#define AUDIT_ARCH_CRIS                (EM_CRIS|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_FRV         (EM_FRV)
+#define AUDIT_ARCH_H8300       (EM_H8_300)
+#define AUDIT_ARCH_I386                (EM_386|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_IA64                (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_M32R                (EM_M32R)
+#define AUDIT_ARCH_M68K                (EM_68K)
+#define AUDIT_ARCH_MIPS                (EM_MIPS)
+#define AUDIT_ARCH_MIPSEL      (EM_MIPS|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_MIPS64      (EM_MIPS|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_MIPSEL64    (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_PARISC      (EM_PARISC)
+#define AUDIT_ARCH_PARISC64    (EM_PARISC|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_PPC         (EM_PPC)
+#define AUDIT_ARCH_PPC64       (EM_PPC64|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_S390                (EM_S390)
+#define AUDIT_ARCH_S390X       (EM_S390|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_SH          (EM_SH)
+#define AUDIT_ARCH_SHEL                (EM_SH|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_SH64                (EM_SH|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_SHEL64      (EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_SPARC       (EM_SPARC)
+#define AUDIT_ARCH_SPARC64     (EM_SPARC64|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_V850                (EM_V850|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_X86_64      (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+
 #ifndef __KERNEL__
 struct audit_message {
        struct nlmsghdr nlh;
@@ -129,32 +165,36 @@ struct audit_buffer;
 struct audit_context;
 struct inode;
 
+#define AUDITSC_INVALID 0
+#define AUDITSC_SUCCESS 1
+#define AUDITSC_FAILURE 2
+#define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS )
 #ifdef CONFIG_AUDITSYSCALL
 /* These are defined in auditsc.c */
                                /* Public API */
 extern int  audit_alloc(struct task_struct *task);
 extern void audit_free(struct task_struct *task);
-extern void audit_syscall_entry(struct task_struct *task,
+extern void audit_syscall_entry(struct task_struct *task, int arch,
                                int major, unsigned long a0, unsigned long a1,
                                unsigned long a2, unsigned long a3);
-extern void audit_syscall_exit(struct task_struct *task, int return_code);
+extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code);
 extern void audit_getname(const char *name);
 extern void audit_putname(const char *name);
 extern void audit_inode(const char *name, const struct inode *inode);
 
                                /* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
-                                void *data);
+                                void *data, uid_t loginuid);
 extern void audit_get_stamp(struct audit_context *ctx,
-                           struct timespec *t, int *serial);
-extern int  audit_set_loginuid(struct audit_context *ctx, uid_t loginuid);
+                           struct timespec *t, unsigned int *serial);
+extern int  audit_set_loginuid(struct task_struct *task, uid_t loginuid);
 extern uid_t audit_get_loginuid(struct audit_context *ctx);
 extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
-#define audit_syscall_entry(t,a,b,c,d,e) do { ; } while (0)
-#define audit_syscall_exit(t,r) do { ; } while (0)
+#define audit_syscall_entry(t,ta,a,b,c,d,e) do { ; } while (0)
+#define audit_syscall_exit(t,f,r) do { ; } while (0)
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
 #define audit_inode(n,i) do { ; } while (0)
@@ -174,11 +214,15 @@ extern void                   audit_log_format(struct audit_buffer *ab,
                                             const char *fmt, ...)
                            __attribute__((format(printf,2,3)));
 extern void                audit_log_end(struct audit_buffer *ab);
+extern void                audit_log_hex(struct audit_buffer *ab,
+                                         const unsigned char *buf,
+                                         size_t len);
+extern void                audit_log_untrustedstring(struct audit_buffer *ab,
+                                                     const char *string);
 extern void                audit_log_d_path(struct audit_buffer *ab,
                                             const char *prefix,
                                             struct dentry *dentry,
                                             struct vfsmount *vfsmnt);
-
                                /* Private API (for auditsc.c only) */
 extern void                audit_send_reply(int pid, int seq, int type,
                                             int done, int multi,
@@ -190,6 +234,8 @@ extern void             audit_log_lost(const char *message);
 #define audit_log_vformat(b,f,a) do { ; } while (0)
 #define audit_log_format(b,f,...) do { ; } while (0)
 #define audit_log_end(b) do { ; } while (0)
+#define audit_log_hex(a,b,l) do { ; } while (0)
+#define audit_log_untrustedstring(a,s) do { ; } while (0)
 #define audit_log_d_path(b,p,d,v) do { ; } while (0)
 #endif
 #endif
index da0e27de752c45ade3645d06bdae6cbf233cd645..4bf9f33048e2aa22104b528e1f8c92e93e677e20 100644 (file)
@@ -29,9 +29,9 @@
 #define SAMPLE_TYPE_AWE32      0x20
 #endif
 
-#ifndef _PATCHKEY
-#define _PATCHKEY(id) ((id<<8)|0xfd)
-#endif
+#define _LINUX_PATCHKEY_H_INDIRECT
+#include <linux/patchkey.h>
+#undef _LINUX_PATCHKEY_H_INDIRECT
 
 /*----------------------------------------------------------------
  * patch information record
index 54f820832c730e71de9273bdf035a13ba95d2885..7e736e201c46c125eb11a1722f5a5e31fabcd4df 100644 (file)
@@ -77,7 +77,6 @@ extern int flush_old_exec(struct linux_binprm * bprm);
 extern int setup_arg_pages(struct linux_binprm * bprm,
                           unsigned long stack_top,
                           int executable_stack);
-extern int copy_strings(int argc,char __user * __user * argv,struct linux_binprm *bprm); 
 extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
 extern void compute_creds(struct linux_binprm *binprm);
 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
index f21af067d015f4cad91e9db214931b2215cd41c2..927daa86c9b366e52b41ff388303879896e6c6a4 100644 (file)
@@ -49,7 +49,7 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
 /* Frequency values here are CPU kHz so that hardware which doesn't run 
  * with some frequencies can complain without having to guess what per 
  * cent / per mille means. 
- * Maximum transition latency is in microseconds - if it's unknown,
+ * Maximum transition latency is in nanoseconds - if it's unknown,
  * CPUFREQ_ETERNAL shall be used.
  */
 
index cf470459fa691985be0b4c79fb86a7c2945f534a..df94c0de53f2b6b0d91c56142838766db5fd0a3b 100644 (file)
@@ -273,9 +273,6 @@ struct device {
                                           BIOS data relevant to device) */
        struct dev_pm_info      power;
 
-       u32             detach_state;   /* State to enter when device is
-                                          detached from its driver. */
-
        u64             *dma_mask;      /* dma mask (if dma'able device) */
        u64             coherent_dma_mask;/* Like dma_mask, but for
                                             alloc_coherent mappings as
index 17c55df13615a9bda172e80c6f4711c11f3183e8..ff71d2af5da33ac711da7f64957d8d93bad4f91f 100644 (file)
@@ -13,6 +13,8 @@
  * This should be a per-architecture thing, to allow different
  * error and pointer decisions.
  */
+#define IS_ERR_VALUE(x) unlikely((x) > (unsigned long)-1000L)
+
 static inline void *ERR_PTR(long error)
 {
        return (void *) error;
@@ -25,7 +27,7 @@ static inline long PTR_ERR(const void *ptr)
 
 static inline long IS_ERR(const void *ptr)
 {
-       return unlikely((unsigned long)ptr > (unsigned long)-1000L);
+       return IS_ERR_VALUE((unsigned long)ptr);
 }
 
 #endif /* _LINUX_ERR_H */
index 396c48cbaeb1419117ff3a9b8f8c1b975481c011..a1478258d00243c93fec79a8e66b07739caeea92 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)eth.h       1.0.4   05/13/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  *             Relocated to include/linux where it belongs by Alan Cox 
@@ -55,19 +55,33 @@ static inline int is_zero_ether_addr(const u8 *addr)
        return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
 }
 
+/**
+ * is_multicast_ether_addr - Determine if the given Ethernet address is a
+ * multicast address.
+ *
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is a multicast address.
+ */
+static inline int is_multicast_ether_addr(const u8 *addr)
+{
+       return addr[0] & 0x01;
+}
+
 /**
  * is_valid_ether_addr - Determine if the given Ethernet address is valid
  * @addr: Pointer to a six-byte array containing the Ethernet address
  *
  * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
- * a multicast address, and is not FF:FF:FF:FF:FF:FF.  The multicast
- * and FF:FF:... tests are combined into the single test "!(addr[0]&1)".
+ * a multicast address, and is not FF:FF:FF:FF:FF:FF.
  *
  * Return true if the address is valid.
  */
 static inline int is_valid_ether_addr(const u8 *addr)
 {
-       return !(addr[0]&1) && !is_zero_ether_addr(addr);
+       /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
+        * explicitly check for it here. */
+       return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
 }
 
 /**
@@ -83,6 +97,6 @@ static inline void random_ether_addr(u8 *addr)
        addr [0] &= 0xfe;       /* clear multicast bit */
        addr [0] |= 0x02;       /* set local assignment bit (IEEE802) */
 }
-#endif
+#endif /* __KERNEL__ */
 
 #endif /* _LINUX_ETHERDEVICE_H */
index c85b210490ea33a1cf5910fb309911266f44adb3..a0ab26aab450db653ab44d45296bc2809b42b13a 100644 (file)
@@ -256,6 +256,7 @@ struct net_device;
 u32 ethtool_op_get_link(struct net_device *dev);
 u32 ethtool_op_get_tx_csum(struct net_device *dev);
 int ethtool_op_set_tx_csum(struct net_device *dev, u32 data);
+int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data);
 u32 ethtool_op_get_sg(struct net_device *dev);
 int ethtool_op_set_sg(struct net_device *dev, u32 data);
 u32 ethtool_op_get_tso(struct net_device *dev);
index 2e5ee47f3e1ec030b0920d4e19b2236362561ad2..002f6367697d8b8d1ad5d83a5df4aa060e222616 100644 (file)
@@ -10,7 +10,7 @@
  * Author:     Lawrence V. Stefani, <stefani@lkg.dec.com>
  *
  *             fddidevice.h is based on previous trdevice.h work by
- *                     Ross Biro, <bir7@leland.Stanford.Edu>
+ *                     Ross Biro
  *                     Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *                     Alan Cox, <gw4pts@gw4pts.ampr.org>
  *
index 4edba067a7178103f78544717a91ef98dae7994d..0180102dace1ef28edcd1de1199cfe65f3ba8499 100644 (file)
@@ -1341,7 +1341,7 @@ extern int fs_may_remount_ro(struct super_block *);
 
 extern int check_disk_change(struct block_device *);
 extern int invalidate_inodes(struct super_block *);
-extern int __invalidate_device(struct block_device *, int);
+extern int __invalidate_device(struct block_device *);
 extern int invalidate_partition(struct gendisk *, int);
 unsigned long invalidate_mapping_pages(struct address_space *mapping,
                                        pgoff_t start, pgoff_t end);
index b1272f822cfa15cd0b1acca21267c9a73174ee37..cd623eccdbea61c8e8b8eba1f931645b95c01115 100644 (file)
@@ -67,6 +67,8 @@ int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mo
 void gameport_close(struct gameport *gameport);
 void gameport_rescan(struct gameport *gameport);
 
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+
 void __gameport_register_port(struct gameport *gameport, struct module *owner);
 static inline void gameport_register_port(struct gameport *gameport)
 {
@@ -75,6 +77,29 @@ static inline void gameport_register_port(struct gameport *gameport)
 
 void gameport_unregister_port(struct gameport *gameport);
 
+void gameport_set_phys(struct gameport *gameport, const char *fmt, ...)
+       __attribute__ ((format (printf, 2, 3)));
+
+#else
+
+static inline void gameport_register_port(struct gameport *gameport)
+{
+       return;
+}
+
+static inline void gameport_unregister_port(struct gameport *gameport)
+{
+       return;
+}
+
+static inline void gameport_set_phys(struct gameport *gameport,
+                                    const char *fmt, ...)
+{
+       return;
+}
+
+#endif
+
 static inline struct gameport *gameport_allocate_port(void)
 {
        struct gameport *gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL);
@@ -92,9 +117,6 @@ static inline void gameport_set_name(struct gameport *gameport, const char *name
        strlcpy(gameport->name, name, sizeof(gameport->name));
 }
 
-void gameport_set_phys(struct gameport *gameport, const char *fmt, ...)
-       __attribute__ ((format (printf, 2, 3)));
-
 /*
  * Use the following fucntions to manipulate gameport's per-port
  * driver-specific data.
index ebc712e910669ea863b65c684560e1f0d756244f..8336dba18971bb85ce5075977d457e1ff4551c0f 100644 (file)
 #define __IRQ_MASK(x)  ((1UL << (x))-1)
 
 #define PREEMPT_MASK   (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
-#define HARDIRQ_MASK   (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
 #define SOFTIRQ_MASK   (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
+#define HARDIRQ_MASK   (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
 
 #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT)
 #define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)
 #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
 
+#if PREEMPT_ACTIVE < (1 << (HARDIRQ_SHIFT + HARDIRQ_BITS))
+#error PREEMPT_ACTIVE is too low!
+#endif
+
 #define hardirq_count()        (preempt_count() & HARDIRQ_MASK)
 #define softirq_count()        (preempt_count() & SOFTIRQ_MASK)
 #define irq_count()    (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
index 89b3a4a5b7615a20c3be6a2e7026cbe1ea5563e4..9debe6bbe5f0265cf4ab5dd81248d2b9d4d4f04b 100644 (file)
@@ -10,7 +10,7 @@
  * Author:     Jes Sorensen, <Jes.Sorensen@cern.ch>
  *
  *             hippidevice.h is based on previous fddidevice.h work by
- *                     Ross Biro, <bir7@leland.Stanford.Edu>
+ *                     Ross Biro
  *                     Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *                     Alan Cox, <gw4pts@gw4pts.ampr.org>
  *                     Lawrence V. Stefani, <stefani@lkg.dec.com>
index 9cfc0999becba75c452cda6fe3deeb03ac4b502b..336d6e509f59df38c9588f8597f72232e8837693 100644 (file)
@@ -664,7 +664,6 @@ typedef struct ide_drive_s {
 
        struct request          *rq;    /* current request */
        struct ide_drive_s      *next;  /* circular list of hwgroup drives */
-       struct ide_driver_s     *driver;/* (ide_driver_t *) */
        void            *driver_data;   /* extra driver data */
        struct hd_driveid       *id;    /* drive model identification info */
        struct proc_dir_entry *proc;    /* /proc/ide/ directory entry */
@@ -758,6 +757,8 @@ typedef struct ide_drive_s {
        struct semaphore gendev_rel_sem;        /* to deal with device release() */
 } ide_drive_t;
 
+#define to_ide_device(dev)container_of(dev, ide_drive_t, gendev)
+
 #define IDE_CHIPSET_PCI_MASK   \
     ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
 #define IDE_CHIPSET_IS_PCI(c)  ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
@@ -1086,28 +1087,20 @@ enum {
  */
 typedef struct ide_driver_s {
        struct module                   *owner;
-       const char                      *name;
        const char                      *version;
        u8                              media;
-       unsigned busy                   : 1;
        unsigned supports_dsc_overlap   : 1;
-       int             (*cleanup)(ide_drive_t *);
        ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t);
        int             (*end_request)(ide_drive_t *, int, int);
        ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8);
        ide_startstop_t (*abort)(ide_drive_t *, struct request *rq);
        int             (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
        ide_proc_entry_t        *proc;
-       int             (*attach)(ide_drive_t *);
        void            (*ata_prebuilder)(ide_drive_t *);
        void            (*atapi_prebuilder)(ide_drive_t *);
        struct device_driver    gen_driver;
-       struct list_head drives;
-       struct list_head drivers;
 } ide_driver_t;
 
-#define DRIVER(drive)          ((drive)->driver)
-
 int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long);
 
 /*
@@ -1328,8 +1321,6 @@ extern void ide_init_subdrivers(void);
 
 void ide_init_disk(struct gendisk *, ide_drive_t *);
 
-extern int ata_attach(ide_drive_t *);
-
 extern int ideprobe_init(void);
 
 extern void ide_scan_pcibus(int scan_direction) __init;
@@ -1342,11 +1333,8 @@ extern void default_hwif_iops(ide_hwif_t *);
 extern void default_hwif_mmiops(ide_hwif_t *);
 extern void default_hwif_transport(ide_hwif_t *);
 
-int ide_register_driver(ide_driver_t *driver);
-void ide_unregister_driver(ide_driver_t *driver);
-int ide_register_subdriver(ide_drive_t *, ide_driver_t *);
-int ide_unregister_subdriver (ide_drive_t *drive);
-int ide_replace_subdriver(ide_drive_t *drive, const char *driver);
+void ide_register_subdriver(ide_drive_t *, ide_driver_t *);
+void ide_unregister_subdriver(ide_drive_t *, ide_driver_t *);
 
 #define ON_BOARD               1
 #define NEVER_BOARD            0
index 110282dbd3e0b7c8f301ca07d3afe4c04074722f..d73a9d62f208a7a2ad3fb9fd01c2800c4dade0da 100644 (file)
@@ -8,7 +8,7 @@
  * Version:    @(#)if.h        1.0.2   04/18/93
  *
  * Authors:    Original taken from Berkeley UNIX 4.3, (c) UCB 1982-1988
- *             Ross Biro, <bir7@leland.Stanford.Edu>
+ *             Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  *             This program is free software; you can redistribute it and/or
index bbf49bcd77053db6100ea5609baf7d4f7b9ee32b..0856548a2a08b2eadab1b6e9de56dfc667993673 100644 (file)
@@ -9,7 +9,7 @@
  *
  * Authors:    Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988
  *             Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source.
- *             Ross Biro, <bir7@leland.Stanford.Edu>
+ *             Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Florian La Roche,
  *             Jonathan Layes <layes@loran.com>
index e75e832b7ff0dd56d79bb07029a89a16c067afa2..76525760ba48398550dc856ec90c9a2ca55a05a7 100644 (file)
@@ -6,7 +6,7 @@
 #define LTALK_ALEN             1
 
 #ifdef __KERNEL__
-extern void ltalk_setup(struct net_device *);
+extern struct net_device *alloc_ltalkdev(int sizeof_priv);
 #endif
 
 #endif
index 0485b256d043adbb3c823f9a0369021643695820..004e6f09a6e2daf89387bb2d1794cdd377c0ec1d 100644 (file)
@@ -23,7 +23,7 @@ struct shaper
        __u32 shapeclock;
        unsigned long recovery; /* Time we can next clock a packet out on
                                   an empty queue */
-        unsigned long locked;
+       struct semaphore sem;
         struct net_device_stats stats;
        struct net_device *dev;
        int  (*hard_start_xmit) (struct sk_buff *skb,
@@ -38,7 +38,6 @@ struct shaper
        int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh);
        void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char *  haddr);
        struct net_device_stats* (*get_stats)(struct net_device *dev);
-       wait_queue_head_t  wait_queue;
        struct timer_list timer;
 };
 
index 4fd451f81ccb6e814311120774e399e1af16fb67..3fba9e2f5427d633a9260854112647e9294b07a3 100644 (file)
@@ -9,7 +9,7 @@
  *
  * Author:     Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Donald Becker, <becker@super.org>
- *    Peter De Schrijver, <stud11@cc4.kuleuven.ac.be>
+ *             Peter De Schrijver, <stud11@cc4.kuleuven.ac.be>
  *
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
 #ifndef _LINUX_IF_TR_H
 #define _LINUX_IF_TR_H
 
+#include <asm/byteorder.h>     /* For __be16 */
 
 /* IEEE 802.5 Token-Ring magic constants.  The frame sizes omit the preamble
    and FCS/CRC (frame check sequence). */
-#define TR_ALEN        6               /* Octets in one ethernet addr   */
-#define TR_HLEN   (sizeof(struct trh_hdr)+sizeof(struct trllc))
-#define AC                     0x10
-#define LLC_FRAME 0x40
-#if 0
-#define ETH_HLEN       14              /* Total octets in header.       */
-#define ETH_ZLEN       60              /* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN   1500            /* Max. octets in payload        */
-#define ETH_FRAME_LEN  1514            /* Max. octets in frame sans FCS */
-#endif
-
+#define TR_ALEN                6               /* Octets in one token-ring addr */
+#define TR_HLEN        (sizeof(struct trh_hdr)+sizeof(struct trllc))
+#define AC             0x10
+#define LLC_FRAME      0x40
 
 /* LLC and SNAP constants */
-#define EXTENDED_SAP 0xAA
-#define UI_CMD       0x03
+#define EXTENDED_SAP   0xAA
+#define UI_CMD         0x03
 
 /* This is an Token-Ring frame header. */
 struct trh_hdr {
@@ -44,8 +38,8 @@ struct trh_hdr {
        __u8  fc;                       /* frame control field */
        __u8  daddr[TR_ALEN];           /* destination address */
        __u8  saddr[TR_ALEN];           /* source address */
-       __u16 rcf;                      /* route control field */
-       __u16 rseg[8];                  /* routing registers */
+       __be16 rcf;                     /* route control field */
+       __be16 rseg[8];                 /* routing registers */
 };
 
 #ifdef __KERNEL__
@@ -63,7 +57,7 @@ struct trllc {
        __u8  ssap;                     /* source SAP */
        __u8  llc;                      /* LLC control field */
        __u8  protid[3];                /* protocol id */
-       __u16 ethertype;                /* ether type field */
+       __be16 ethertype;               /* ether type field */
 };
 
 /* Token-Ring statistics collection data. */
@@ -96,14 +90,13 @@ struct tr_statistics {
 };
 
 /* source routing stuff */
-
-#define TR_RII 0x80
-#define TR_RCF_DIR_BIT 0x80
-#define TR_RCF_LEN_MASK 0x1f00
-#define TR_RCF_BROADCAST 0x8000         /* all-routes broadcast */
-#define TR_RCF_LIMITED_BROADCAST 0xC000 /* single-route broadcast */
-#define TR_RCF_FRAME2K 0x20
-#define TR_RCF_BROADCAST_MASK 0xC000
-#define TR_MAXRIFLEN 18
+#define TR_RII                         0x80
+#define TR_RCF_DIR_BIT                 0x80
+#define TR_RCF_LEN_MASK        0x1f00
+#define TR_RCF_BROADCAST       0x8000  /* all-routes broadcast */
+#define TR_RCF_LIMITED_BROADCAST 0xC000        /* single-route broadcast */
+#define TR_RCF_FRAME2K                 0x20
+#define TR_RCF_BROADCAST_MASK  0xC000
+#define TR_MAXRIFLEN           18
 
 #endif /* _LINUX_IF_TR_H */
index 6fafb27877a7d5adbac3b0419f82a37eed1fc9c7..7e1e15f934f340851c503c789e701724d81bcb0c 100644 (file)
@@ -29,6 +29,7 @@ struct ipv4_devconf
        int     no_xfrm;
        int     no_policy;
        int     force_igmp_version;
+       int     promote_secondaries;
        void    *sysctl;
 };
 
@@ -71,6 +72,7 @@ struct in_device
 #define IN_DEV_SEC_REDIRECTS(in_dev)   (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
 #define IN_DEV_IDTAG(in_dev)           ((in_dev)->cnf.tag)
 #define IN_DEV_MEDIUM_ID(in_dev)       ((in_dev)->cnf.medium_id)
+#define IN_DEV_PROMOTE_SECONDARIES(in_dev)     (ipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries)
 
 #define IN_DEV_RX_REDIRECTS(in_dev) \
        ((IN_DEV_FORWARD(in_dev) && \
index 88121166d7153b35babc6f7be0768b33746ecf29..fd1756d3a47e9b29f77f917b730464f4fb5daa33 100644 (file)
@@ -42,8 +42,6 @@
  *
  *****************************************************************************/
 
-static char ixjuser_h_rcsid[] = "$Id: ixjuser.h,v 4.1 2001/08/05 00:17:37 craigs Exp $";
-
 #include <linux/telephony.h>
 
 
index f20c163de4f5162b54cdd2603423d471756023ec..99ddba5a4e009b553a56e2c25b1d89c41154fb8e 100644 (file)
@@ -43,6 +43,9 @@ typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *,
 struct kprobe {
        struct hlist_node hlist;
 
+       /* list of kprobes for multi-handler support */
+       struct list_head list;
+
        /* location of the probe point */
        kprobe_opcode_t *addr;
 
index 505160ab472b0198ec5393380ce7c21b2fad85d1..b009f801e7c5880d671668fa31176bf824d4bf31 100644 (file)
@@ -410,6 +410,7 @@ extern u8 ata_chk_err(struct ata_port *ap);
 extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf);
 extern int ata_port_start (struct ata_port *ap);
 extern void ata_port_stop (struct ata_port *ap);
+extern void ata_host_stop (struct ata_host_set *host_set);
 extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
 extern void ata_qc_prep(struct ata_queued_cmd *qc);
 extern int ata_qc_issue_prot(struct ata_queued_cmd *qc);
@@ -466,12 +467,34 @@ static inline u8 ata_chk_status(struct ata_port *ap)
        return ap->ops->check_status(ap);
 }
 
+
+/**
+ *     ata_pause - Flush writes and pause 400 nanoseconds.
+ *     @ap: Port to wait for.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
 static inline void ata_pause(struct ata_port *ap)
 {
        ata_altstatus(ap);
        ndelay(400);
 }
 
+
+/**
+ *     ata_busy_wait - Wait for a port status register
+ *     @ap: Port to wait for.
+ *
+ *     Waits up to max*10 microseconds for the selected bits in the port's
+ *     status register to be cleared.
+ *     Returns final value of status register.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
 static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
                               unsigned int max)
 {
@@ -486,6 +509,18 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
        return status;
 }
 
+
+/**
+ *     ata_wait_idle - Wait for a port to be idle.
+ *     @ap: Port to wait for.
+ *
+ *     Waits up to 10ms for port's BUSY and DRQ signals to clear.
+ *     Returns final value of status register.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
 static inline u8 ata_wait_idle(struct ata_port *ap)
 {
        u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
@@ -524,6 +559,18 @@ static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, uns
                tf->device = ATA_DEVICE_OBS | ATA_DEV1;
 }
 
+
+/**
+ *     ata_irq_on - Enable interrupts on a port.
+ *     @ap: Port on which interrupts are enabled.
+ *
+ *     Enable interrupts on a legacy IDE device using MMIO or PIO,
+ *     wait for idle, clear any pending interrupts.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
 static inline u8 ata_irq_on(struct ata_port *ap)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -543,6 +590,18 @@ static inline u8 ata_irq_on(struct ata_port *ap)
        return tmp;
 }
 
+
+/**
+ *     ata_irq_ack - Acknowledge a device interrupt.
+ *     @ap: Port on which interrupts are enabled.
+ *
+ *     Wait up to 10 ms for legacy IDE device to become idle (BUSY
+ *     or BUSY+DRQ clear).  Obtain dma status and port status from
+ *     device.  Clear the interrupt.  Return port status.
+ *
+ *     LOCKING:
+ */
+
 static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
 {
        unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
@@ -584,6 +643,13 @@ static inline void scr_write(struct ata_port *ap, unsigned int reg, u32 val)
        ap->ops->scr_write(ap, reg, val);
 }
 
+static inline void scr_write_flush(struct ata_port *ap, unsigned int reg, 
+                                  u32 val)
+{
+       ap->ops->scr_write(ap, reg, val);
+       (void) ap->ops->scr_read(ap, reg);
+}
+
 static inline unsigned int sata_dev_present(struct ata_port *ap)
 {
        return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
index 20971fe78a8d31bdbf456348ccbe71d925b6fd6f..374b615ea9ea95ec130aeb10dfffc31f0f29a6f1 100644 (file)
 #define ADVERTISE_SLCT          0x001f  /* Selector bits               */
 #define ADVERTISE_CSMA          0x0001  /* Only selector supported     */
 #define ADVERTISE_10HALF        0x0020  /* Try for 10mbps half-duplex  */
+#define ADVERTISE_1000XFULL     0x0020  /* Try for 1000BASE-X full-duplex */
 #define ADVERTISE_10FULL        0x0040  /* Try for 10mbps full-duplex  */
+#define ADVERTISE_1000XHALF     0x0040  /* Try for 1000BASE-X half-duplex */
 #define ADVERTISE_100HALF       0x0080  /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE    0x0080  /* Try for 1000BASE-X pause    */
 #define ADVERTISE_100FULL       0x0100  /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100  /* Try for 1000BASE-X asym pause */
 #define ADVERTISE_100BASE4      0x0200  /* Try for 100mbps 4k packets  */
 #define ADVERTISE_PAUSE_CAP     0x0400  /* Try for pause               */
 #define ADVERTISE_PAUSE_ASYM    0x0800  /* Try for asymetric pause     */
 /* Link partner ability register. */
 #define LPA_SLCT                0x001f  /* Same as advertise selector  */
 #define LPA_10HALF              0x0020  /* Can do 10mbps half-duplex   */
+#define LPA_1000XFULL           0x0020  /* Can do 1000BASE-X full-duplex */
 #define LPA_10FULL              0x0040  /* Can do 10mbps full-duplex   */
+#define LPA_1000XHALF           0x0040  /* Can do 1000BASE-X half-duplex */
 #define LPA_100HALF             0x0080  /* Can do 100mbps half-duplex  */
+#define LPA_1000XPAUSE          0x0080  /* Can do 1000BASE-X pause     */
 #define LPA_100FULL             0x0100  /* Can do 100mbps full-duplex  */
+#define LPA_1000XPAUSE_ASYM     0x0100  /* Can do 1000BASE-X pause asym*/
 #define LPA_100BASE4            0x0200  /* Can do 100mbps 4k packets   */
 #define LPA_PAUSE_CAP           0x0400  /* Can pause                   */
 #define LPA_PAUSE_ASYM          0x0800  /* Can pause asymetrically     */
index 8b007ad2d450ca586722005c49fefe6f2132bdbc..17518fe0b311aa0ed08122bc459970d6a21ea139 100644 (file)
@@ -637,9 +637,9 @@ extern unsigned long do_mremap(unsigned long addr,
  * These functions are passed a count `nr_to_scan' and a gfpmask.  They should
  * scan `nr_to_scan' objects, attempting to free them.
  *
- * The callback must the number of objects which remain in the cache.
+ * The callback must return the number of objects which remain in the cache.
  *
- * The callback will be passes nr_to_scan == 0 when the VM is querying the
+ * The callback will be passed nr_to_scan == 0 when the VM is querying the
  * cache size, so a fastpath for that case is appropriate.
  */
 typedef int (*shrinker_t)(int nr_to_scan, unsigned int gfp_mask);
index 7b904c5102f6b96bd9d5cfa3fd956c8334bc5c59..896342817b97bab2a7b20bb247115317224583fe 100644 (file)
@@ -195,6 +195,33 @@ struct _mmc_csd {
 #define MMC_VDD_35_36  0x00800000      /* VDD voltage 3.5 ~ 3.6 */
 #define MMC_CARD_BUSY  0x80000000      /* Card Power up status bit */
 
+/*
+ * Card Command Classes (CCC)
+ */
+#define CCC_BASIC              (1<<0)  /* (0) Basic protocol functions */
+                                       /* (CMD0,1,2,3,4,7,9,10,12,13,15) */
+#define CCC_STREAM_READ                (1<<1)  /* (1) Stream read commands */
+                                       /* (CMD11) */
+#define CCC_BLOCK_READ         (1<<2)  /* (2) Block read commands */
+                                       /* (CMD16,17,18) */
+#define CCC_STREAM_WRITE       (1<<3)  /* (3) Stream write commands */
+                                       /* (CMD20) */
+#define CCC_BLOCK_WRITE                (1<<4)  /* (4) Block write commands */
+                                       /* (CMD16,24,25,26,27) */
+#define CCC_ERASE              (1<<5)  /* (5) Ability to erase blocks */
+                                       /* (CMD32,33,34,35,36,37,38,39) */
+#define CCC_WRITE_PROT         (1<<6)  /* (6) Able to write protect blocks */
+                                       /* (CMD28,29,30) */
+#define CCC_LOCK_CARD          (1<<7)  /* (7) Able to lock down card */
+                                       /* (CMD16,CMD42) */
+#define CCC_APP_SPEC           (1<<8)  /* (8) Application specific */
+                                       /* (CMD55,56,57,ACMD*) */
+#define CCC_IO_MODE            (1<<9)  /* (9) I/O mode */
+                                       /* (CMD5,39,40,52,53) */
+#define CCC_SWITCH             (1<<10) /* (10) High speed switch */
+                                       /* (CMD6,34,35,36,37,50) */
+                                       /* (11) Reserved */
+                                       /* (CMD?) */
 
 /*
  * CSD field definitions
index dea1b0083661c146be748832046fd00483690818..3ca880463c47426029bad70eb02f30ad3ab41015 100644 (file)
@@ -20,9 +20,6 @@ int mpage_writepages(struct address_space *mapping,
                struct writeback_control *wbc, get_block_t get_block);
 int mpage_writepage(struct page *page, get_block_t *get_block,
                struct writeback_control *wbc);
-int __mpage_writepages(struct address_space *mapping,
-               struct writeback_control *wbc, get_block_t get_block,
-               writepage_t writepage);
 
 static inline int
 generic_writepages(struct address_space *mapping, struct writeback_control *wbc)
index e5914c1f0c4db8464b57704994c0e87c68b545ff..20cb226b22685fcd55428104c84b64ba14c4443c 100644 (file)
@@ -7,7 +7,7 @@
  * Version:    @(#)net.h       1.0.3   05/25/93
  *
  * Authors:    Orest Zborowski, <obz@Kodak.COM>
- *             Ross Biro, <bir7@leland.Stanford.Edu>
+ *             Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  *             This program is free software; you can redistribute it and/or
@@ -101,7 +101,6 @@ enum sock_type {
  *  @sk: internal networking protocol agnostic socket representation
  *  @wait: wait queue for several uses
  *  @type: socket type (%SOCK_STREAM, etc)
- *  @passcred: credentials (used only in Unix Sockets (aka PF_LOCAL))
  */
 struct socket {
        socket_state            state;
index 8d775be67833e74993bc3b7c18e10ea33c799f39..ba5d1236aa170c75a92c1137e34b3c0fb242f93b 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)dev.h       1.0.10  08/12/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Corey Minyard <wf-rch!minyard@relay.EU.net>
  *             Donald J. Becker, <becker@cesdis.gsfc.nasa.gov>
@@ -204,7 +204,7 @@ struct hh_cache
        /* cached hardware header; allow for machine alignment needs.        */
 #define HH_DATA_MOD    16
 #define HH_DATA_OFF(__len) \
-       (HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1)))
+       (HH_DATA_MOD - (((__len - 1) & (HH_DATA_MOD - 1)) + 1))
 #define HH_DATA_ALIGN(__len) \
        (((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1))
        unsigned long   hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)];
@@ -401,7 +401,7 @@ struct net_device
        } reg_state;
 
        /* Net device features */
-       int                     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_NO_CSUM                4       /* Does not require checksum. F.e. loopack. */
@@ -503,7 +503,7 @@ static inline void *netdev_priv(struct net_device *dev)
 #define SET_NETDEV_DEV(net, pdev)      ((net)->class_dev.dev = (pdev))
 
 struct packet_type {
-       unsigned short          type;   /* This is really htons(ether_type).    */
+       __be16                  type;   /* This is really htons(ether_type).    */
        struct net_device               *dev;   /* NULL is wildcarded here              */
        int                     (*func) (struct sk_buff *, struct net_device *,
                                         struct packet_type *);
@@ -913,6 +913,7 @@ extern void         dev_mc_discard(struct net_device *dev);
 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);
+extern void            netdev_features_change(struct net_device *dev);
 /* Load a device via the kmod */
 extern void            dev_load(const char *name);
 extern void            dev_mcast_init(void);
index f731abdc1a29a9cd1d5290d6a8121414377e88df..b2738ac8bc999f30c0840f318c5da73d95214fed 100644 (file)
@@ -110,6 +110,7 @@ struct netlink_skb_parms
        __u32                   dst_pid;
        __u32                   dst_groups;
        kernel_cap_t            eff_cap;
+       __u32                   loginuid;       /* Login (audit) uid */
 };
 
 #define NETLINK_CB(skb)                (*(struct netlink_skb_parms*)&((skb)->cb))
index 9303a003e9ab85147dcafc82c6d74fc27d468bf5..5937dd6053c398d594889a02c4894924f577ba16 100644 (file)
@@ -56,6 +56,7 @@ extern int notifier_call_chain(struct notifier_block **n, unsigned long val, voi
 #define NETDEV_CHANGEADDR      0x0008
 #define NETDEV_GOING_DOWN      0x0009
 #define NETDEV_CHANGENAME      0x000A
+#define NETDEV_FEAT_CHANGE     0x000B
 
 #define SYS_DOWN       0x0001  /* Notify of system down */
 #define SYS_RESTART    SYS_DOWN
diff --git a/include/linux/patchkey.h b/include/linux/patchkey.h
new file mode 100644 (file)
index 0000000..d974a6e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * <linux/patchkey.h> -- definition of _PATCHKEY macro
+ *
+ * Copyright (C) 2005 Stuart Brady
+ *
+ * This exists because awe_voice.h defined its own _PATCHKEY and it wasn't
+ * clear whether removing this would break anything in userspace.
+ *
+ * Do not include this file directly.  Please use <sys/soundcard.h> instead.
+ * For kernel code, use <linux/soundcard.h>
+ */
+
+#ifndef _LINUX_PATCHKEY_H_INDIRECT
+#error "patchkey.h included directly"
+#endif
+
+#ifndef _LINUX_PATCHKEY_H
+#define _LINUX_PATCHKEY_H
+
+/* Endian macros. */
+#ifdef __KERNEL__
+#  include <asm/byteorder.h>
+#else
+#  include <endian.h>
+#endif
+
+#if defined(__KERNEL__)
+#  if defined(__BIG_ENDIAN)
+#    define _PATCHKEY(id) (0xfd00|id)
+#  elif defined(__LITTLE_ENDIAN)
+#    define _PATCHKEY(id) ((id<<8)|0x00fd)
+#  else
+#    error "could not determine byte order"
+#  endif
+#elif defined(__BYTE_ORDER)
+#  if __BYTE_ORDER == __BIG_ENDIAN
+#    define _PATCHKEY(id) (0xfd00|id)
+#  elif __BYTE_ORDER == __LITTLE_ENDIAN
+#    define _PATCHKEY(id) ((id<<8)|0x00fd)
+#  else
+#    error "could not determine byte order"
+#  endif
+#endif
+
+#endif /* _LINUX_PATCHKEY_H */
index 3c89148ae28a6e28d4ec21e680a6e383fb885e3d..b5238bd188302be2bf941a11594a61814c40120f 100644 (file)
@@ -671,6 +671,7 @@ struct pci_driver {
        int  (*suspend) (struct pci_dev *dev, pm_message_t state);      /* Device suspended */
        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 device_driver    driver;
        struct pci_dynids dynids;
@@ -810,7 +811,6 @@ void pci_set_master(struct pci_dev *dev);
 int pci_set_mwi(struct pci_dev *dev);
 void pci_clear_mwi(struct pci_dev *dev);
 int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
-int pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_assign_resource(struct pci_dev *dev, int i);
 
@@ -941,7 +941,6 @@ static inline void pci_set_master(struct pci_dev *dev) { }
 static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
 static inline void pci_disable_device(struct pci_dev *dev) { }
 static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; }
-static inline int pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; }
 static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;}
 static inline int pci_register_driver(struct pci_driver *drv) { return 0;}
 static inline void pci_unregister_driver(struct pci_driver *drv) { }
index 5d5820a4cf1097bb8bc561fc8ce8ee38be9c5f25..b8b4ebf9abf1f3b28089030edcb067f4f08a080f 100644 (file)
 #define PCI_DEVICE_ID_MYLEX_DAC960_LA  0x0020
 #define PCI_DEVICE_ID_MYLEX_DAC960_LP  0x0050
 #define PCI_DEVICE_ID_MYLEX_DAC960_BA  0xBA56
+#define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166
 
 #define PCI_VENDOR_ID_PICOP            0x1066
 #define PCI_DEVICE_ID_PICOP_PT86C52X   0x0001
 #define PCI_DEVICE_ID_APPLE_KL_USB_P   0x0026
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P        0x0027
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15        0x002d
+#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15        0x002e
 #define PCI_DEVICE_ID_APPLE_UNI_N_FW2  0x0030
 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2        0x0032
 #define PCI_DEVIEC_ID_APPLE_UNI_N_ATA  0x0033
 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL    0x0258
 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL    0x0259
 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL    0x025B
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE  0x0265
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2        0x0267
+#define PCI_DEVICE_ID_NVIDIA_NVENET_12         0x0268
+#define PCI_DEVICE_ID_NVIDIA_NVENET_13         0x0269
+#define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO       0x026B
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800  0x0280
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X    0x0281
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE     0x0282
 
 #define PCI_VENDOR_ID_BROADCOM         0x14e4
 #define PCI_DEVICE_ID_TIGON3_5752      0x1600
+#define PCI_DEVICE_ID_TIGON3_5752M     0x1601
 #define PCI_DEVICE_ID_TIGON3_5700      0x1644
 #define PCI_DEVICE_ID_TIGON3_5701      0x1645
 #define PCI_DEVICE_ID_TIGON3_5702      0x1646
 #define PCI_DEVICE_ID_TIGON3_5703      0x1647
 #define PCI_DEVICE_ID_TIGON3_5704      0x1648
 #define PCI_DEVICE_ID_TIGON3_5704S_2   0x1649
+#define PCI_DEVICE_ID_NX2_5706         0x164a
 #define PCI_DEVICE_ID_TIGON3_5702FE    0x164d
 #define PCI_DEVICE_ID_TIGON3_5705      0x1653
 #define PCI_DEVICE_ID_TIGON3_5705_2    0x1654
 #define PCI_DEVICE_ID_TIGON3_5702X     0x16a6
 #define PCI_DEVICE_ID_TIGON3_5703X     0x16a7
 #define PCI_DEVICE_ID_TIGON3_5704S     0x16a8
+#define PCI_DEVICE_ID_NX2_5706S                0x16aa
 #define PCI_DEVICE_ID_TIGON3_5702A3    0x16c6
 #define PCI_DEVICE_ID_TIGON3_5703A3    0x16c7
 #define PCI_DEVICE_ID_TIGON3_5781      0x16dd
 #define PCI_DEVICE_ID_INTEL_82915G_IG  0x2582
 #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590
 #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592
+#define PCI_DEVICE_ID_INTEL_82945G_HB  0x2770
+#define PCI_DEVICE_ID_INTEL_82945G_IG  0x2772
 #define PCI_DEVICE_ID_INTEL_ICH6_0     0x2640
 #define PCI_DEVICE_ID_INTEL_ICH6_1     0x2641
 #define PCI_DEVICE_ID_INTEL_ICH6_2     0x2642
index 73d84c071cb1d17018a0b490e003f48d3b7e3d8a..1d9da36eb9db2f76488f1cdb86acf320809172f1 100644 (file)
@@ -427,6 +427,7 @@ enum
        TCA_NETEM_UNSPEC,
        TCA_NETEM_CORR,
        TCA_NETEM_DELAY_DIST,
+       TCA_NETEM_REORDER,
        __TCA_NETEM_MAX,
 };
 
@@ -437,7 +438,7 @@ struct tc_netem_qopt
        __u32   latency;        /* added delay (us) */
        __u32   limit;          /* fifo limit (packets) */
        __u32   loss;           /* random packet loss (0=none ~0=100%) */
-       __u32   gap;            /* re-ordering gap (0 for delay all) */
+       __u32   gap;            /* re-ordering gap (0 for none) */
        __u32   duplicate;      /* random packet dup  (0=none ~0=100%) */
        __u32   jitter;         /* random jitter in latency (us) */
 };
@@ -449,6 +450,12 @@ struct tc_netem_corr
        __u32   dup_corr;       /* duplicate correlation  */
 };
 
+struct tc_netem_reorder
+{
+       __u32   probability;
+       __u32   correlation;
+};
+
 #define NETEM_DIST_SCALE       8192
 
 #endif
index 5f868a5885811571fdc701037bf7b09b40a746b8..4dbb109022f3646ff39b7f64464bebb0200071fc 100644 (file)
@@ -578,7 +578,7 @@ struct task_struct {
        unsigned long flags;    /* per process flags, defined below */
        unsigned long ptrace;
 
-       int lock_depth;         /* Lock depth */
+       int lock_depth;         /* BKL lock depth */
 
        int prio, static_prio;
        struct list_head run_list;
@@ -661,7 +661,10 @@ struct task_struct {
        struct key *thread_keyring;     /* keyring private to this thread */
 #endif
        int oomkilladj; /* OOM kill score adjustment (bit shift). */
-       char comm[TASK_COMM_LEN];
+       char comm[TASK_COMM_LEN]; /* executable name excluding path
+                                    - access with [gs]et_task_comm (which lock
+                                      it with task_lock())
+                                    - initialized normally by flush_old_exec */
 /* file system info */
        int link_count, total_link_count;
 /* ipc stuff */
index c3fb5984f250a19e5f45ff23551fc7d148e9790e..d6025af7efac39154d65c90f447b54f79a43ac37 100644 (file)
@@ -479,6 +479,25 @@ uart_handle_cts_change(struct uart_port *port, unsigned int status)
        }
 }
 
+#include <linux/tty_flip.h>
+
+static inline void
+uart_insert_char(struct uart_port *port, unsigned int status,
+                unsigned int overrun, unsigned int ch, unsigned int flag)
+{
+       struct tty_struct *tty = port->info->tty;
+
+       if ((status & port->ignore_status_mask & ~overrun) == 0)
+               tty_insert_flip_char(tty, ch, flag);
+
+       /*
+        * Overrun is special.  Since it's reported immediately,
+        * it doesn't affect the current character.
+        */
+       if (status & ~port->ignore_status_mask & overrun)
+               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+}
+
 /*
  *     UART_ENABLE_MS - determine if port should enable modem status irqs
  */
index 0a98f5ec5caed28fdfcaa91c183e7ef181534833..7be18b5e2fb41a9ec1794028a0364324360a6828 100644 (file)
@@ -231,10 +231,8 @@ extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
 extern long do_sigpending(void __user *, unsigned long);
 extern int sigprocmask(int, sigset_t *, sigset_t *);
 
-#ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
 struct pt_regs;
 extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
-#endif
 
 #endif /* __KERNEL__ */
 
index 5eb33205cc04f63fe9df17f9676bb4b1ecc24cfb..e6b9d1d36ea262f7c9032b6308f19144fc948bcb 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)sockios.h   1.0.2   03/09/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  *             This program is free software; you can redistribute it and/or
index 28d2d18819780d62e89d1a98b3f9108663af1cc1..523d069c862c4fd9e95060bf5470a4fd664c4fd5 100644 (file)
 /* In Linux we need to be prepared for cross compiling */
 #include <linux/ioctl.h>
 
+/* Endian macros. */
+#ifdef __KERNEL__
+#  include <asm/byteorder.h>
+#else
+#  include <endian.h>
+#endif
+
 /*
  *     Supported card ID numbers (Should be somewhere else?)
  */
@@ -179,13 +186,26 @@ typedef struct seq_event_rec {
  * Some big endian/little endian handling macros
  */
 
-#if defined(_AIX) || defined(AIX) || defined(sparc) || defined(__sparc__) || defined(HPPA) || defined(PPC) || defined(__mc68000__)
-/* Big endian machines */
-#  define _PATCHKEY(id) (0xfd00|id)
-#  define AFMT_S16_NE AFMT_S16_BE
-#else
-#  define _PATCHKEY(id) ((id<<8)|0xfd)
-#  define AFMT_S16_NE AFMT_S16_LE
+#define _LINUX_PATCHKEY_H_INDIRECT
+#include <linux/patchkey.h>
+#undef _LINUX_PATCHKEY_H_INDIRECT
+
+#if defined(__KERNEL__)
+#  if defined(__BIG_ENDIAN)
+#    define AFMT_S16_NE AFMT_S16_BE
+#  elif defined(__LITTLE_ENDIAN)
+#    define AFMT_S16_NE AFMT_S16_LE
+#  else
+#    error "could not determine byte order"
+#  endif
+#elif defined(__BYTE_ORDER)
+#  if __BYTE_ORDER == __BIG_ENDIAN
+#    define AFMT_S16_NE AFMT_S16_BE
+#  elif __BYTE_ORDER == __LITTLE_ENDIAN
+#    define AFMT_S16_NE AFMT_S16_LE
+#  else
+#    error "could not determine byte order"
+#  endif
 #endif
 
 /*
index e895f3eaf53ab1196ee0473ba258586998ec2d4c..d6ba068719b61bf4a035e4d6e297694b65941442 100644 (file)
@@ -248,7 +248,7 @@ typedef struct {
 
 #define _spin_trylock_bh(lock) ({preempt_disable(); local_bh_disable(); \
                                _raw_spin_trylock(lock) ? \
-                               1 : ({preempt_enable(); local_bh_enable(); 0;});})
+                               1 : ({preempt_enable_no_resched(); local_bh_enable(); 0;});})
 
 #define _spin_lock(lock)       \
 do { \
@@ -383,7 +383,7 @@ do { \
 #define _spin_unlock_bh(lock) \
 do { \
        _raw_spin_unlock(lock); \
-       preempt_enable(); \
+       preempt_enable_no_resched(); \
        local_bh_enable(); \
        __release(lock); \
 } while (0)
@@ -391,7 +391,7 @@ do { \
 #define _write_unlock_bh(lock) \
 do { \
        _raw_write_unlock(lock); \
-       preempt_enable(); \
+       preempt_enable_no_resched(); \
        local_bh_enable(); \
        __release(lock); \
 } while (0)
@@ -423,8 +423,8 @@ do { \
 #define _read_unlock_bh(lock)  \
 do { \
        _raw_read_unlock(lock); \
+       preempt_enable_no_resched();    \
        local_bh_enable();      \
-       preempt_enable();       \
        __release(lock); \
 } while (0)
 
index 772998147e3ef989988c184520f6dacba9fb601d..a17745c80a91a6ce19fdeeb007aa1f529ce440df 100644 (file)
@@ -346,6 +346,7 @@ enum
        NET_TCP_MODERATE_RCVBUF=106,
        NET_TCP_TSO_WIN_DIVISOR=107,
        NET_TCP_BIC_BETA=108,
+       NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
 };
 
 enum {
@@ -399,6 +400,7 @@ enum
        NET_IPV4_CONF_FORCE_IGMP_VERSION=17,
        NET_IPV4_CONF_ARP_ANNOUNCE=18,
        NET_IPV4_CONF_ARP_IGNORE=19,
+       NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
        __NET_IPV4_CONF_MAX
 };
 
index aa6b48bb4dcd0c1fbeec59278d84eb3e15244da0..a6b2cc530af5e1be70ed02d2cf05240c2894c297 100644 (file)
@@ -56,6 +56,36 @@ enum
        TCF_META_ID_TCCLASSID,
        TCF_META_ID_RTCLASSID,
        TCF_META_ID_RTIIF,
+       TCF_META_ID_SK_FAMILY,
+       TCF_META_ID_SK_STATE,
+       TCF_META_ID_SK_REUSE,
+       TCF_META_ID_SK_BOUND_IF,
+       TCF_META_ID_SK_REFCNT,
+       TCF_META_ID_SK_SHUTDOWN,
+       TCF_META_ID_SK_PROTO,
+       TCF_META_ID_SK_TYPE,
+       TCF_META_ID_SK_RCVBUF,
+       TCF_META_ID_SK_RMEM_ALLOC,
+       TCF_META_ID_SK_WMEM_ALLOC,
+       TCF_META_ID_SK_OMEM_ALLOC,
+       TCF_META_ID_SK_WMEM_QUEUED,
+       TCF_META_ID_SK_RCV_QLEN,
+       TCF_META_ID_SK_SND_QLEN,
+       TCF_META_ID_SK_ERR_QLEN,
+       TCF_META_ID_SK_FORWARD_ALLOCS,
+       TCF_META_ID_SK_SNDBUF,
+       TCF_META_ID_SK_ALLOCS,
+       TCF_META_ID_SK_ROUTE_CAPS,
+       TCF_META_ID_SK_HASHENT,
+       TCF_META_ID_SK_LINGERTIME,
+       TCF_META_ID_SK_ACK_BACKLOG,
+       TCF_META_ID_SK_MAX_ACK_BACKLOG,
+       TCF_META_ID_SK_PRIO,
+       TCF_META_ID_SK_RCVLOWAT,
+       TCF_META_ID_SK_RCVTIMEO,
+       TCF_META_ID_SK_SNDTIMEO,
+       TCF_META_ID_SK_SENDMSG_OFF,
+       TCF_META_ID_SK_WRITE_PENDING,
        __TCF_META_ID_MAX
 };
 #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1)
index aaa1f337edcbc1d34fbbac2f25aa9cf7e9dd9717..99e02ef54c47db8fa1e9ceff2644acb9c2b98b38 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)eth.h       1.0.4   05/13/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  *             Relocated to include/linux where it belongs by Alan Cox 
index 41d1a644c9d43aa8206cf2b6e708c4a8173b7fd2..2d1ac5058534cdd8db3ecb86233ab31d247e2c44 100644 (file)
@@ -796,6 +796,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
  * of the iso_frame_desc array, and the number of errors is reported in
  * error_count.  Completion callbacks for ISO transfers will normally
  * (re)submit URBs to ensure a constant transfer rate.
+ *
+ * Note that even fields marked "public" should not be touched by the driver
+ * when the urb is owned by the hcd, that is, since the call to
+ * usb_submit_urb() till the entry into the completion routine.
  */
 struct urb
 {
@@ -803,12 +807,12 @@ struct urb
        struct kref kref;               /* reference count of the URB */
        spinlock_t lock;                /* lock for the URB */
        void *hcpriv;                   /* private data for host controller */
-       struct list_head urb_list;      /* list pointer to all active urbs */
        int bandwidth;                  /* bandwidth for INT/ISO request */
        atomic_t use_count;             /* concurrent submissions counter */
        u8 reject;                      /* submissions will fail */
 
        /* public, documented fields in the urb that can be used by drivers */
+       struct list_head urb_list;      /* list head for use by the urb owner */
        struct usb_device *dev;         /* (in) pointer to associated device */
        unsigned int pipe;              /* (in) pipe information */
        int status;                     /* (return) non-ISO status */
index 3a358c895188f6506e2eddf4fb1487bc2d3da4c5..6409d9cf59659d8377d140e205a4a6099e8b4277 100644 (file)
@@ -41,6 +41,7 @@ extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
 extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
                                        unsigned long start, unsigned long end);
 extern struct vm_struct *remove_vm_area(void *addr);
+extern struct vm_struct *__remove_vm_area(void *addr);
 extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
                        struct page ***pages);
 extern void unmap_vm_area(struct vm_struct *area);
index 17c874a8eb3f15b839898de9368297c189c8dc21..c9486c3efb4a1ac25bf79531cc369a00c487c474 100644 (file)
@@ -386,9 +386,7 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
        wait_queue_t name = {                                           \
                .task           = current,                              \
                .func           = autoremove_wake_function,             \
-               .task_list      = {     .next = &(name).task_list,      \
-                                       .prev = &(name).task_list,      \
-                               },                                      \
+               .task_list      = LIST_HEAD_INIT((name).task_list),     \
        }
 
 #define DEFINE_WAIT_BIT(name, word, bit)                               \
index 94bd33619aa5af542b747c7a0829917e824b42e0..ad0a07a3a89502e08c580029e96959576c81c821 100644 (file)
@@ -16,7 +16,7 @@ struct videobuf_dvb {
        int                        nfeeds;
 
        /* videobuf_dvb_(un)register manges this */
-       struct dvb_adapter         *adapter;
+       struct dvb_adapter         adapter;
        struct dvb_demux           demux;
        struct dmxdev              dmxdev;
        struct dmx_frontend        fe_hw;
index 95b120781c14696b40e9f9528e414289e9051ac5..c9daa7e52300da04d17defe8ec49ab79ea743166 100644 (file)
@@ -2,8 +2,8 @@
  * include/net/act_generic.h
  *
 */
-#ifndef ACT_GENERIC_H
-#define ACT_GENERIC_H
+#ifndef _NET_ACT_GENERIC_H
+#define _NET_ACT_GENERIC_H
 static inline int tcf_defact_release(struct tcf_defact *p, int bind)
 {
        int ret = 0;
index f1e5af4be98e4a9cde314a5c1ceeaf3a61cf87ad..a0ed9367217601cd1e1dbcb6266bf2e8d25f68cf 100644 (file)
@@ -17,6 +17,8 @@
 
 #define IPV6_MAX_ADDRESSES             16
 
+#include <linux/in6.h>
+
 struct prefix_info {
        __u8                    type;
        __u8                    length;
@@ -43,7 +45,6 @@ struct prefix_info {
 
 #ifdef __KERNEL__
 
-#include <linux/in6.h>
 #include <linux/netdevice.h>
 #include <net/if_inet6.h>
 #include <net/ipv6.h>
index 3fc192478aa2027d590f33ee40fa80e0a6505ff6..e5ef0d15fb45e8e7130c53ecdeb5c0f3279a7492 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)icmp.h      1.0.4   05/13/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  *             This program is free software; you can redistribute it and/or
index b4db1375da2c67da3b8e57de5f370a75ac1a543c..32360bbe143faebcefe80eb9ae7a43d19585680c 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)ip.h        1.0.2   05/07/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Alan Cox, <gw4pts@gw4pts.ampr.org>
  *
@@ -163,6 +163,7 @@ DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
 
 extern int sysctl_local_port_range[2];
 extern int sysctl_ip_default_ttl;
+extern int sysctl_ip_nonlocal_bind;
 
 #ifdef CONFIG_INET
 /* The function in 2.2 was invalid, producing wrong result for
index 22da7579d5de5cbd0a540444a56b6618be9fdc4c..d34ca8fc67569ccf2d4af632bb1a08862b359ba1 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)route.h     1.0.4   05/27/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  * Fixes:
  *             Alan Cox        :       Reformatted. Added ip_rt_local()
@@ -181,9 +181,6 @@ static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport,
                memcpy(&fl, &(*rp)->fl, sizeof(fl));
                fl.fl_ip_sport = sport;
                fl.fl_ip_dport = dport;
-#if defined(CONFIG_IP_ROUTE_MULTIPATH_CACHED)
-               fl.flags |= FLOWI_FLAG_MULTIPATHOLDROUTE;
-#endif
                ip_rt_put(*rp);
                *rp = NULL;
                return ip_route_output_flow(rp, &fl, sk, 0);
index cc4c9190b7fd861fb715953759a5b9068b03f7c3..a9ef3a6a13f3374a68b4c0817777531781227141 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)sock.h      1.0.4   05/13/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Corey Minyard <wf-rch!minyard@relay.EU.net>
  *             Florian La Roche <flla@stud.uni-sb.de>
@@ -141,6 +141,7 @@ struct sock_common {
   *    @sk_callback_lock: used with the callbacks in the end of this struct
   *    @sk_error_queue: rarely used
   *    @sk_prot: protocol handlers inside a network family
+  *    @sk_prot_creator: sk_prot of original sock creator (see ipv6_setsockopt, IPV6_ADDRFORM for instance)
   *    @sk_err: last error
   *    @sk_err_soft: errors that don't cause failure but are the cause of a persistent failure not just 'timed out'
   *    @sk_ack_backlog: current listen backlog
@@ -218,6 +219,7 @@ struct sock {
        } sk_backlog;
        struct sk_buff_head     sk_error_queue;
        struct proto            *sk_prot;
+       struct proto            *sk_prot_creator;
        rwlock_t                sk_callback_lock;
        int                     sk_err,
                                sk_err_soft;
index 9355ae5b1d75b1720d4957725d42a22774679a67..e71f8ba3e101e580bd41c163a76ad20e6109fb1a 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)tcp.h       1.0.5   05/23/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  *             This program is free software; you can redistribute it and/or
index c496d10101dbda3f8ecda8762267730665e68054..ac229b761dbc488b24fb031b1acf51192c6bb927 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)udp.h       1.0.2   05/07/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  * Fixes:
index e142a256d5dc394a8d52e50a3a4bd78b0a2b5c48..d675836ba6c35faf99cee4564a0ab4d7f9e1928f 100644 (file)
@@ -515,6 +515,8 @@ struct xfrm_dst
        struct dst_entry *route;
        u32 route_mtu_cached;
        u32 child_mtu_cached;
+       u32 route_cookie;
+       u32 path_cookie;
 };
 
 static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
index 6dcf497bf46dc485e4b61800ff7d4429b3506919..a30d6cd4c0e8d805c49a18a2a68f34a8f37fe8ba 100644 (file)
@@ -27,8 +27,11 @@ struct scsi_transport_template;
 
 struct spi_transport_attrs {
        int period;             /* value in the PPR/SDTR command */
+       int min_period;
        int offset;
+       int max_offset;
        unsigned int width:1;   /* 0 - narrow, 1 - wide */
+       unsigned int max_width:1;
        unsigned int iu:1;      /* Information Units enabled */
        unsigned int dt:1;      /* DT clocking enabled */
        unsigned int qas:1;     /* Quick Arbitration and Selection enabled */
@@ -63,8 +66,11 @@ struct spi_host_attrs {
 
 /* accessor functions */
 #define spi_period(x)  (((struct spi_transport_attrs *)&(x)->starget_data)->period)
+#define spi_min_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->min_period)
 #define spi_offset(x)  (((struct spi_transport_attrs *)&(x)->starget_data)->offset)
+#define spi_max_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_offset)
 #define spi_width(x)   (((struct spi_transport_attrs *)&(x)->starget_data)->width)
+#define spi_max_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_width)
 #define spi_iu(x)      (((struct spi_transport_attrs *)&(x)->starget_data)->iu)
 #define spi_dt(x)      (((struct spi_transport_attrs *)&(x)->starget_data)->dt)
 #define spi_qas(x)     (((struct spi_transport_attrs *)&(x)->starget_data)->qas)
index 40d286d1d118f5c5d65498ad911a84a9d047cdb1..a7660ccc693f8976c8a5a090d3d82f817e9c339d 100644 (file)
@@ -173,7 +173,7 @@ config AUDIT
 
 config AUDITSYSCALL
        bool "Enable system-call auditing support"
-       depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64)
+       depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64 || UML)
        default y if SECURITY_SELINUX
        help
          Enable low-overhead system-call auditing infrastructure that
@@ -442,7 +442,7 @@ config OBSOLETE_MODPARM
 
 config MODVERSIONS
        bool "Module versioning support (EXPERIMENTAL)"
-       depends on MODULES && EXPERIMENTAL && !UML
+       depends on MODULES && EXPERIMENTAL
        help
          Usually, you have to use modules compiled with your kernel.
          Saying Y here makes it sometimes possible to use modules
index eb88b446c2ccade2c1983db855c1bd16034debcf..b01d26fe8db71abdd0397bcb25eb4e47d3f8c45e 100644 (file)
@@ -29,7 +29,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_SECCOMP) += seccomp.o
 
-ifneq ($(CONFIG_IA64),y)
+ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
 # needed for x86 only.  Why this used to be enabled for all architectures is beyond
 # me.  I suspect most platforms don't need this, but until we know that for sure
index ac26d4d960d3366d0473ede3533ab89446b75dc3..9c4f1af0c794674404810d7caff0131218cbc950 100644 (file)
@@ -1,4 +1,4 @@
-/* audit.c -- Auditing support -*- linux-c -*-
+/* audit.c -- Auditing support
  * Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
  * System-call specific features have moved to auditsc.c
  *
@@ -38,7 +38,7 @@
  *       6) Support low-overhead kernel-based filtering to minimize the
  *          information that must be passed to user-space.
  *
- * Example user-space utilities: http://people.redhat.com/faith/audit/
+ * Example user-space utilities: http://people.redhat.com/sgrubb/audit/
  */
 
 #include <linux/init.h>
@@ -142,7 +142,6 @@ struct audit_buffer {
        int                  total;
        int                  type;
        int                  pid;
-       int                  count; /* Times requeued */
 };
 
 void audit_set_type(struct audit_buffer *ab, int type)
@@ -239,36 +238,36 @@ void audit_log_lost(const char *message)
 
 }
 
-static int audit_set_rate_limit(int limit)
+static int audit_set_rate_limit(int limit, uid_t loginuid)
 {
        int old          = audit_rate_limit;
        audit_rate_limit = limit;
-       audit_log(current->audit_context, "audit_rate_limit=%d old=%d",
-                 audit_rate_limit, old);
+       audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
+                       audit_rate_limit, old, loginuid);
        return old;
 }
 
-static int audit_set_backlog_limit(int limit)
+static int audit_set_backlog_limit(int limit, uid_t loginuid)
 {
        int old          = audit_backlog_limit;
        audit_backlog_limit = limit;
-       audit_log(current->audit_context, "audit_backlog_limit=%d old=%d",
-                 audit_backlog_limit, old);
+       audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
+                       audit_backlog_limit, old, loginuid);
        return old;
 }
 
-static int audit_set_enabled(int state)
+static int audit_set_enabled(int state, uid_t loginuid)
 {
        int old          = audit_enabled;
        if (state != 0 && state != 1)
                return -EINVAL;
        audit_enabled = state;
-       audit_log(current->audit_context, "audit_enabled=%d old=%d",
-                 audit_enabled, old);
+       audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
+                 audit_enabled, old, loginuid);
        return old;
 }
 
-static int audit_set_failure(int state)
+static int audit_set_failure(int state, uid_t loginuid)
 {
        int old          = audit_failure;
        if (state != AUDIT_FAIL_SILENT
@@ -276,8 +275,8 @@ static int audit_set_failure(int state)
            && state != AUDIT_FAIL_PANIC)
                return -EINVAL;
        audit_failure = state;
-       audit_log(current->audit_context, "audit_failure=%d old=%d",
-                 audit_failure, old);
+       audit_log(NULL, "audit_failure=%d old=%d by auid %u",
+                 audit_failure, old, loginuid);
        return old;
 }
 
@@ -344,6 +343,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        int                     err;
        struct audit_buffer     *ab;
        u16                     msg_type = nlh->nlmsg_type;
+       uid_t                   loginuid; /* loginuid of sender */
 
        err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
        if (err)
@@ -351,6 +351,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 
        pid  = NETLINK_CREDS(skb)->pid;
        uid  = NETLINK_CREDS(skb)->uid;
+       loginuid = NETLINK_CB(skb).loginuid;
        seq  = nlh->nlmsg_seq;
        data = NLMSG_DATA(nlh);
 
@@ -371,34 +372,36 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                        return -EINVAL;
                status_get   = (struct audit_status *)data;
                if (status_get->mask & AUDIT_STATUS_ENABLED) {
-                       err = audit_set_enabled(status_get->enabled);
+                       err = audit_set_enabled(status_get->enabled, loginuid);
                        if (err < 0) return err;
                }
                if (status_get->mask & AUDIT_STATUS_FAILURE) {
-                       err = audit_set_failure(status_get->failure);
+                       err = audit_set_failure(status_get->failure, loginuid);
                        if (err < 0) return err;
                }
                if (status_get->mask & AUDIT_STATUS_PID) {
                        int old   = audit_pid;
                        audit_pid = status_get->pid;
-                       audit_log(current->audit_context,
-                                 "audit_pid=%d old=%d", audit_pid, old);
+                       audit_log(NULL, "audit_pid=%d old=%d by auid %u",
+                                 audit_pid, old, loginuid);
                }
                if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
-                       audit_set_rate_limit(status_get->rate_limit);
+                       audit_set_rate_limit(status_get->rate_limit, loginuid);
                if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
-                       audit_set_backlog_limit(status_get->backlog_limit);
+                       audit_set_backlog_limit(status_get->backlog_limit,
+                                                       loginuid);
                break;
        case AUDIT_USER:
                ab = audit_log_start(NULL);
                if (!ab)
                        break;  /* audit_panic has been called */
                audit_log_format(ab,
-                                "user pid=%d uid=%d length=%d msg='%.1024s'",
+                                "user pid=%d uid=%d length=%d loginuid=%u"
+                                " msg='%.1024s'",
                                 pid, uid,
                                 (int)(nlh->nlmsg_len
                                       - ((char *)data - (char *)nlh)),
-                                (char *)data);
+                                loginuid, (char *)data);
                ab->type = AUDIT_USER;
                ab->pid  = pid;
                audit_log_end(ab);
@@ -411,7 +414,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        case AUDIT_LIST:
 #ifdef CONFIG_AUDITSYSCALL
                err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
-                                          uid, seq, data);
+                                          uid, seq, data, loginuid);
 #else
                err = -EOPNOTSUPP;
 #endif
@@ -480,7 +483,7 @@ static void audit_log_move(struct audit_buffer *ab)
        if (ab->len == 0)
                return;
 
-       skb = skb_peek(&ab->sklist);
+       skb = skb_peek_tail(&ab->sklist);
        if (!skb || skb_tailroom(skb) <= ab->len + extra) {
                skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
                if (!skb) {
@@ -519,9 +522,9 @@ static inline int audit_log_drain(struct audit_buffer *ab)
                        retval = netlink_unicast(audit_sock, skb, audit_pid,
                                                 MSG_DONTWAIT);
                }
-               if (retval == -EAGAIN && ab->count < 5) {
-                       ++ab->count;
-                       skb_queue_tail(&ab->sklist, skb);
+               if (retval == -EAGAIN &&
+                   (atomic_read(&audit_backlog)) < audit_backlog_limit) {
+                       skb_queue_head(&ab->sklist, skb);
                        audit_log_end_irq(ab);
                        return 1;
                }
@@ -537,8 +540,8 @@ static inline int audit_log_drain(struct audit_buffer *ab)
                if (!audit_pid) { /* No daemon */
                        int offset = ab->nlh ? NLMSG_SPACE(0) : 0;
                        int len    = skb->len - offset;
-                       printk(KERN_ERR "%*.*s\n",
-                              len, len, skb->data + offset);
+                       skb->data[offset + len] = '\0';
+                       printk(KERN_ERR "%s\n", skb->data + offset);
                }
                kfree_skb(skb);
                ab->nlh = NULL;
@@ -617,7 +620,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
        struct audit_buffer     *ab     = NULL;
        unsigned long           flags;
        struct timespec         t;
-       int                     serial  = 0;
+       unsigned int            serial;
 
        if (!audit_initialized)
                return NULL;
@@ -659,15 +662,16 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
        ab->total = 0;
        ab->type  = AUDIT_KERNEL;
        ab->pid   = 0;
-       ab->count = 0;
 
 #ifdef CONFIG_AUDITSYSCALL
        if (ab->ctx)
                audit_get_stamp(ab->ctx, &t, &serial);
        else
 #endif
+       {
                t = CURRENT_TIME;
-
+               serial = 0;
+       }
        audit_log_format(ab, "audit(%lu.%03lu:%u): ",
                         t.tv_sec, t.tv_nsec/1000000, serial);
        return ab;
@@ -717,6 +721,29 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
        va_end(args);
 }
 
+void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len)
+{
+       int i;
+
+       for (i=0; i<len; i++)
+               audit_log_format(ab, "%02x", buf[i]);
+}
+
+void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
+{
+       const unsigned char *p = string;
+
+       while (*p) {
+               if (*p == '"' || *p == ' ' || *p < 0x20 || *p > 0x7f) {
+                       audit_log_hex(ab, string, strlen(string));
+                       return;
+               }
+               p++;
+       }
+       audit_log_format(ab, "\"%s\"", string);
+}
+
+
 /* This is a helper-function to print the d_path without using a static
  * buffer or allocating another buffer in addition to the one in
  * audit_buffer. */
index 6f1931381bc9eae1ff454c943036c5b077c4a8a6..37b3ac94bc47492d026ae697cc92b1d4ddd70bd5 100644 (file)
@@ -1,4 +1,4 @@
-/* auditsc.c -- System-call auditing support -*- linux-c -*-
+/* auditsc.c -- System-call auditing support
  * Handles all system-call specific auditing features.
  *
  * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
@@ -123,7 +123,7 @@ struct audit_context {
        int                 major;      /* syscall number */
        unsigned long       argv[4];    /* syscall arguments */
        int                 return_valid; /* return code is valid */
-       int                 return_code;/* syscall return code */
+       long                return_code;/* syscall return code */
        int                 auditable;  /* 1 if record should be written */
        int                 name_count;
        struct audit_names  names[AUDIT_NAMES];
@@ -135,6 +135,7 @@ struct audit_context {
        uid_t               uid, euid, suid, fsuid;
        gid_t               gid, egid, sgid, fsgid;
        unsigned long       personality;
+       int                 arch;
 
 #if AUDIT_DEBUG
        int                 put_count;
@@ -250,7 +251,8 @@ static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
        return 0;
 }
 
-int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
+int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
+                                                       uid_t loginuid)
 {
        u32                flags;
        struct audit_entry *entry;
@@ -285,6 +287,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
                        err = audit_add_rule(entry, &audit_entlist);
                if (!err && (flags & AUDIT_AT_EXIT))
                        err = audit_add_rule(entry, &audit_extlist);
+               audit_log(NULL, "auid %u added an audit rule\n", loginuid);
                break;
        case AUDIT_DEL:
                flags =((struct audit_rule *)data)->flags;
@@ -294,6 +297,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
                        err = audit_del_rule(data, &audit_entlist);
                if (!err && (flags & AUDIT_AT_EXIT))
                        err = audit_del_rule(data, &audit_extlist);
+               audit_log(NULL, "auid %u removed an audit rule\n", loginuid);
                break;
        default:
                return -EINVAL;
@@ -348,6 +352,10 @@ static int audit_filter_rules(struct task_struct *tsk,
                case AUDIT_PERS:
                        result = (tsk->personality == value);
                        break;
+               case AUDIT_ARCH:
+                       if (ctx) 
+                               result = (ctx->arch == value);
+                       break;
 
                case AUDIT_EXIT:
                        if (ctx && ctx->return_valid)
@@ -355,7 +363,7 @@ static int audit_filter_rules(struct task_struct *tsk,
                        break;
                case AUDIT_SUCCESS:
                        if (ctx && ctx->return_valid)
-                               result = (ctx->return_code >= 0);
+                               result = (ctx->return_valid == AUDITSC_SUCCESS);
                        break;
                case AUDIT_DEVMAJOR:
                        if (ctx) {
@@ -648,8 +656,11 @@ static void audit_log_exit(struct audit_context *context)
        audit_log_format(ab, "syscall=%d", context->major);
        if (context->personality != PER_LINUX)
                audit_log_format(ab, " per=%lx", context->personality);
+       audit_log_format(ab, " arch=%x", context->arch);
        if (context->return_valid)
-               audit_log_format(ab, " exit=%d", context->return_code);
+               audit_log_format(ab, " success=%s exit=%ld", 
+                                (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
+                                context->return_code);
        audit_log_format(ab,
                  " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
                  " pid=%d loginuid=%d uid=%d gid=%d"
@@ -696,9 +707,10 @@ static void audit_log_exit(struct audit_context *context)
                if (!ab)
                        continue; /* audit_panic has been called */
                audit_log_format(ab, "item=%d", i);
-               if (context->names[i].name)
-                       audit_log_format(ab, " name=%s",
-                                        context->names[i].name);
+               if (context->names[i].name) {
+                       audit_log_format(ab, " name=");
+                       audit_log_untrustedstring(ab, context->names[i].name);
+               }
                if (context->names[i].ino != (unsigned long)-1)
                        audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
                                             " uid=%d gid=%d rdev=%02x:%02x",
@@ -772,7 +784,7 @@ static inline unsigned int audit_serial(void)
  * then the record will be written at syscall exit time (otherwise, it
  * will only be written if another part of the kernel requests that it
  * be written). */
-void audit_syscall_entry(struct task_struct *tsk, int major,
+void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
                         unsigned long a1, unsigned long a2,
                         unsigned long a3, unsigned long a4)
 {
@@ -826,6 +838,7 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
        if (!audit_enabled)
                return;
 
+       context->arch       = arch;
        context->major      = major;
        context->argv[0]    = a1;
        context->argv[1]    = a2;
@@ -849,13 +862,13 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
  * filtering, or because some other part of the kernel write an audit
  * message), then write out the syscall information.  In call cases,
  * free the names stored from getname(). */
-void audit_syscall_exit(struct task_struct *tsk, int return_code)
+void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
 {
        struct audit_context *context;
 
        get_task_struct(tsk);
        task_lock(tsk);
-       context = audit_get_context(tsk, 1, return_code);
+       context = audit_get_context(tsk, valid, return_code);
        task_unlock(tsk);
 
        /* Not having a context here is ok, since the parent may have
@@ -868,6 +881,7 @@ void audit_syscall_exit(struct task_struct *tsk, int return_code)
 
        context->in_syscall = 0;
        context->auditable  = 0;
+
        if (context->previous) {
                struct audit_context *new_context = context->previous;
                context->previous  = NULL;
@@ -981,7 +995,7 @@ void audit_inode(const char *name, const struct inode *inode)
 }
 
 void audit_get_stamp(struct audit_context *ctx,
-                    struct timespec *t, int *serial)
+                    struct timespec *t, unsigned int *serial)
 {
        if (ctx) {
                t->tv_sec  = ctx->ctime.tv_sec;
@@ -996,20 +1010,21 @@ void audit_get_stamp(struct audit_context *ctx,
 
 extern int audit_set_type(struct audit_buffer *ab, int type);
 
-int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid)
+int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
 {
-       if (ctx) {
+       if (task->audit_context) {
                struct audit_buffer *ab;
 
                ab = audit_log_start(NULL);
                if (ab) {
                        audit_log_format(ab, "login pid=%d uid=%u "
                                "old loginuid=%u new loginuid=%u",
-                               ctx->pid, ctx->uid, ctx->loginuid, loginuid);
+                               task->pid, task->uid, 
+                               task->audit_context->loginuid, loginuid);
                        audit_set_type(ab, AUDIT_LOGIN);
                        audit_log_end(ab);
                }
-               ctx->loginuid = loginuid;
+               task->audit_context->loginuid = loginuid;
        }
        return 0;
 }
index 961d74044deb0b08f8ce237e4f86c700da5e768a..00e8f2575512c6159c9a2ad76718f96f308042f5 100644 (file)
@@ -166,9 +166,8 @@ static struct super_block *cpuset_sb = NULL;
  * The hooks from fork and exit, cpuset_fork() and cpuset_exit(), don't
  * (usually) grab cpuset_sem.  These are the two most performance
  * critical pieces of code here.  The exception occurs on exit(),
- * if the last task using a cpuset exits, and the cpuset was marked
- * notify_on_release.  In that case, the cpuset_sem is taken, the
- * path to the released cpuset calculated, and a usermode call made
+ * when a task in a notify_on_release cpuset exits.  Then cpuset_sem
+ * is taken, and if the cpuset count is zero, a usermode call made
  * to /sbin/cpuset_release_agent with the name of the cpuset (path
  * relative to the root of cpuset file system) as the argument.
  *
@@ -1404,6 +1403,18 @@ void cpuset_fork(struct task_struct *tsk)
  *
  * Description: Detach cpuset from @tsk and release it.
  *
+ * Note that cpusets marked notify_on_release force every task
+ * in them to take the global cpuset_sem semaphore when exiting.
+ * This could impact scaling on very large systems.  Be reluctant
+ * to use notify_on_release cpusets where very high task exit
+ * scaling is required on large systems.
+ *
+ * Don't even think about derefencing 'cs' after the cpuset use
+ * count goes to zero, except inside a critical section guarded
+ * by the cpuset_sem semaphore.  If you don't hold cpuset_sem,
+ * then a zero cpuset use count is a license to any other task to
+ * nuke the cpuset immediately.
+ *
  **/
 
 void cpuset_exit(struct task_struct *tsk)
@@ -1415,10 +1426,13 @@ void cpuset_exit(struct task_struct *tsk)
        tsk->cpuset = NULL;
        task_unlock(tsk);
 
-       if (atomic_dec_and_test(&cs->count)) {
+       if (notify_on_release(cs)) {
                down(&cpuset_sem);
-               check_for_release(cs);
+               if (atomic_dec_and_test(&cs->count))
+                       check_for_release(cs);
                up(&cpuset_sem);
+       } else {
+               atomic_dec(&cs->count);
        }
 }
 
index 7be283d98983d8cebc6f7853ab3ef233185e7532..edaa50b5bbfaecc36f1e492e28d9b80ef55b5dae 100644 (file)
@@ -846,6 +846,8 @@ fastcall NORET_TYPE void do_exit(long code)
        for (;;) ;
 }
 
+EXPORT_SYMBOL_GPL(do_exit);
+
 NORET_TYPE void complete_and_exit(struct completion *comp, long code)
 {
        if (comp)
index 2fb0e46e11f390679550ebbb41852973c413b221..436c7d93c00a9555f245da72ce9efced1bffd47b 100644 (file)
@@ -30,6 +30,7 @@
  */
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
        [0 ... NR_IRQS-1] = {
+               .status = IRQ_DISABLED,
                .handler = &no_irq_type,
                .lock = SPIN_LOCK_UNLOCKED
        }
@@ -118,8 +119,6 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
                 */
                desc->handler->ack(irq);
                action_ret = handle_IRQ_event(irq, regs, desc->action);
-               if (!noirqdebug)
-                       note_interrupt(irq, desc, action_ret);
                desc->handler->end(irq);
                return 1;
        }
index e9a40e947e079615650c2491eddf7d7b35fdea9f..1dc988e0d2c77e962063c776b7b035800f51b9be 100644 (file)
@@ -123,7 +123,11 @@ static inline void it_real_arm(struct task_struct *p, unsigned long interval)
                return;
        if (interval > (unsigned long) LONG_MAX)
                interval = LONG_MAX;
-       p->signal->real_timer.expires = jiffies + interval;
+       /* the "+ 1" below makes sure that the timer doesn't go off before
+        * the interval requested. This could happen if
+        * time requested % (usecs per jiffy) is more than the usecs left
+        * in the current jiffy */
+       p->signal->real_timer.expires = jiffies + interval + 1;
        add_timer(&p->signal->real_timer);
 }
 
index 1627f8d6e0cdd5f918c30666f4434407df25c293..13bcec151b57f8ebc68f1665a688f200f8c63d89 100644 (file)
@@ -46,6 +46,14 @@ static inline int is_kernel_inittext(unsigned long addr)
        return 0;
 }
 
+static inline int is_kernel_extratext(unsigned long addr)
+{
+       if (addr >= (unsigned long)_sextratext
+           && addr <= (unsigned long)_eextratext)
+               return 1;
+       return 0;
+}
+
 static inline int is_kernel_text(unsigned long addr)
 {
        if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext)
@@ -169,8 +177,9 @@ const char *kallsyms_lookup(unsigned long addr,
        namebuf[0] = 0;
 
        if ((all_var && is_kernel(addr)) ||
-           (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr)))) {
-               unsigned long symbol_end=0;
+           (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) ||
+                               is_kernel_extratext(addr)))) {
+               unsigned long symbol_end = 0;
 
                /* do a binary search on the sorted kallsyms_addresses array */
                low = 0;
index 1d5dd1337bd1cd4a089b13d1e67c749fe822234f..037142b72a49eccdb8ef7d64205aaf1e4f31af1f 100644 (file)
@@ -44,6 +44,7 @@ static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 
 unsigned int kprobe_cpu = NR_CPUS;
 static DEFINE_SPINLOCK(kprobe_lock);
+static struct kprobe *curr_kprobe;
 
 /* Locks kprobe: irqs must be disabled */
 void lock_kprobes(void)
@@ -73,22 +74,139 @@ struct kprobe *get_kprobe(void *addr)
        return NULL;
 }
 
+/*
+ * Aggregate handlers for multiple kprobes support - these handlers
+ * take care of invoking the individual kprobe handlers on p->list
+ */
+int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+       struct kprobe *kp;
+
+       list_for_each_entry(kp, &p->list, list) {
+               if (kp->pre_handler) {
+                       curr_kprobe = kp;
+                       kp->pre_handler(kp, regs);
+                       curr_kprobe = NULL;
+               }
+       }
+       return 0;
+}
+
+void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
+               unsigned long flags)
+{
+       struct kprobe *kp;
+
+       list_for_each_entry(kp, &p->list, list) {
+               if (kp->post_handler) {
+                       curr_kprobe = kp;
+                       kp->post_handler(kp, regs, flags);
+                       curr_kprobe = NULL;
+               }
+       }
+       return;
+}
+
+int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr)
+{
+       /*
+        * if we faulted "during" the execution of a user specified
+        * probe handler, invoke just that probe's fault handler
+        */
+       if (curr_kprobe && curr_kprobe->fault_handler) {
+               if (curr_kprobe->fault_handler(curr_kprobe, regs, trapnr))
+                       return 1;
+       }
+       return 0;
+}
+
+/*
+ * Fill in the required fields of the "manager kprobe". Replace the
+ * earlier kprobe in the hlist with the manager kprobe
+ */
+static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
+{
+       ap->addr = p->addr;
+       ap->opcode = p->opcode;
+       memcpy(&ap->ainsn, &p->ainsn, sizeof(struct arch_specific_insn));
+
+       ap->pre_handler = aggr_pre_handler;
+       ap->post_handler = aggr_post_handler;
+       ap->fault_handler = aggr_fault_handler;
+
+       INIT_LIST_HEAD(&ap->list);
+       list_add(&p->list, &ap->list);
+
+       INIT_HLIST_NODE(&ap->hlist);
+       hlist_del(&p->hlist);
+       hlist_add_head(&ap->hlist,
+               &kprobe_table[hash_ptr(ap->addr, KPROBE_HASH_BITS)]);
+}
+
+/*
+ * This is the second or subsequent kprobe at the address - handle
+ * the intricacies
+ * TODO: Move kcalloc outside the spinlock
+ */
+static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p)
+{
+       int ret = 0;
+       struct kprobe *ap;
+
+       if (old_p->break_handler || p->break_handler) {
+               ret = -EEXIST;  /* kprobe and jprobe can't (yet) coexist */
+       } else if (old_p->pre_handler == aggr_pre_handler) {
+               list_add(&p->list, &old_p->list);
+       } else {
+               ap = kcalloc(1, sizeof(struct kprobe), GFP_ATOMIC);
+               if (!ap)
+                       return -ENOMEM;
+               add_aggr_kprobe(ap, old_p);
+               list_add(&p->list, &ap->list);
+       }
+       return ret;
+}
+
+/* kprobe removal house-keeping routines */
+static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
+{
+       *p->addr = p->opcode;
+       hlist_del(&p->hlist);
+       flush_icache_range((unsigned long) p->addr,
+                  (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+       spin_unlock_irqrestore(&kprobe_lock, flags);
+       arch_remove_kprobe(p);
+}
+
+static inline void cleanup_aggr_kprobe(struct kprobe *old_p,
+               struct kprobe *p, unsigned long flags)
+{
+       list_del(&p->list);
+       if (list_empty(&old_p->list)) {
+               cleanup_kprobe(old_p, flags);
+               kfree(old_p);
+       } else
+               spin_unlock_irqrestore(&kprobe_lock, flags);
+}
+
 int register_kprobe(struct kprobe *p)
 {
        int ret = 0;
        unsigned long flags = 0;
+       struct kprobe *old_p;
 
        if ((ret = arch_prepare_kprobe(p)) != 0) {
                goto rm_kprobe;
        }
        spin_lock_irqsave(&kprobe_lock, flags);
-       INIT_HLIST_NODE(&p->hlist);
-       if (get_kprobe(p->addr)) {
-               ret = -EEXIST;
+       old_p = get_kprobe(p->addr);
+       if (old_p) {
+               ret = register_aggr_kprobe(old_p, p);
                goto out;
        }
-       arch_copy_kprobe(p);
 
+       arch_copy_kprobe(p);
+       INIT_HLIST_NODE(&p->hlist);
        hlist_add_head(&p->hlist,
                       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
 
@@ -107,13 +225,17 @@ rm_kprobe:
 void unregister_kprobe(struct kprobe *p)
 {
        unsigned long flags;
-       arch_remove_kprobe(p);
+       struct kprobe *old_p;
+
        spin_lock_irqsave(&kprobe_lock, flags);
-       *p->addr = p->opcode;
-       hlist_del(&p->hlist);
-       flush_icache_range((unsigned long) p->addr,
-                          (unsigned long) p->addr + sizeof(kprobe_opcode_t));
-       spin_unlock_irqrestore(&kprobe_lock, flags);
+       old_p = get_kprobe(p->addr);
+       if (old_p) {
+               if (old_p->pre_handler == aggr_pre_handler)
+                       cleanup_aggr_kprobe(old_p, p, flags);
+               else
+                       cleanup_kprobe(p, flags);
+       } else
+               spin_unlock_irqrestore(&kprobe_lock, flags);
 }
 
 static struct notifier_block kprobe_exceptions_nb = {
index 5734ab09d3f984af2e424a5b3da5fbf79f83aef2..83b3d376708c04f00fdf674622b1c1071045eada 100644 (file)
@@ -1758,6 +1758,7 @@ sys_init_module(void __user *umod,
                const char __user *uargs)
 {
        struct module *mod;
+       mm_segment_t old_fs = get_fs();
        int ret = 0;
 
        /* Must have permission */
@@ -1775,6 +1776,9 @@ sys_init_module(void __user *umod,
                return PTR_ERR(mod);
        }
 
+       /* flush the icache in correct context */
+       set_fs(KERNEL_DS);
+
        /* Flush the instruction cache, since we've played with text */
        if (mod->module_init)
                flush_icache_range((unsigned long)mod->module_init,
@@ -1783,6 +1787,8 @@ sys_init_module(void __user *umod,
        flush_icache_range((unsigned long)mod->module_core,
                           (unsigned long)mod->module_core + mod->core_size);
 
+       set_fs(old_fs);
+
        /* Now sew it into the lists.  They won't access us, since
            strong_try_module_get() will fail. */
        stop_machine_run(__link_module, mod, NR_CPUS);
index 7960ddf04a57fca65ce7562ed565a1e1f5f872cd..4cdebc972ff2a55c7fdac702dca0c36f81905558 100644 (file)
@@ -156,14 +156,14 @@ static int enter_state(suspend_state_t state)
                goto Unlock;
        }
 
-       pr_debug("PM: Preparing system for suspend\n");
+       pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
        if ((error = suspend_prepare(state)))
                goto Unlock;
 
-       pr_debug("PM: Entering state.\n");
+       pr_debug("PM: Entering %s sleep\n", pm_states[state]);
        error = suspend_enter(state);
 
-       pr_debug("PM: Finishing up.\n");
+       pr_debug("PM: Finishing wakeup.\n");
        suspend_finish(state);
  Unlock:
        up(&pm_sem);
index 290a07ce2c8a8029089d24304ea216bf8b937ade..01b58d7d17ff763d50f92cb80b66e8ffe67dad4f 100644 (file)
@@ -160,42 +160,6 @@ static int __init console_setup(char *str)
 
 __setup("console=", console_setup);
 
-/**
- * add_preferred_console - add a device to the list of preferred consoles.
- *
- * The last preferred console added will be used for kernel messages
- * and stdin/out/err for init.  Normally this is used by console_setup
- * above to handle user-supplied console arguments; however it can also
- * be used by arch-specific code either to override the user or more
- * commonly to provide a default console (ie from PROM variables) when
- * the user has not supplied one.
- */
-int __init add_preferred_console(char *name, int idx, char *options)
-{
-       struct console_cmdline *c;
-       int i;
-
-       /*
-        *      See if this tty is not yet registered, and
-        *      if we have a slot free.
-        */
-       for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
-               if (strcmp(console_cmdline[i].name, name) == 0 &&
-                         console_cmdline[i].index == idx) {
-                               selected_console = i;
-                               return 0;
-               }
-       if (i == MAX_CMDLINECONSOLES)
-               return -E2BIG;
-       selected_console = i;
-       c = &console_cmdline[i];
-       memcpy(c->name, name, sizeof(c->name));
-       c->name[sizeof(c->name) - 1] = 0;
-       c->options = options;
-       c->index = idx;
-       return 0;
-}
-
 static int __init log_buf_len_setup(char *str)
 {
        unsigned long size = memparse(str, &str);
@@ -670,6 +634,42 @@ static void call_console_drivers(unsigned long start, unsigned long end) {}
 
 #endif
 
+/**
+ * add_preferred_console - add a device to the list of preferred consoles.
+ *
+ * The last preferred console added will be used for kernel messages
+ * and stdin/out/err for init.  Normally this is used by console_setup
+ * above to handle user-supplied console arguments; however it can also
+ * be used by arch-specific code either to override the user or more
+ * commonly to provide a default console (ie from PROM variables) when
+ * the user has not supplied one.
+ */
+int __init add_preferred_console(char *name, int idx, char *options)
+{
+       struct console_cmdline *c;
+       int i;
+
+       /*
+        *      See if this tty is not yet registered, and
+        *      if we have a slot free.
+        */
+       for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
+               if (strcmp(console_cmdline[i].name, name) == 0 &&
+                         console_cmdline[i].index == idx) {
+                               selected_console = i;
+                               return 0;
+               }
+       if (i == MAX_CMDLINECONSOLES)
+               return -E2BIG;
+       selected_console = i;
+       c = &console_cmdline[i];
+       memcpy(c->name, name, sizeof(c->name));
+       c->name[sizeof(c->name) - 1] = 0;
+       c->options = options;
+       c->index = idx;
+       return 0;
+}
+
 /**
  * acquire_console_sem - lock the console system for exclusive use.
  *
index 0221a50ca867c50feda6b0f1317fd2637d41d8a6..ad8cbb75ffa2c4921031a161b497df10fcf0a22f 100644 (file)
@@ -49,15 +49,19 @@ static DECLARE_MUTEX(profile_flip_mutex);
 
 static int __init profile_setup(char * str)
 {
+       static char __initdata schedstr[] = "schedule";
        int par;
 
-       if (!strncmp(str, "schedule", 8)) {
+       if (!strncmp(str, schedstr, strlen(schedstr))) {
                prof_on = SCHED_PROFILING;
-               printk(KERN_INFO "kernel schedule profiling enabled\n");
-               if (str[7] == ',')
-                       str += 8;
-       }
-       if (get_option(&str,&par)) {
+               if (str[strlen(schedstr)] == ',')
+                       str += strlen(schedstr) + 1;
+               if (get_option(&str, &par))
+                       prof_shift = par;
+               printk(KERN_INFO
+                       "kernel schedule profiling enabled (shift: %ld)\n",
+                       prof_shift);
+       } else if (get_option(&str, &par)) {
                prof_shift = par;
                prof_on = CPU_PROFILING;
                printk(KERN_INFO "kernel profiling enabled (shift: %ld)\n",
index 0dc3158667a2c7aba86f65fad19989e32a1baf8e..f12a0c8a7d98d0cbda8507dd9fa8233acb51f087 100644 (file)
@@ -3755,19 +3755,22 @@ EXPORT_SYMBOL(cond_resched);
  */
 int cond_resched_lock(spinlock_t * lock)
 {
+       int ret = 0;
+
        if (need_lockbreak(lock)) {
                spin_unlock(lock);
                cpu_relax();
+               ret = 1;
                spin_lock(lock);
        }
        if (need_resched()) {
                _raw_spin_unlock(lock);
                preempt_enable_no_resched();
                __cond_resched();
+               ret = 1;
                spin_lock(lock);
-               return 1;
        }
-       return 0;
+       return ret;
 }
 
 EXPORT_SYMBOL(cond_resched_lock);
@@ -4243,7 +4246,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *tsk)
 
        /* No more Mr. Nice Guy. */
        if (dest_cpu == NR_CPUS) {
-               tsk->cpus_allowed = cpuset_cpus_allowed(tsk);
+               cpus_setall(tsk->cpus_allowed);
                dest_cpu = any_online_cpu(tsk->cpus_allowed);
 
                /*
index 8f3debc77c5b2c6db5c7e360d18f9d2e2502a068..b3c24c732c5ad0d69a65945211151e84565435cb 100644 (file)
@@ -522,7 +522,16 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
 {
        int sig = 0;
 
-       sig = next_signal(pending, mask);
+       /* SIGKILL must have priority, otherwise it is quite easy
+        * to create an unkillable process, sending sig < SIGKILL
+        * to self */
+       if (unlikely(sigismember(&pending->signal, SIGKILL))) {
+               if (!sigismember(mask, SIGKILL))
+                       sig = SIGKILL;
+       }
+
+       if (likely(!sig))
+               sig = next_signal(pending, mask);
        if (sig) {
                if (current->notifier) {
                        if (sigismember(current->notifier_mask, sig)) {
index e15ed17863f16d1c266b82124e76222f1829e26c..0c3f9d8bbe17b3bd00a1c4a77e941bbebc90e226 100644 (file)
@@ -294,7 +294,7 @@ EXPORT_SYMBOL(_spin_unlock_irq);
 void __lockfunc _spin_unlock_bh(spinlock_t *lock)
 {
        _raw_spin_unlock(lock);
-       preempt_enable();
+       preempt_enable_no_resched();
        local_bh_enable();
 }
 EXPORT_SYMBOL(_spin_unlock_bh);
@@ -318,7 +318,7 @@ EXPORT_SYMBOL(_read_unlock_irq);
 void __lockfunc _read_unlock_bh(rwlock_t *lock)
 {
        _raw_read_unlock(lock);
-       preempt_enable();
+       preempt_enable_no_resched();
        local_bh_enable();
 }
 EXPORT_SYMBOL(_read_unlock_bh);
@@ -342,7 +342,7 @@ EXPORT_SYMBOL(_write_unlock_irq);
 void __lockfunc _write_unlock_bh(rwlock_t *lock)
 {
        _raw_write_unlock(lock);
-       preempt_enable();
+       preempt_enable_no_resched();
        local_bh_enable();
 }
 EXPORT_SYMBOL(_write_unlock_bh);
@@ -354,7 +354,7 @@ int __lockfunc _spin_trylock_bh(spinlock_t *lock)
        if (_raw_spin_trylock(lock))
                return 1;
 
-       preempt_enable();
+       preempt_enable_no_resched();
        local_bh_enable();
        return 0;
 }
index f64e97cabe253603dc860dd74412cc7731fe684d..f006632c2ba70c4493e1340db7c99bcad7ff38c0 100644 (file)
@@ -1195,7 +1195,7 @@ static int groups_from_user(struct group_info *group_info,
        return 0;
 }
 
-/* a simple shell-metzner sort */
+/* a simple Shell sort */
 static void groups_sort(struct group_info *group_info)
 {
        int base, max, stride;
index ac23847ce0e3cbcb3f006805dbd6d65a3966d399..0c421295e613f3436ddb29cf62c4823e48817762 100644 (file)
@@ -151,7 +151,8 @@ config DEBUG_FS
 
 config FRAME_POINTER
        bool "Compile the kernel with frame pointers"
-       depends on DEBUG_KERNEL && ((X86 && !X86_64) || CRIS || M68K || M68KNOMMU || FRV)
+       depends on DEBUG_KERNEL && ((X86 && !X86_64) || CRIS || M68K || M68KNOMMU || FRV || UML)
+       default y if DEBUG_INFO && UML
        help
          If you say Y here the resulting kernel image will be slightly larger
          and slower, but it will give very useful debugging information.
index ea3caedeabdb67f2ebe5199daa1086d7fbac0882..b73dbb0e7c83a4721fafbe4401c551a02e3225f9 100644 (file)
@@ -90,7 +90,7 @@ int cmpint(const void *a, const void *b)
 
 static int sort_test(void)
 {
-       int *a, i, r = 0;
+       int *a, i, r = 1;
 
        a = kmalloc(1000 * sizeof(int), GFP_KERNEL);
        BUG_ON(!a);
index 4bb93ad23c60cf5ad7e7c50e3c6c518cf52542df..d886ef157c121ffb04fec4db267ee9af69e01f60 100644 (file)
@@ -65,6 +65,7 @@ EXPORT_SYMBOL(strnicmp);
  * @dest: Where to copy the string to
  * @src: Where to copy the string from
  */
+#undef strcpy
 char * strcpy(char * dest,const char *src)
 {
        char *tmp = dest;
@@ -85,6 +86,10 @@ EXPORT_SYMBOL(strcpy);
  *
  * The result is not %NUL-terminated if the source exceeds
  * @count bytes.
+ *
+ * In the case where the length of @src is less than  that  of
+ * count, the remainder of @dest will be padded with %NUL.
+ *
  */
 char * strncpy(char * dest,const char *src,size_t count)
 {
@@ -132,6 +137,7 @@ EXPORT_SYMBOL(strlcpy);
  * @dest: The string to be appended to
  * @src: The string to append to it
  */
+#undef strcat
 char * strcat(char * dest, const char * src)
 {
        char *tmp = dest;
@@ -209,6 +215,7 @@ EXPORT_SYMBOL(strlcat);
  * @cs: One string
  * @ct: Another string
  */
+#undef strcmp
 int strcmp(const char * cs,const char * ct)
 {
        register signed char __res;
@@ -514,6 +521,7 @@ EXPORT_SYMBOL(memmove);
  * @ct: Another area of memory
  * @count: The size of the area.
  */
+#undef memcmp
 int memcmp(const void * cs,const void * ct,size_t count)
 {
        const unsigned char *su1, *su2;
index d5fdae2eb183861e4380c5f4367ac298d67966f1..4a2fee2cb62bad714491e1e910406ecd66dc2557 100644 (file)
 #include <linux/security.h>
 #include <linux/syscalls.h>
 /*
- * This is needed for the following functions:
- *  - try_to_release_page
- *  - block_invalidatepage
- *  - generic_osync_inode
- *
  * FIXME: remove all knowledge of the buffer layer from the core VM
  */
 #include <linux/buffer_head.h> /* for generic_osync_inode */
@@ -1009,7 +1004,7 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
                if (pos < size) {
                        retval = generic_file_direct_IO(READ, iocb,
                                                iov, pos, nr_segs);
-                       if (retval >= 0 && !is_sync_kiocb(iocb))
+                       if (retval > 0 && !is_sync_kiocb(iocb))
                                retval = -EIOCBQUEUED;
                        if (retval > 0)
                                *ppos = pos + retval;
@@ -1973,6 +1968,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
        do {
                unsigned long index;
                unsigned long offset;
+               unsigned long maxlen;
                size_t copied;
 
                offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
@@ -1987,7 +1983,10 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
                 * same page as we're writing to, without it being marked
                 * up-to-date.
                 */
-               fault_in_pages_readable(buf, bytes);
+               maxlen = cur_iov->iov_len - iov_base;
+               if (maxlen > bytes)
+                       maxlen = bytes;
+               fault_in_pages_readable(buf, maxlen);
 
                page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
                if (!page) {
@@ -2029,6 +2028,8 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
                                        filemap_set_next_iovec(&cur_iov,
                                                        &iov_base, status);
                                        buf = cur_iov->iov_base + iov_base;
+                               } else {
+                                       iov_base += status;
                                }
                        }
                }
index 6bad4c4064e7e0bae9886d976ccd7fbde8ccf753..d209f745db7fbc3154e83cf04666770068986724 100644 (file)
@@ -1701,12 +1701,13 @@ static int do_swap_page(struct mm_struct * mm,
        spin_lock(&mm->page_table_lock);
        page_table = pte_offset_map(pmd, address);
        if (unlikely(!pte_same(*page_table, orig_pte))) {
-               pte_unmap(page_table);
-               spin_unlock(&mm->page_table_lock);
-               unlock_page(page);
-               page_cache_release(page);
                ret = VM_FAULT_MINOR;
-               goto out;
+               goto out_nomap;
+       }
+
+       if (unlikely(!PageUptodate(page))) {
+               ret = VM_FAULT_SIGBUS;
+               goto out_nomap;
        }
 
        /* The page isn't present yet, go ahead with the fault. */
@@ -1741,6 +1742,12 @@ static int do_swap_page(struct mm_struct * mm,
        spin_unlock(&mm->page_table_lock);
 out:
        return ret;
+out_nomap:
+       pte_unmap(page_table);
+       spin_unlock(&mm->page_table_lock);
+       unlock_page(page);
+       page_cache_release(page);
+       goto out;
 }
 
 /*
index 01f9793591f666965342df8ef886358680bbae4c..de54acd9942f9929004921042721df5cdfe2b6c7 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1244,7 +1244,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        addr = mm->free_area_cache;
 
        /* make sure it can fit in the remaining address space */
-       if (addr >= len) {
+       if (addr > len) {
                vma = find_vma(mm, addr-len);
                if (!vma || addr <= vma->vm_start)
                        /* remember the address as a hint for next time */
@@ -1266,7 +1266,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 
                /* try just below the current vma->vm_start */
                addr = vma->vm_start-len;
-       } while (len <= vma->vm_start);
+       } while (len < vma->vm_start);
 
        /*
         * A failed mmap() very likely causes application failure,
@@ -1302,37 +1302,40 @@ unsigned long
 get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
                unsigned long pgoff, unsigned long flags)
 {
-       if (flags & MAP_FIXED) {
-               unsigned long ret;
+       unsigned long ret;
 
-               if (addr > TASK_SIZE - len)
-                       return -ENOMEM;
-               if (addr & ~PAGE_MASK)
-                       return -EINVAL;
-               if (file && is_file_hugepages(file))  {
-                       /*
-                        * Check if the given range is hugepage aligned, and
-                        * can be made suitable for hugepages.
-                        */
-                       ret = prepare_hugepage_range(addr, len);
-               } else {
-                       /*
-                        * Ensure that a normal request is not falling in a
-                        * reserved hugepage range.  For some archs like IA-64,
-                        * there is a separate region for hugepages.
-                        */
-                       ret = is_hugepage_only_range(current->mm, addr, len);
-               }
-               if (ret)
-                       return -EINVAL;
-               return addr;
-       }
+       if (!(flags & MAP_FIXED)) {
+               unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
 
-       if (file && file->f_op && file->f_op->get_unmapped_area)
-               return file->f_op->get_unmapped_area(file, addr, len,
-                                               pgoff, flags);
+               get_area = current->mm->get_unmapped_area;
+               if (file && file->f_op && file->f_op->get_unmapped_area)
+                       get_area = file->f_op->get_unmapped_area;
+               addr = get_area(file, addr, len, pgoff, flags);
+               if (IS_ERR_VALUE(addr))
+                       return addr;
+       }
 
-       return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
+       if (addr > TASK_SIZE - len)
+               return -ENOMEM;
+       if (addr & ~PAGE_MASK)
+               return -EINVAL;
+       if (file && is_file_hugepages(file))  {
+               /*
+                * Check if the given range is hugepage aligned, and
+                * can be made suitable for hugepages.
+                */
+               ret = prepare_hugepage_range(addr, len);
+       } else {
+               /*
+                * Ensure that a normal request is not falling in a
+                * reserved hugepage range.  For some archs like IA-64,
+                * there is a separate region for hugepages.
+                */
+               ret = is_hugepage_only_range(current->mm, addr, len);
+       }
+       if (ret)
+               return -EINVAL;
+       return addr;
 }
 
 EXPORT_SYMBOL(get_unmapped_area);
index 0dd7ace94e519d13f96d601bc1ecc543bb8ac595..ec7238a78f36c5eeac4bf1954e215399428a858d 100644 (file)
@@ -224,6 +224,12 @@ static unsigned long move_vma(struct vm_area_struct *vma,
                        split = 1;
        }
 
+       /*
+        * if we failed to move page tables we still do total_vm increment
+        * since do_munmap() will decrement it by old_len == new_len
+        */
+       mm->total_vm += new_len >> PAGE_SHIFT;
+
        if (do_munmap(mm, old_addr, old_len) < 0) {
                /* OOM: unable to split vma, just get accounts right */
                vm_unacct_memory(excess >> PAGE_SHIFT);
@@ -237,7 +243,6 @@ static unsigned long move_vma(struct vm_area_struct *vma,
                        vma->vm_next->vm_flags |= VM_ACCOUNT;
        }
 
-       mm->total_vm += new_len >> PAGE_SHIFT;
        __vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
        if (vm_flags & VM_LOCKED) {
                mm->locked_vm += new_len >> PAGE_SHIFT;
index b293ec1cc4e66879428684ef78afa0a313577528..c53e9c8f6b4adc98ac9fe69b1bc3526bba1baaa5 100644 (file)
@@ -150,7 +150,8 @@ void vfree(void *addr)
        kfree(addr);
 }
 
-void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
+void *__vmalloc(unsigned long size, unsigned int __nocast gfp_mask,
+                       pgprot_t prot)
 {
        /*
         * kmalloc doesn't like __GFP_HIGHMEM for some reason
index fc1b1064c5052317b597e43a3e2c343b3b834f8d..b1061b1962f86497a0deb83c2409b0e571fbf9d3 100644 (file)
@@ -43,7 +43,9 @@
  * initializer cleaner
  */
 nodemask_t node_online_map = { { [0] = 1UL } };
+EXPORT_SYMBOL(node_online_map);
 nodemask_t node_possible_map = NODE_MASK_ALL;
+EXPORT_SYMBOL(node_possible_map);
 struct pglist_data *pgdat_list;
 unsigned long totalram_pages;
 unsigned long totalhigh_pages;
index 378de234c12b9e74af3e6f43fc3ae8bf7ffe234c..9827409eb7c7ea4026e27b34fdaceacd909cabc3 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -586,7 +586,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
                dec_mm_counter(mm, anon_rss);
        }
 
-       inc_mm_counter(mm, rss);
+       dec_mm_counter(mm, rss);
        page_remove_rmap(page);
        page_cache_release(page);
 
@@ -626,7 +626,7 @@ static void try_to_unmap_cluster(unsigned long cursor,
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
-       pte_t *pte;
+       pte_t *pte, *original_pte;
        pte_t pteval;
        struct page *page;
        unsigned long address;
@@ -658,7 +658,7 @@ static void try_to_unmap_cluster(unsigned long cursor,
        if (!pmd_present(*pmd))
                goto out_unlock;
 
-       for (pte = pte_offset_map(pmd, address);
+       for (original_pte = pte = pte_offset_map(pmd, address);
                        address < end; pte++, address += PAGE_SIZE) {
 
                if (!pte_present(*pte))
@@ -694,7 +694,7 @@ static void try_to_unmap_cluster(unsigned long cursor,
                (*mapcount)--;
        }
 
-       pte_unmap(pte);
+       pte_unmap(original_pte);
 out_unlock:
        spin_unlock(&mm->page_table_lock);
 }
index a60e0075d55bd4d5692a5b39f146a7cedffe51e7..da48405cd9a3199d9088d1221864fa77a76a108d 100644 (file)
@@ -79,7 +79,7 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page)
                WARN_ON(page_count(page) <= 1);
 
                bdi = bdev->bd_inode->i_mapping->backing_dev_info;
-               bdi->unplug_io_fn(bdi, page);
+               blk_run_backing_dev(bdi, page);
        }
        up_read(&swap_unplug_sem);
 }
index 2bd83e5c2bbf0c7e8f12af4ea2f7b3b749a1a6b4..8ff16a1eee6ad43e5a7bec93a207ee94392c2233 100644 (file)
@@ -248,31 +248,20 @@ struct vm_struct *get_vm_area(unsigned long size, unsigned long flags)
        return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END);
 }
 
-/**
- *     remove_vm_area  -  find and remove a contingous kernel virtual area
- *
- *     @addr:          base address
- *
- *     Search for the kernel VM area starting at @addr, and remove it.
- *     This function returns the found VM area, but using it is NOT safe
- *     on SMP machines.
- */
-struct vm_struct *remove_vm_area(void *addr)
+/* Caller must hold vmlist_lock */
+struct vm_struct *__remove_vm_area(void *addr)
 {
        struct vm_struct **p, *tmp;
 
-       write_lock(&vmlist_lock);
        for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next) {
                 if (tmp->addr == addr)
                         goto found;
        }
-       write_unlock(&vmlist_lock);
        return NULL;
 
 found:
        unmap_vm_area(tmp);
        *p = tmp->next;
-       write_unlock(&vmlist_lock);
 
        /*
         * Remove the guard page.
@@ -281,6 +270,24 @@ found:
        return tmp;
 }
 
+/**
+ *     remove_vm_area  -  find and remove a contingous kernel virtual area
+ *
+ *     @addr:          base address
+ *
+ *     Search for the kernel VM area starting at @addr, and remove it.
+ *     This function returns the found VM area, but using it is NOT safe
+ *     on SMP machines, except for its size or flags.
+ */
+struct vm_struct *remove_vm_area(void *addr)
+{
+       struct vm_struct *v;
+       write_lock(&vmlist_lock);
+       v = __remove_vm_area(addr);
+       write_unlock(&vmlist_lock);
+       return v;
+}
+
 void __vunmap(void *addr, int deallocate_pages)
 {
        struct vm_struct *area;
index f9a31a9f70f1d5585cedfdc64eacebfd26cd89d7..ebcf4830d6f11a4da50fd17f40ee00f25c716c5a 100644 (file)
@@ -10,7 +10,7 @@
  * Authors:    Lawrence V. Stefani, <stefani@lkg.dec.com>
  *
  *             fddi.c is based on previous eth.c and tr.c work by
- *                     Ross Biro, <bir7@leland.Stanford.Edu>
+ *                     Ross Biro
  *                     Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *                     Mark Evans, <evansmp@uhura.aston.ac.uk>
  *                     Florian La Roche, <rzsfl@rz.uni-sb.de>
index 4eb135c0afbb796ed366cc020b1dfde89c8e38a6..051e8af56a7785f371b24e8ba9b4a3ae28c8f58e 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)hippi.c     1.0.0   05/29/97
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Mark Evans, <evansmp@uhura.aston.ac.uk>
  *             Florian  La Roche, <rzsfl@rz.uni-sb.de>
index 85293ccf7efcd3c66724dd8bfed62d9a1afef19c..a755e880f4bafa1d8847ab622d83ec189c95f5b4 100644 (file)
@@ -47,12 +47,12 @@ static void rif_check_expire(unsigned long dummy);
  *     Each RIF entry we learn is kept this way
  */
  
-struct rif_cache_s {   
+struct rif_cache {
        unsigned char addr[TR_ALEN];
        int iface;
-       __u16 rcf;
-       __u16 rseg[8];
-       struct rif_cache_s *next;
+       __be16 rcf;
+       __be16 rseg[8];
+       struct rif_cache *next;
        unsigned long last_used;
        unsigned char local_ring;
 };
@@ -64,7 +64,7 @@ struct rif_cache_s {
  *     up a lot.
  */
  
-static struct rif_cache_s *rif_table[RIF_TABLE_SIZE];
+static struct rif_cache *rif_table[RIF_TABLE_SIZE];
 
 static DEFINE_SPINLOCK(rif_lock);
 
@@ -249,7 +249,7 @@ void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *
 {
        int slack;
        unsigned int hash;
-       struct rif_cache_s *entry;
+       struct rif_cache *entry;
        unsigned char *olddata;
        static const unsigned char mcast_func_addr[] 
                = {0xC0,0x00,0x00,0x04,0x00,0x00};
@@ -337,7 +337,7 @@ printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0],
 static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev)
 {
        unsigned int hash, rii_p = 0;
-       struct rif_cache_s *entry;
+       struct rif_cache *entry;
 
 
        spin_lock_bh(&rif_lock);
@@ -373,7 +373,7 @@ printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
                 *      FIXME: We ought to keep some kind of cache size
                 *      limiting and adjust the timers to suit.
                 */
-               entry=kmalloc(sizeof(struct rif_cache_s),GFP_ATOMIC);
+               entry=kmalloc(sizeof(struct rif_cache),GFP_ATOMIC);
 
                if(!entry) 
                {
@@ -435,7 +435,7 @@ static void rif_check_expire(unsigned long dummy)
        spin_lock_bh(&rif_lock);
        
        for(i =0; i < RIF_TABLE_SIZE; i++) {
-               struct rif_cache_s *entry, **pentry;
+               struct rif_cache *entry, **pentry;
                
                pentry = rif_table+i;
                while((entry=*pentry) != NULL) {
@@ -467,10 +467,10 @@ static void rif_check_expire(unsigned long dummy)
  
 #ifdef CONFIG_PROC_FS
 
-static struct rif_cache_s *rif_get_idx(loff_t pos)
+static struct rif_cache *rif_get_idx(loff_t pos)
 {
        int i;
-       struct rif_cache_s *entry;
+       struct rif_cache *entry;
        loff_t off = 0;
 
        for(i = 0; i < RIF_TABLE_SIZE; i++) 
@@ -493,7 +493,7 @@ static void *rif_seq_start(struct seq_file *seq, loff_t *pos)
 static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
        int i;
-       struct rif_cache_s *ent = v;
+       struct rif_cache *ent = v;
 
        ++*pos;
 
@@ -522,7 +522,7 @@ static void rif_seq_stop(struct seq_file *seq, void *v)
 static int rif_seq_show(struct seq_file *seq, void *v)
 {
        int j, rcf_len, segment, brdgnmb;
-       struct rif_cache_s *entry = v;
+       struct rif_cache *entry = v;
 
        if (v == SEQ_START_TOKEN)
                seq_puts(seq,
index 76598445d84b1591279ea3467b68ebe119bb3684..1237e208e246a5ebcce6d69f524749472c4d3b06 100644 (file)
@@ -19,7 +19,7 @@ static int ltalk_mac_addr(struct net_device *dev, void *addr)
        return -EINVAL;
 }
 
-void ltalk_setup(struct net_device *dev)
+static void ltalk_setup(struct net_device *dev)
 {
        /* Fill in the fields of the device structure with localtalk-generic values. */
        
@@ -40,4 +40,22 @@ void ltalk_setup(struct net_device *dev)
 
        dev->flags              = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
 }
-EXPORT_SYMBOL(ltalk_setup);
+
+/**
+ * alloc_ltalkdev - Allocates and sets up an localtalk device
+ * @sizeof_priv: Size of additional driver-private structure to be allocated
+ *     for this localtalk device
+ *
+ * Fill in the fields of the device structure with localtalk-generic
+ * values. Basically does everything except registering the device.
+ *
+ * Constructs a new net device, complete with a private data area of
+ * size @sizeof_priv.  A 32-byte (not bit) alignment is enforced for
+ * this private data area.
+ */
+
+struct net_device *alloc_ltalkdev(int sizeof_priv)
+{
+       return alloc_netdev(sizeof_priv, "lt%d", ltalk_setup);
+}
+EXPORT_SYMBOL(alloc_ltalkdev);
index d9b72fde433c4e378b1d3657843785f684497a52..f564ee99782d248dab471e124f3d02dadeb5512a 100644 (file)
 
 static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
 {
-       struct net_bridge *br;
-
-       br = dev->priv;
-
+       struct net_bridge *br = netdev_priv(dev);
        return &br->statistics;
 }
 
@@ -54,9 +51,11 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static int br_dev_open(struct net_device *dev)
 {
-       netif_start_queue(dev);
+       struct net_bridge *br = netdev_priv(dev);
 
-       br_stp_enable_bridge(dev->priv);
+       br_features_recompute(br);
+       netif_start_queue(dev);
+       br_stp_enable_bridge(br);
 
        return 0;
 }
@@ -67,7 +66,7 @@ static void br_dev_set_multicast_list(struct net_device *dev)
 
 static int br_dev_stop(struct net_device *dev)
 {
-       br_stp_disable_bridge(dev->priv);
+       br_stp_disable_bridge(netdev_priv(dev));
 
        netif_stop_queue(dev);
 
@@ -76,7 +75,7 @@ static int br_dev_stop(struct net_device *dev)
 
 static int br_change_mtu(struct net_device *dev, int new_mtu)
 {
-       if ((new_mtu < 68) || new_mtu > br_min_mtu(dev->priv))
+       if (new_mtu < 68 || new_mtu > br_min_mtu(netdev_priv(dev)))
                return -EINVAL;
 
        dev->mtu = new_mtu;
index 69872bf3b87e9e59426e384406f72747e9d09b6a..91bb895375f4c8e90c4ef6190e19dd7de4de6c0f 100644 (file)
@@ -314,6 +314,28 @@ int br_min_mtu(const struct net_bridge *br)
        return mtu;
 }
 
+/*
+ * Recomputes features using slave's features
+ */
+void br_features_recompute(struct net_bridge *br)
+{
+       struct net_bridge_port *p;
+       unsigned long features, checksum;
+
+       features = NETIF_F_SG | NETIF_F_FRAGLIST 
+               | NETIF_F_HIGHDMA | NETIF_F_TSO;
+       checksum = NETIF_F_IP_CSUM;     /* least commmon subset */
+
+       list_for_each_entry(p, &br->port_list, list) {
+               if (!(p->dev->features 
+                     & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
+                       checksum = 0;
+               features &= p->dev->features;
+       }
+
+       br->dev->features = features | checksum | NETIF_F_LLTX;
+}
+
 /* called with RTNL */
 int br_add_if(struct net_bridge *br, struct net_device *dev)
 {
@@ -368,6 +390,7 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
 
        spin_lock_bh(&br->lock);
        br_stp_recalculate_bridge_id(br);
+       br_features_recompute(br);
        spin_unlock_bh(&br->lock);
 
        return 0;
index 2b1cce46cab42f71faee654e91c9fdfc2a224551..8f5f2e7309920d4047571b2237b530fe1c791dfc 100644 (file)
@@ -26,7 +26,7 @@ static int br_pass_frame_up_finish(struct sk_buff *skb)
 #ifdef CONFIG_NETFILTER_DEBUG
        skb->nf_debug = 0;
 #endif
-       netif_rx(skb);
+       netif_receive_skb(skb);
 
        return 0;
 }
@@ -54,6 +54,9 @@ int br_handle_frame_finish(struct sk_buff *skb)
        struct net_bridge_fdb_entry *dst;
        int passedup = 0;
 
+       /* insert into forwarding database after filtering to avoid spoofing */
+       br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
+
        if (br->dev->flags & IFF_PROMISC) {
                struct sk_buff *skb2;
 
@@ -108,8 +111,7 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
        if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
                goto err;
 
-       if (p->state == BR_STATE_LEARNING ||
-           p->state == BR_STATE_FORWARDING)
+       if (p->state == BR_STATE_LEARNING)
                br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
 
        if (p->br->stp_enabled &&
index f8fb49e34764e86cc8884c32b2ee924d512b3365..917311c6828b9c5c70d2290c617c4ebaf9be3405 100644 (file)
@@ -65,6 +65,15 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
                }
                break;
 
+       case NETDEV_FEAT_CHANGE:
+               if (br->dev->flags & IFF_UP) 
+                       br_features_recompute(br);
+
+               /* could do recursive feature change notification
+                * but who would care?? 
+                */
+               break;
+
        case NETDEV_DOWN:
                if (br->dev->flags & IFF_UP)
                        br_stp_disable_port(p);
index 54d63f1372a0a65641baf53c7d4dbeb3f9f1c963..bdf95a74d8cd3294ec5765dabf94de1edd20de93 100644 (file)
@@ -174,6 +174,7 @@ extern int br_add_if(struct net_bridge *br,
 extern int br_del_if(struct net_bridge *br,
              struct net_device *dev);
 extern int br_min_mtu(const struct net_bridge *br);
+extern void br_features_recompute(struct net_bridge *br);
 
 /* br_input.c */
 extern int br_handle_frame_finish(struct sk_buff *skb);
index b91a875aca01c23f0b37b7916cad225e0c5f9fe5..d071f1c9ad0b00076c18ce677ed1ccba0bc300ec 100644 (file)
@@ -140,6 +140,9 @@ int br_stp_handle_bpdu(struct sk_buff *skb)
        struct net_bridge *br = p->br;
        unsigned char *buf;
 
+       /* insert into forwarding database after filtering to avoid spoofing */
+       br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
+
        /* need at least the 802 and STP headers */
        if (!pskb_may_pull(skb, sizeof(header)+1) ||
            memcmp(skb->data, header, sizeof(header)))
index f5f005846fe1aca24c96caca1cbf875d3e99ebba..ab935778ce81009cadea261d289f7bd44e623850 100644 (file)
@@ -7,7 +7,7 @@
  *             2 of the License, or (at your option) any later version.
  *
  *     Derived from the non IP parts of dev.c 1.0.19
- *             Authors:        Ross Biro, <bir7@leland.Stanford.Edu>
+ *             Authors:        Ross Biro
  *                             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *                             Mark Evans, <evansmp@uhura.aston.ac.uk>
  *
@@ -760,6 +760,18 @@ int dev_change_name(struct net_device *dev, char *newname)
        return err;
 }
 
+/**
+ *     netdev_features_change - device changes fatures
+ *     @dev: device to cause notification
+ *
+ *     Called to indicate a device has changed features.
+ */
+void netdev_features_change(struct net_device *dev)
+{
+       notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
+}
+EXPORT_SYMBOL(netdev_features_change);
+
 /**
  *     netdev_state_change - device changes state
  *     @dev: device to cause notification
@@ -1732,6 +1744,7 @@ static int process_backlog(struct net_device *backlog_dev, int *budget)
        struct softnet_data *queue = &__get_cpu_var(softnet_data);
        unsigned long start_time = jiffies;
 
+       backlog_dev->weight = weight_p;
        for (;;) {
                struct sk_buff *skb;
                struct net_device *dev;
index f05fde97c43d6a8741fa8992972f022998be5161..a3eeb88e1c81fabe1eea26499958723955b08615 100644 (file)
@@ -29,7 +29,7 @@ u32 ethtool_op_get_link(struct net_device *dev)
 
 u32 ethtool_op_get_tx_csum(struct net_device *dev)
 {
-       return (dev->features & NETIF_F_IP_CSUM) != 0;
+       return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0;
 }
 
 int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
@@ -42,6 +42,15 @@ int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
        return 0;
 }
 
+int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data)
+{
+       if (data)
+               dev->features |= NETIF_F_HW_CSUM;
+       else
+               dev->features &= ~NETIF_F_HW_CSUM;
+
+       return 0;
+}
 u32 ethtool_op_get_sg(struct net_device *dev)
 {
        return (dev->features & NETIF_F_SG) != 0;
@@ -347,7 +356,7 @@ static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
 {
        struct ethtool_coalesce coalesce;
 
-       if (!dev->ethtool_ops->get_coalesce)
+       if (!dev->ethtool_ops->set_coalesce)
                return -EOPNOTSUPP;
 
        if (copy_from_user(&coalesce, useraddr, sizeof(coalesce)))
@@ -682,6 +691,7 @@ int dev_ethtool(struct ifreq *ifr)
        void __user *useraddr = ifr->ifr_data;
        u32 ethcmd;
        int rc;
+       unsigned long old_features;
 
        /*
         * XXX: This can be pushed down into the ethtool_* handlers that
@@ -703,6 +713,8 @@ int dev_ethtool(struct ifreq *ifr)
                if ((rc = dev->ethtool_ops->begin(dev)) < 0)
                        return rc;
 
+       old_features = dev->features;
+
        switch (ethcmd) {
        case ETHTOOL_GSET:
                rc = ethtool_get_settings(dev, useraddr);
@@ -712,7 +724,6 @@ int dev_ethtool(struct ifreq *ifr)
                break;
        case ETHTOOL_GDRVINFO:
                rc = ethtool_get_drvinfo(dev, useraddr);
-
                break;
        case ETHTOOL_GREGS:
                rc = ethtool_get_regs(dev, useraddr);
@@ -801,6 +812,10 @@ int dev_ethtool(struct ifreq *ifr)
        
        if(dev->ethtool_ops->complete)
                dev->ethtool_ops->complete(dev);
+
+       if (old_features != dev->features)
+               netdev_features_change(dev);
+
        return rc;
 
  ioctl:
@@ -817,3 +832,4 @@ EXPORT_SYMBOL(ethtool_op_get_tx_csum);
 EXPORT_SYMBOL(ethtool_op_set_sg);
 EXPORT_SYMBOL(ethtool_op_set_tso);
 EXPORT_SYMBOL(ethtool_op_set_tx_csum);
+EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum);
index 060f703659e83544283990912aa92c587938e41b..e2137f3e489d1adbb39cecb7abb88e8567f448e4 100644 (file)
@@ -21,6 +21,7 @@
 #define to_net_dev(class) container_of(class, struct net_device, class_dev)
 
 static const char fmt_hex[] = "%#x\n";
+static const char fmt_long_hex[] = "%#lx\n";
 static const char fmt_dec[] = "%d\n";
 static const char fmt_ulong[] = "%lu\n";
 
@@ -91,7 +92,7 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)          \
 NETDEVICE_ATTR(addr_len, fmt_dec);
 NETDEVICE_ATTR(iflink, fmt_dec);
 NETDEVICE_ATTR(ifindex, fmt_dec);
-NETDEVICE_ATTR(features, fmt_hex);
+NETDEVICE_ATTR(features, fmt_long_hex);
 NETDEVICE_ATTR(type, fmt_dec);
 
 /* use same locking rules as GIFHWADDR ioctl's */
@@ -184,6 +185,22 @@ static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, siz
 static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, 
                         store_tx_queue_len);
 
+NETDEVICE_SHOW(weight, fmt_dec);
+
+static int change_weight(struct net_device *net, unsigned long new_weight)
+{
+       net->weight = new_weight;
+       return 0;
+}
+
+static ssize_t store_weight(struct class_device *dev, const char *buf, size_t len)
+{
+       return netdev_store(dev, buf, len, change_weight);
+}
+
+static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, 
+                        store_weight);
+
 
 static struct class_device_attribute *net_class_attributes[] = {
        &class_device_attr_ifindex,
@@ -193,6 +210,7 @@ static struct class_device_attribute *net_class_attributes[] = {
        &class_device_attr_features,
        &class_device_attr_mtu,
        &class_device_attr_flags,
+       &class_device_attr_weight,
        &class_device_attr_type,
        &class_device_attr_address,
        &class_device_attr_broadcast,
index 98171ddd7e7d668a4728d0d84e5994a64c6e9dd2..96e00b08698f986f21cebd6fe26c467bb2e6e202 100644 (file)
@@ -9,7 +9,7 @@
  *
  * Version:    $Id: sock.c,v 1.117 2002/02/01 22:01:03 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Florian La Roche, <flla@stud.uni-sb.de>
  *             Alan Cox, <A.Cox@swansea.ac.uk>
@@ -635,7 +635,11 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
                if (zero_it) {
                        memset(sk, 0, prot->obj_size);
                        sk->sk_family = family;
-                       sk->sk_prot = prot;
+                       /*
+                        * See comment in struct sock definition to understand
+                        * why we need sk_prot_creator -acme
+                        */
+                       sk->sk_prot = sk->sk_prot_creator = prot;
                        sock_lock_init(sk);
                }
                
@@ -654,7 +658,7 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
 void sk_free(struct sock *sk)
 {
        struct sk_filter *filter;
-       struct module *owner = sk->sk_prot->owner;
+       struct module *owner = sk->sk_prot_creator->owner;
 
        if (sk->sk_destruct)
                sk->sk_destruct(sk);
@@ -672,8 +676,8 @@ void sk_free(struct sock *sk)
                       __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
 
        security_sk_free(sk);
-       if (sk->sk_prot->slab != NULL)
-               kmem_cache_free(sk->sk_prot->slab, sk);
+       if (sk->sk_prot_creator->slab != NULL)
+               kmem_cache_free(sk->sk_prot_creator->slab, sk);
        else
                kfree(sk);
        module_put(owner);
index e6e23eb144280151124cdeaeaf546e9d39b905a3..ee7bf46eb78ab60f7f8b7646b4fa1ab6b44ab98e 100644 (file)
@@ -1426,7 +1426,7 @@ static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] =
        [RTM_GETRULE  - RTM_BASE] = { .dumpit   = dn_fib_dump_rules,    },
 #else
        [RTM_GETROUTE - RTM_BASE] = { .doit     = dn_cache_getroute,
-                                     .dumpit   = dn_cache_dump,        
+                                     .dumpit   = dn_cache_dump,        },
 #endif
 
 };
index 16c4234cbe123cff01bb35bf8e558b8d6ab04432..6617ea47d3656a6b6c6cfa94e546c12dc9648f8e 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    @(#)eth.c       1.0.7   05/25/93
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Mark Evans, <evansmp@uhura.aston.ac.uk>
  *             Florian  La Roche, <rzsfl@rz.uni-sb.de>
index cdad47642ae74d80ef783670cefedfc898fff809..03942f13394471c2e0816a70765da05fc518d9ff 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Florian La Roche, <flla@stud.uni-sb.de>
  *             Alan Cox, <A.Cox@swansea.ac.uk>
@@ -1181,6 +1181,7 @@ EXPORT_SYMBOL(inet_stream_connect);
 EXPORT_SYMBOL(inet_stream_ops);
 EXPORT_SYMBOL(inet_unregister_protosw);
 EXPORT_SYMBOL(net_statistics);
+EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
 
 #ifdef INET_REFCNT_DEBUG
 EXPORT_SYMBOL(inet_sock_nr);
index abbc6d5c183e3da23e16d7190ff997174635c0bb..478a30179a527149a837bf1092e1cda0b704456f 100644 (file)
@@ -9,7 +9,7 @@
  *             2 of the License, or (at your option) any later version.
  *
  *     Derived from the IP parts of dev.c 1.0.19
- *             Authors:        Ross Biro, <bir7@leland.Stanford.Edu>
+ *             Authors:        Ross Biro
  *                             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *                             Mark Evans, <evansmp@uhura.aston.ac.uk>
  *
@@ -233,11 +233,14 @@ int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b)
 static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
                         int destroy)
 {
+       struct in_ifaddr *promote = NULL;
        struct in_ifaddr *ifa1 = *ifap;
 
        ASSERT_RTNL();
 
-       /* 1. Deleting primary ifaddr forces deletion all secondaries */
+       /* 1. Deleting primary ifaddr forces deletion all secondaries 
+        * unless alias promotion is set
+        **/
 
        if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) {
                struct in_ifaddr *ifa;
@@ -251,11 +254,16 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
                                continue;
                        }
 
-                       *ifap1 = ifa->ifa_next;
+                       if (!IN_DEV_PROMOTE_SECONDARIES(in_dev)) {
+                               *ifap1 = ifa->ifa_next;
 
-                       rtmsg_ifa(RTM_DELADDR, ifa);
-                       notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
-                       inet_free_ifa(ifa);
+                               rtmsg_ifa(RTM_DELADDR, ifa);
+                               notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
+                               inet_free_ifa(ifa);
+                       } else {
+                               promote = ifa;
+                               break;
+                       }
                }
        }
 
@@ -281,6 +289,13 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
                if (!in_dev->ifa_list)
                        inetdev_destroy(in_dev);
        }
+
+       if (promote && IN_DEV_PROMOTE_SECONDARIES(in_dev)) {
+               /* not sure if we should send a delete notify first? */
+               promote->ifa_flags &= ~IFA_F_SECONDARY;
+               rtmsg_ifa(RTM_NEWADDR, promote);
+               notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote);
+       }
 }
 
 static int inet_insert_ifa(struct in_ifaddr *ifa)
@@ -1384,6 +1399,15 @@ static struct devinet_sysctl_table {
                        .proc_handler   = &ipv4_doint_and_flush,
                        .strategy       = &ipv4_doint_and_flush_strategy,
                },
+               {
+                       .ctl_name       = NET_IPV4_CONF_PROMOTE_SECONDARIES,
+                       .procname       = "promote_secondaries",
+                       .data           = &ipv4_devconf.promote_secondaries,
+                       .maxlen         = sizeof(int),
+                       .mode           = 0644,
+                       .proc_handler   = &ipv4_doint_and_flush,
+                       .strategy       = &ipv4_doint_and_flush_strategy,
+               },
        },
        .devinet_dev = {
                {
index 053a883247ba68ad4f68eb88971a33a881196840..eae84cc39d3f10e984c93e11cb4a94c160bc6a80 100644 (file)
@@ -478,7 +478,7 @@ static int __init esp4_init(void)
 {
        struct xfrm_decap_state decap;
 
-       if (sizeof(struct esp_decap_data)  <
+       if (sizeof(struct esp_decap_data)  >
            sizeof(decap.decap_data)) {
                extern void decap_data_too_small(void);
 
index 85bf0d3e294b2c6d5da9fe721904ff07f2c47567..cb759484979d94d46d946a66cca3ef4bf87d84a1 100644 (file)
@@ -207,6 +207,7 @@ int sysctl_icmp_ignore_bogus_error_responses;
 
 int sysctl_icmp_ratelimit = 1 * HZ;
 int sysctl_icmp_ratemask = 0x1818;
+int sysctl_icmp_errors_use_inbound_ifaddr;
 
 /*
  *     ICMP control array. This specifies what to do with each ICMP.
@@ -511,8 +512,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
         */
 
        saddr = iph->daddr;
-       if (!(rt->rt_flags & RTCF_LOCAL))
-               saddr = 0;
+       if (!(rt->rt_flags & RTCF_LOCAL)) {
+               if (sysctl_icmp_errors_use_inbound_ifaddr)
+                       saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
+               else
+                       saddr = 0;
+       }
 
        tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) |
                                           IPTOS_PREC_INTERNETCONTROL) :
index a0d0833034be70703a8b9f6c184394cd55079f7a..4e47a2658c7cd3444f6bf10ec769f9fc726859fb 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: ip_input.c,v 1.55 2002/01/12 07:39:45 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Donald Becker, <becker@super.org>
  *             Alan Cox, <Alan.Cox@linux.org>
index 24fe3e00b42b0bb673be5a6d8ceb15defb192974..760dc8238d653e74351d30aa6fbeec6efc3c21d9 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: ip_output.c,v 1.100 2002/02/01 22:01:03 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Donald Becker, <becker@super.org>
  *             Alan Cox, <Alan.Cox@linux.org>
@@ -490,6 +490,14 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
                        /* Partially cloned skb? */
                        if (skb_shared(frag))
                                goto slow_path;
+
+                       BUG_ON(frag->sk);
+                       if (skb->sk) {
+                               sock_hold(skb->sk);
+                               frag->sk = skb->sk;
+                               frag->destructor = sock_wfree;
+                               skb->truesize -= frag->truesize;
+                       }
                }
 
                /* Everything is OK. Generate! */
index a788461a40c9228688dcc42ce72f5a7543339140..30e85de9fffff03662455d2357b5d384135d3db0 100644 (file)
@@ -11,7 +11,7 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH) += ip_vs_proto_ah.o
 
 ip_vs-objs :=  ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o        \
                ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o                      \
-               ip_vs_est.o ip_vs_proto.o ip_vs_proto_icmp.o               \
+               ip_vs_est.o ip_vs_proto.o                                  \
                $(ip_vs_proto-objs-y)
 
 
index 253c46252bd5b1dfeae6382c94a2eaf7340278ae..867d4e9c6594c3a62eb70475d6b2c26cfe74c2ca 100644 (file)
@@ -216,9 +216,6 @@ int ip_vs_protocol_init(void)
 #ifdef CONFIG_IP_VS_PROTO_UDP
        REGISTER_PROTOCOL(&ip_vs_protocol_udp);
 #endif
-#ifdef CONFIG_IP_VS_PROTO_ICMP
-       REGISTER_PROTOCOL(&ip_vs_protocol_icmp);
-#endif
 #ifdef CONFIG_IP_VS_PROTO_AH
        REGISTER_PROTOCOL(&ip_vs_protocol_ah);
 #endif
diff --git a/net/ipv4/ipvs/ip_vs_proto_icmp.c b/net/ipv4/ipvs/ip_vs_proto_icmp.c
deleted file mode 100644 (file)
index 191e94a..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * ip_vs_proto_icmp.c: ICMP load balancing support for IP Virtual Server
- *
- * Authors:    Julian Anastasov <ja@ssi.bg>, March 2002
- *
- *             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/icmp.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter_ipv4.h>
-
-#include <net/ip_vs.h>
-
-
-static int icmp_timeouts[1] =          { 1*60*HZ };
-
-static char * icmp_state_name_table[1] = { "ICMP" };
-
-static struct ip_vs_conn *
-icmp_conn_in_get(const struct sk_buff *skb,
-                struct ip_vs_protocol *pp,
-                const struct iphdr *iph,
-                unsigned int proto_off,
-                int inverse)
-{
-#if 0
-       struct ip_vs_conn *cp;
-
-       if (likely(!inverse)) {
-               cp = ip_vs_conn_in_get(iph->protocol,
-                       iph->saddr, 0,
-                       iph->daddr, 0);
-       } else {
-               cp = ip_vs_conn_in_get(iph->protocol,
-                       iph->daddr, 0,
-                       iph->saddr, 0);
-       }
-
-       return cp;
-
-#else
-       return NULL;
-#endif
-}
-
-static struct ip_vs_conn *
-icmp_conn_out_get(const struct sk_buff *skb,
-                 struct ip_vs_protocol *pp,
-                 const struct iphdr *iph,
-                 unsigned int proto_off,
-                 int inverse)
-{
-#if 0
-       struct ip_vs_conn *cp;
-
-       if (likely(!inverse)) {
-               cp = ip_vs_conn_out_get(iph->protocol,
-                       iph->saddr, 0,
-                       iph->daddr, 0);
-       } else {
-               cp = ip_vs_conn_out_get(IPPROTO_UDP,
-                       iph->daddr, 0,
-                       iph->saddr, 0);
-       }
-
-       return cp;
-#else
-       return NULL;
-#endif
-}
-
-static int
-icmp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
-                  int *verdict, struct ip_vs_conn **cpp)
-{
-       *verdict = NF_ACCEPT;
-       return 0;
-}
-
-static int
-icmp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
-{
-       if (!(skb->nh.iph->frag_off & __constant_htons(IP_OFFSET))) {
-               if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
-                       if (ip_vs_checksum_complete(skb, skb->nh.iph->ihl * 4)) {
-                               IP_VS_DBG_RL_PKT(0, pp, skb, 0, "Failed checksum for");
-                               return 0;
-                       }
-               }
-       }
-       return 1;
-}
-
-static void
-icmp_debug_packet(struct ip_vs_protocol *pp,
-                 const struct sk_buff *skb,
-                 int offset,
-                 const char *msg)
-{
-       char buf[256];
-       struct iphdr _iph, *ih;
-
-       ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
-       if (ih == NULL)
-               sprintf(buf, "%s TRUNCATED", pp->name);
-       else if (ih->frag_off & __constant_htons(IP_OFFSET))
-               sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u frag",
-                       pp->name, NIPQUAD(ih->saddr),
-                       NIPQUAD(ih->daddr));
-       else {
-               struct icmphdr _icmph, *ic;
-
-               ic = skb_header_pointer(skb, offset + ih->ihl*4,
-                                       sizeof(_icmph), &_icmph);
-               if (ic == NULL)
-                       sprintf(buf, "%s TRUNCATED to %u bytes\n",
-                               pp->name, skb->len - offset);
-               else
-                       sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u T:%d C:%d",
-                               pp->name, NIPQUAD(ih->saddr),
-                               NIPQUAD(ih->daddr),
-                               ic->type, ic->code);
-       }
-       printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
-}
-
-static int
-icmp_state_transition(struct ip_vs_conn *cp, int direction,
-                     const struct sk_buff *skb,
-                     struct ip_vs_protocol *pp)
-{
-       cp->timeout = pp->timeout_table[IP_VS_ICMP_S_NORMAL];
-       return 1;
-}
-
-static int
-icmp_set_state_timeout(struct ip_vs_protocol *pp, char *sname, int to)
-{
-       int num;
-       char **names;
-
-       num = IP_VS_ICMP_S_LAST;
-       names = icmp_state_name_table;
-       return ip_vs_set_state_timeout(pp->timeout_table, num, names, sname, to);
-}
-
-
-static void icmp_init(struct ip_vs_protocol *pp)
-{
-       pp->timeout_table = icmp_timeouts;
-}
-
-static void icmp_exit(struct ip_vs_protocol *pp)
-{
-}
-
-struct ip_vs_protocol ip_vs_protocol_icmp = {
-       .name =                 "ICMP",
-       .protocol =             IPPROTO_ICMP,
-       .dont_defrag =          0,
-       .init =                 icmp_init,
-       .exit =                 icmp_exit,
-       .conn_schedule =        icmp_conn_schedule,
-       .conn_in_get =          icmp_conn_in_get,
-       .conn_out_get =         icmp_conn_out_get,
-       .snat_handler =         NULL,
-       .dnat_handler =         NULL,
-       .csum_check =           icmp_csum_check,
-       .state_transition =     icmp_state_transition,
-       .register_app =         NULL,
-       .unregister_app =       NULL,
-       .app_conn_bind =        NULL,
-       .debug_packet =         icmp_debug_packet,
-       .timeout_change =       NULL,
-       .set_state_timeout =    icmp_set_state_timeout,
-};
index faa6176bbeb195eb37329964d092c377a2489890..de21da00057f3df6f84338244ab668d9f73bb90e 100644 (file)
@@ -508,7 +508,6 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
                        rc = NF_ACCEPT;
                /* do not touch skb anymore */
                atomic_inc(&cp->in_pkts);
-               __ip_vs_conn_put(cp);
                goto out;
        }
 
index 9349686131fcf2552a748913675dab743f6bc733..c9cf8726051d7cae07a3d1278b0bea36b1c2eee5 100644 (file)
@@ -31,6 +31,7 @@
 #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>
@@ -57,7 +58,6 @@ struct multipath_device {
 
 static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES];
 static DEFINE_SPINLOCK(state_lock);
-static struct rtable *last_selection = NULL;
 
 static int inline __multipath_findslot(void)
 {
@@ -111,11 +111,6 @@ struct notifier_block drr_dev_notifier = {
        .notifier_call  = drr_dev_event,
 };
 
-static void drr_remove(struct rtable *rt)
-{
-       if (last_selection == rt)
-               last_selection = NULL;
-}
 
 static void drr_safe_inc(atomic_t *usecount)
 {
@@ -144,14 +139,6 @@ static void drr_select_route(const struct flowi *flp,
        int devidx = -1;
        int cur_min_devidx = -1;
 
-               /* if necessary and possible utilize the old alternative */
-       if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 &&
-           last_selection != NULL) {
-               result = last_selection;
-               *rp = result;
-               return;
-       }
-
        /* 1. make sure all alt. nexthops have the same GC related data */
        /* 2. determine the new candidate to be returned */
        result = NULL;
@@ -229,12 +216,10 @@ static void drr_select_route(const struct flowi *flp,
        }
 
        *rp = result;
-       last_selection = result;
 }
 
 static struct ip_mp_alg_ops drr_ops = {
        .mp_alg_select_route    =       drr_select_route,
-       .mp_alg_remove          =       drr_remove,
 };
 
 static int __init drr_init(void)
@@ -244,7 +229,7 @@ static int __init drr_init(void)
        if (err)
                return err;
 
-       err = multipath_alg_register(&drr_ops, IP_MP_ALG_RR);
+       err = multipath_alg_register(&drr_ops, IP_MP_ALG_DRR);
        if (err)
                goto fail;
 
@@ -263,3 +248,4 @@ static void __exit drr_exit(void)
 
 module_init(drr_init);
 module_exit(drr_exit);
+MODULE_LICENSE("GPL");
index 805a16e47de5ff9f35f2623dd0fc3e524aac18c5..5249dbe7c559f90fce4671405954a415aebb3b4c 100644 (file)
@@ -31,6 +31,7 @@
 #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>
@@ -126,3 +127,4 @@ static void __exit random_exit(void)
 
 module_init(random_init);
 module_exit(random_exit);
+MODULE_LICENSE("GPL");
index 554a8256816027bbbeb60c16db62ff6a4e44de29..b6cd2870478f9db2700e5a49839f07782ac758da 100644 (file)
@@ -31,6 +31,7 @@
 #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/checksum.h>
 #include <net/ip_mp_alg.h>
 
-#define MULTIPATH_MAX_CANDIDATES 40
-
-static struct rtable* last_used = NULL;
-
-static void rr_remove(struct rtable *rt)
-{
-       if (last_used == rt)
-               last_used = NULL;
-}
-
 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;
 
-       /* if necessary and possible utilize the old alternative */
-       if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 &&
-           last_used != NULL) {
-               result = last_used;
-               goto out;
-       }
-
        /* 1. make sure all alt. nexthops have the same GC related data
         * 2. determine the new candidate to be returned
         */
@@ -90,15 +74,12 @@ static void rr_select_route(const struct flowi *flp,
        if (!result)
                result = first;
 
-out:
-       last_used = result;
        result->u.dst.__use++;
        *rp = result;
 }
 
 static struct ip_mp_alg_ops rr_ops = {
        .mp_alg_select_route    =       rr_select_route,
-       .mp_alg_remove          =       rr_remove,
 };
 
 static int __init rr_init(void)
@@ -113,3 +94,4 @@ static void __exit rr_exit(void)
 
 module_init(rr_init);
 module_exit(rr_exit);
+MODULE_LICENSE("GPL");
index 10b23e1bece663bd8a9317f980b30ec0df7f0a11..bd7d75b6abe0a6a7e1ed63d78b5d18becf3eb961 100644 (file)
@@ -31,6 +31,7 @@
 #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>
@@ -172,7 +173,7 @@ static void wrandom_select_route(const struct flowi *flp,
                    multipath_comparekeys(&rt->fl, flp)) {
                        struct multipath_candidate* mpc =
                                (struct multipath_candidate*)
-                               kmalloc(size_mpc, GFP_KERNEL);
+                               kmalloc(size_mpc, GFP_ATOMIC);
 
                        if (!mpc)
                                return;
@@ -244,7 +245,7 @@ static void wrandom_set_nhinfo(__u32 network,
        if (!target_route) {
                const size_t size_rt = sizeof(struct multipath_route);
                target_route = (struct multipath_route *)
-                       kmalloc(size_rt, GFP_KERNEL);
+                       kmalloc(size_rt, GFP_ATOMIC);
 
                target_route->gw = nh->nh_gw;
                target_route->oif = nh->nh_oif;
@@ -265,7 +266,7 @@ static void wrandom_set_nhinfo(__u32 network,
        if (!target_dest) {
                const size_t size_dst = sizeof(struct multipath_dest);
                target_dest = (struct multipath_dest*)
-                       kmalloc(size_dst, GFP_KERNEL);
+                       kmalloc(size_dst, GFP_ATOMIC);
 
                target_dest->nh_info = nh;
                target_dest->network = network;
@@ -342,3 +343,4 @@ static void __exit wrandom_exit(void)
 
 module_init(wrandom_init);
 module_exit(wrandom_exit);
+MODULE_LICENSE("GPL");
index 28d9425d5c390dac7601953e65043e973833e7aa..09e8246229770fa45b438491a3eacff229d1f1a1 100644 (file)
@@ -940,37 +940,25 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct,
 struct sk_buff *
 ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user)
 {
-       struct sock *sk = skb->sk;
 #ifdef CONFIG_NETFILTER_DEBUG
        unsigned int olddebug = skb->nf_debug;
 #endif
 
-       if (sk) {
-               sock_hold(sk);
-               skb_orphan(skb);
-       }
+       skb_orphan(skb);
 
        local_bh_disable(); 
        skb = ip_defrag(skb, user);
        local_bh_enable();
 
-       if (!skb) {
-               if (sk)
-                       sock_put(sk);
-               return skb;
-       }
-
-       if (sk) {
-               skb_set_owner_w(skb, sk);
-               sock_put(sk);
-       }
-
-       ip_send_check(skb->nh.iph);
-       skb->nfcache |= NFC_ALTERED;
+       if (skb) {
+               ip_send_check(skb->nh.iph);
+               skb->nfcache |= NFC_ALTERED;
 #ifdef CONFIG_NETFILTER_DEBUG
-       /* Packet path as if nothing had happened. */
-       skb->nf_debug = olddebug;
+               /* Packet path as if nothing had happened. */
+               skb->nf_debug = olddebug;
 #endif
+       }
+
        return skb;
 }
 
index 46ca45f74d85b6e543304df6eb6f89b9db2098d4..bc59f7b3980585eacd0410a93de5722f8ccc299f 100644 (file)
@@ -256,6 +256,7 @@ static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
        struct list_head *e = v;
 
+       ++*pos;
        e = e->next;
 
        if (e == &ip_conntrack_expect_list)
index e5746b674413464f6919d3b8880c30dc18feea42..eda1fba431a415cef7f9533c8fdbcaca03f4f4a1 100644 (file)
@@ -3,6 +3,7 @@
  * communicating with userspace via netlink.
  *
  * (C) 2000-2002 James Morris <jmorris@intercode.com.au>
+ * (C) 2003-2005 Netfilter Core Team <coreteam@netfilter.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
@@ -17,6 +18,7 @@
  * 2005-01-10: Added /proc counter for dropped packets; fixed so
  *             packets aren't delivered to user space if they're going 
  *             to be dropped. 
+ * 2005-05-26: local_bh_{disable,enable} around nf_reinject (Harald Welte)
  *
  */
 #include <linux/module.h>
@@ -71,7 +73,15 @@ static DECLARE_MUTEX(ipqnl_sem);
 static void
 ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)
 {
+       /* TCP input path (and probably other bits) assume to be called
+        * from softirq context, not from syscall, like ipq_issue_verdict is
+        * called.  TCP input path deadlocks with locks taken from timer
+        * softirq, e.g.  We therefore emulate this by local_bh_disable() */
+
+       local_bh_disable();
        nf_reinject(entry->skb, entry->info, verdict);
+       local_bh_enable();
+
        kfree(entry);
 }
 
index 90a587cacaa4bbb6fabb04fae60745431031ff8c..0db405a869f2524c4768884580590a0a42c07a37 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: protocol.c,v 1.14 2001/05/18 02:25:49 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  * Fixes:
index 93624a32eb9ae385f8f3f7fcd53405be77194bed..5b1ec586bae631eed81a51eb0472e1c48a1613f2 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  * Fixes:
index 199311746932ee3952abebc5d008b8c9daf9c11b..a682d28e247bf07a091e38363e27bd6218dcbc0d 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Alan Cox, <gw4pts@gw4pts.ampr.org>
  *             Linus Torvalds, <Linus.Torvalds@helsinki.fi>
index 3aafb298c1c19691e26a2a599f53b8e7de4214f3..23068bddbf0bb6837edc01ff2f2f8cd34a12c357 100644 (file)
@@ -23,6 +23,7 @@ extern int sysctl_ip_nonlocal_bind;
 extern int sysctl_icmp_echo_ignore_all;
 extern int sysctl_icmp_echo_ignore_broadcasts;
 extern int sysctl_icmp_ignore_bogus_error_responses;
+extern int sysctl_icmp_errors_use_inbound_ifaddr;
 
 /* From ip_fragment.c */
 extern int sysctl_ipfrag_low_thresh;
@@ -395,6 +396,14 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
+       {
+               .ctl_name       = NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR,
+               .procname       = "icmp_errors_use_inbound_ifaddr",
+               .data           = &sysctl_icmp_errors_use_inbound_ifaddr,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
        {
                .ctl_name       = NET_IPV4_ROUTE,
                .procname       = "route",
index 5cff56af785512ec1971910200f4cda59e591f7e..0d9a4fd5f1a40cb568b691c19a571276b1c7a12d 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Mark Evans, <evansmp@uhura.aston.ac.uk>
  *             Corey Minyard <wf-rch!minyard@relay.EU.net>
@@ -2338,7 +2338,7 @@ void __init tcp_init(void)
                        (tcp_bhash_size * sizeof(struct tcp_bind_hashbucket));
                        order++)
                ;
-       if (order > 4) {
+       if (order >= 4) {
                sysctl_local_port_range[0] = 32768;
                sysctl_local_port_range[1] = 61000;
                sysctl_tcp_max_tw_buckets = 180000;
index 6984042c09272dcf57ed8ee2ca469f623335d729..5bad504630a3b641158af85f402cc91da27e4d06 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: tcp_input.c,v 1.243 2002/02/01 22:01:04 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Mark Evans, <evansmp@uhura.aston.ac.uk>
  *             Corey Minyard <wf-rch!minyard@relay.EU.net>
@@ -4355,16 +4355,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
                                        goto no_ack;
                        }
 
-                       if (eaten) {
-                               if (tcp_in_quickack_mode(tp)) {
-                                       tcp_send_ack(sk);
-                               } else {
-                                       tcp_send_delayed_ack(sk);
-                               }
-                       } else {
-                               __tcp_ack_snd_check(sk, 0);
-                       }
-
+                       __tcp_ack_snd_check(sk, 0);
 no_ack:
                        if (eaten)
                                __kfree_skb(skb);
index fd70509f0d53df8e39b63efbbbfeb360e34dbf2e..eea1a17a9ac2aaaf92abe4a3ab1f4496eef5a64e 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: tcp_minisocks.c,v 1.15 2002/02/01 22:01:04 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Mark Evans, <evansmp@uhura.aston.ac.uk>
  *             Corey Minyard <wf-rch!minyard@relay.EU.net>
index a12df6979ffd3cfb412973e277344ef8387f5b9f..fa24e7ae1f4062f666f5881d51ada562df286a56 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Mark Evans, <evansmp@uhura.aston.ac.uk>
  *             Corey Minyard <wf-rch!minyard@relay.EU.net>
index 85b279f1e935b0e2d5870485d1003287be8848d1..799ebe061e2ca51c1fdd0831e4f227211c2b71e3 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Mark Evans, <evansmp@uhura.aston.ac.uk>
  *             Corey Minyard <wf-rch!minyard@relay.EU.net>
index 8a213238f2873e8a985bf1c85b1f8f347d8f7d8c..7c24e64b443f80eae0c5a3663caff46f37011f69 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
  *             Alan Cox, <Alan.Cox@linux.org>
@@ -738,7 +738,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
                        unsigned long amount;
 
                        amount = 0;
-                       spin_lock_irq(&sk->sk_receive_queue.lock);
+                       spin_lock_bh(&sk->sk_receive_queue.lock);
                        skb = skb_peek(&sk->sk_receive_queue);
                        if (skb != NULL) {
                                /*
@@ -748,7 +748,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
                                 */
                                amount = skb->len - sizeof(struct udphdr);
                        }
-                       spin_unlock_irq(&sk->sk_receive_queue.lock);
+                       spin_unlock_bh(&sk->sk_receive_queue.lock);
                        return put_user(amount, (int __user *)arg);
                }
 
@@ -848,12 +848,12 @@ csum_copy_err:
        /* Clear queue. */
        if (flags&MSG_PEEK) {
                int clear = 0;
-               spin_lock_irq(&sk->sk_receive_queue.lock);
+               spin_lock_bh(&sk->sk_receive_queue.lock);
                if (skb == skb_peek(&sk->sk_receive_queue)) {
                        __skb_unlink(skb, &sk->sk_receive_queue);
                        clear = 1;
                }
-               spin_unlock_irq(&sk->sk_receive_queue.lock);
+               spin_unlock_bh(&sk->sk_receive_queue.lock);
                if (clear)
                        kfree_skb(skb);
        }
@@ -1334,7 +1334,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
                struct sk_buff_head *rcvq = &sk->sk_receive_queue;
                struct sk_buff *skb;
 
-               spin_lock_irq(&rcvq->lock);
+               spin_lock_bh(&rcvq->lock);
                while ((skb = skb_peek(rcvq)) != NULL) {
                        if (udp_checksum_complete(skb)) {
                                UDP_INC_STATS_BH(UDP_MIB_INERRORS);
@@ -1345,7 +1345,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
                                break;
                        }
                }
-               spin_unlock_irq(&rcvq->lock);
+               spin_unlock_bh(&rcvq->lock);
 
                /* nothing to see, move along */
                if (skb == NULL)
index 7744a2592693ff9562f14b4fa0b0cb614f71fdd7..2720899d516c677231bd76cbb736d40f030494f0 100644 (file)
@@ -372,6 +372,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
                ndev->regen_timer.data = (unsigned long) ndev;
                if ((dev->flags&IFF_LOOPBACK) ||
                    dev->type == ARPHRD_TUNNEL ||
+                   dev->type == ARPHRD_NONE ||
                    dev->type == ARPHRD_SIT) {
                        printk(KERN_INFO
                                "Disabled Privacy Extensions on device %p(%s)\n",
index 8e0f569b883e419acd311e79670d9ea916f0a034..ff3ec9822e36bb5e8c0100014c20bd8e3b14af50 100644 (file)
@@ -277,8 +277,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
 {
        struct inet6_dev *idev = NULL;
        struct ipv6hdr *hdr = skb->nh.ipv6h;
-       struct sock *sk = icmpv6_socket->sk;
-       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct sock *sk;
+       struct ipv6_pinfo *np;
        struct in6_addr *saddr = NULL;
        struct dst_entry *dst;
        struct icmp6hdr tmp_hdr;
@@ -358,6 +358,9 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        if (icmpv6_xmit_lock())
                return;
 
+       sk = icmpv6_socket->sk;
+       np = inet6_sk(sk);
+
        if (!icmpv6_xrlim_allow(sk, type, &fl))
                goto out;
 
@@ -423,9 +426,9 @@ out:
 
 static void icmpv6_echo_reply(struct sk_buff *skb)
 {
-       struct sock *sk = icmpv6_socket->sk;
+       struct sock *sk;
        struct inet6_dev *idev;
-       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct ipv6_pinfo *np;
        struct in6_addr *saddr = NULL;
        struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
        struct icmp6hdr tmp_hdr;
@@ -454,6 +457,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        if (icmpv6_xmit_lock())
                return;
 
+       sk = icmpv6_socket->sk;
+       np = inet6_sk(sk);
+
        if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
                fl.oif = np->mcast_oif;
 
index a93f6dc51979f84f61e5fc277a451d5fdcdb1032..0e5f7499debb81ce758d4e788d2182d07c5d2b53 100644 (file)
@@ -535,10 +535,12 @@ release:
                if (err)
                        goto done;
 
-               /* Do not check for fault */
-               if (!freq.flr_label)
-                       copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label,
-                                    &fl->label, sizeof(fl->label));
+               if (!freq.flr_label) {
+                       if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label,
+                                        &fl->label, sizeof(fl->label))) {
+                               /* Intentionally ignore fault. */
+                       }
+               }
 
                sfl1->fl = fl;
                sfl1->next = np->ipv6_fl_list;
index 0f0711417c9da71d7595e6019033b8976d479b03..b78a535868042381dbdd42454b7a1c63f16ddffa 100644 (file)
@@ -552,13 +552,17 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                            skb_headroom(frag) < hlen)
                            goto slow_path;
 
-                       /* Correct socket ownership. */
-                       if (frag->sk == NULL)
-                               goto slow_path;
-
                        /* Partially cloned skb? */
                        if (skb_shared(frag))
                                goto slow_path;
+
+                       BUG_ON(frag->sk);
+                       if (skb->sk) {
+                               sock_hold(skb->sk);
+                               frag->sk = skb->sk;
+                               frag->destructor = sock_wfree;
+                               skb->truesize -= frag->truesize;
+                       }
                }
 
                err = 0;
@@ -1116,12 +1120,10 @@ int ip6_push_pending_frames(struct sock *sk)
                tail_skb = &(tmp_skb->next);
                skb->len += tmp_skb->len;
                skb->data_len += tmp_skb->len;
-#if 0 /* Logically correct, but useless work, ip_fragment() will have to undo */
                skb->truesize += tmp_skb->truesize;
                __sock_put(tmp_skb->sk);
                tmp_skb->destructor = NULL;
                tmp_skb->sk = NULL;
-#endif
        }
 
        ipv6_addr_copy(final_dst, &fl->fl6_dst);
index 3b1c9fa184ae68e81cf3d3ac8fd3c543317a2602..ba3b0c267f759565c3eab810e3ed8bbbaaa91bfd 100644 (file)
@@ -882,6 +882,7 @@ ip6ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p)
        t->parms.hop_limit = p->hop_limit;
        t->parms.encap_limit = p->encap_limit;
        t->parms.flowinfo = p->flowinfo;
+       t->parms.link = p->link;
        ip6ip6_tnl_link_config(t);
        return 0;
 }
index 2f4c91ddc9a36c12d87cd57042a5d5d3644a1fd2..5ade5a5d199053dc20d349a8c8f313263a240260 100644 (file)
@@ -37,5 +37,4 @@ EXPORT_SYMBOL(in6_dev_finish_destroy);
 EXPORT_SYMBOL(xfrm6_rcv);
 #endif
 EXPORT_SYMBOL(rt6_lookup);
-EXPORT_SYMBOL(fl6_sock_lookup);
 EXPORT_SYMBOL(ipv6_push_nfrag_opts);
index 601a148f60f39af5255d651eab7a1f8d23a35a57..6b9867717d117a6686edb9424ddbfb6e7a21aa05 100644 (file)
@@ -84,6 +84,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
                mtu = IPV6_MIN_MTU;
 
        if (skb->len > mtu) {
+               skb->dev = dst->dev;
                icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
                ret = -EMSGSIZE;
        }
index 4429b1a1fe5fe2528318b7417e539279548d9988..cf1d91e74c82a3939ecd2f796ea385fb7eefcff1 100644 (file)
@@ -113,6 +113,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 
                xdst = (struct xfrm_dst *)dst1;
                xdst->route = &rt->u.dst;
+               if (rt->rt6i_node)
+                       xdst->route_cookie = rt->rt6i_node->fn_sernum;
 
                dst1->next = dst_prev;
                dst_prev = dst1;
@@ -137,6 +139,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 
        dst_prev->child = &rt->u.dst;
        dst->path = &rt->u.dst;
+       if (rt->rt6i_node)
+               ((struct xfrm_dst *)dst)->path_cookie = rt->rt6i_node->fn_sernum;
 
        *dst_p = dst;
        dst = dst_prev;
index d6ccd3239dcf5efa25c8c86906062032de8740f7..70543d89438b8d7b4007b26102e8b11ca484e6a3 100644 (file)
@@ -470,6 +470,7 @@ void irda_device_unregister_dongle(struct dongle_reg *dongle)
 }
 EXPORT_SYMBOL(irda_device_unregister_dongle);
 
+#ifdef CONFIG_ISA_DMA_API
 /*
  * Function setup_dma (idev, buffer, count, mode)
  *
@@ -492,3 +493,4 @@ void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode)
        release_dma_lock(flags);
 }
 EXPORT_SYMBOL(irda_setup_dma);
+#endif
index 4ee392066148e771925f601c5159f6d0960776af..e41ce458c2a99afd66c1f7255638c918b61c8fea 100644 (file)
@@ -49,6 +49,8 @@
 #include <linux/bitops.h>
 #include <linux/mm.h>
 #include <linux/types.h>
+#include <linux/audit.h>
+
 #include <net/sock.h>
 #include <net/scm.h>
 
@@ -733,11 +735,15 @@ static inline int do_one_broadcast(struct sock *sk,
 
        sock_hold(sk);
        if (p->skb2 == NULL) {
-               if (atomic_read(&p->skb->users) != 1) {
+               if (skb_shared(p->skb)) {
                        p->skb2 = skb_clone(p->skb, p->allocation);
                } else {
-                       p->skb2 = p->skb;
-                       atomic_inc(&p->skb->users);
+                       p->skb2 = skb_get(p->skb);
+                       /*
+                        * skb ownership may have been set when
+                        * delivered to a previous socket.
+                        */
+                       skb_orphan(p->skb2);
                }
        }
        if (p->skb2 == NULL) {
@@ -783,11 +789,12 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
        sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list)
                do_one_broadcast(sk, &info);
 
+       kfree_skb(skb);
+
        netlink_unlock_table();
 
        if (info.skb2)
                kfree_skb(info.skb2);
-       kfree_skb(skb);
 
        if (info.delivered) {
                if (info.congested && (allocation & __GFP_WAIT))
@@ -904,6 +911,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
        NETLINK_CB(skb).groups  = nlk->groups;
        NETLINK_CB(skb).dst_pid = dst_pid;
        NETLINK_CB(skb).dst_groups = dst_groups;
+       NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
        memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
 
        /* What can I do? Netlink is asynchronous, so that
index 64acea0adaaea6c31aa55a734dcc5263890644ba..0269616e75a16b946b0cf28fae20450831ca6f79 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Version:    $Id: af_packet.c,v 1.61 2002/02/08 03:57:19 davem Exp $
  *
- * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors:    Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *             Alan Cox, <gw4pts@gw4pts.ampr.org>
  *
index b0941186f867710a4f4ca4a9fdb486aa2d9b1455..b22c9beb604d78eb3dbf32809112802cb0b597ee 100644 (file)
@@ -405,7 +405,7 @@ config NET_EMATCH_STACK
        ---help---
          Size of the local stack variable used while evaluating the tree of
          ematches. Limits the depth of the tree, i.e. the number of
-         encapsulated precedences. Every level requires 4 bytes of addtional
+         encapsulated precedences. Every level requires 4 bytes of additional
          stack space.
 
 config NET_EMATCH_CMP
index cafcb084098d161d0d8d09ac64e8b067edb837f9..914c85ff8fe6c967bb30a1a99dba4ef58bd5c2da 100644 (file)
@@ -881,7 +881,7 @@ static int __init tc_action_init(void)
                link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action;
        }
 
-       printk("TC classifier action (bugs to netdev@oss.sgi.com cc "
+       printk("TC classifier action (bugs to netdev@vger.kernel.org cc "
               "hadi@cyberus.ca)\n");
        return 0;
 }
index 0d2d4415f334850b7006c110bc502736ae3f83b1..dfb300bb6baa067963a5e0e1e160087ae69d291d 100644 (file)
@@ -261,6 +261,9 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
        rta = (struct rtattr *) b;
        RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
 
+       if (f->res.classid)
+               RTA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid);
+
        if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 ||
            tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
                goto rtattr_failure;
index f1eeaf65cee5f833aabb493c53442ef80e983eef..48bb23c2a35a404aa5ef6e94a9160e2b346510ad 100644 (file)
@@ -32,7 +32,7 @@
  *           +-----------+                           +-----------+
  *                 |                                       |
  *                 ---> meta_ops[INT][INDEV](...)          |
- *                            |                            |
+ *                                                       |
  *                 -----------                             |
  *                 V                                       V
  *           +-----------+                           +-----------+
@@ -70,6 +70,7 @@
 #include <net/dst.h>
 #include <net/route.h>
 #include <net/pkt_cls.h>
+#include <net/sock.h>
 
 struct meta_obj
 {
@@ -283,6 +284,214 @@ META_COLLECTOR(int_rtiif)
                dst->value = ((struct rtable*) skb->dst)->fl.iif;
 }
 
+/**************************************************************************
+ * Socket Attributes
+ **************************************************************************/
+
+#define SKIP_NONLOCAL(skb)                     \
+       if (unlikely(skb->sk == NULL)) {        \
+               *err = -1;                      \
+               return;                         \
+       }
+
+META_COLLECTOR(int_sk_family)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_family;
+}
+
+META_COLLECTOR(int_sk_state)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_state;
+}
+
+META_COLLECTOR(int_sk_reuse)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_reuse;
+}
+
+META_COLLECTOR(int_sk_bound_if)
+{
+       SKIP_NONLOCAL(skb);
+       /* No error if bound_dev_if is 0, legal userspace check */
+       dst->value = skb->sk->sk_bound_dev_if;
+}
+
+META_COLLECTOR(var_sk_bound_if)
+{
+       SKIP_NONLOCAL(skb);
+
+        if (skb->sk->sk_bound_dev_if == 0) {
+               dst->value = (unsigned long) "any";
+               dst->len = 3;
+        } else  {
+               struct net_device *dev;
+               
+               dev = dev_get_by_index(skb->sk->sk_bound_dev_if);
+               *err = var_dev(dev, dst);
+               if (dev)
+                       dev_put(dev);
+        }
+}
+
+META_COLLECTOR(int_sk_refcnt)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = atomic_read(&skb->sk->sk_refcnt);
+}
+
+META_COLLECTOR(int_sk_rcvbuf)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_rcvbuf;
+}
+
+META_COLLECTOR(int_sk_shutdown)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_shutdown;
+}
+
+META_COLLECTOR(int_sk_proto)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_protocol;
+}
+
+META_COLLECTOR(int_sk_type)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_type;
+}
+
+META_COLLECTOR(int_sk_rmem_alloc)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = atomic_read(&skb->sk->sk_rmem_alloc);
+}
+
+META_COLLECTOR(int_sk_wmem_alloc)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = atomic_read(&skb->sk->sk_wmem_alloc);
+}
+
+META_COLLECTOR(int_sk_omem_alloc)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = atomic_read(&skb->sk->sk_omem_alloc);
+}
+
+META_COLLECTOR(int_sk_rcv_qlen)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_receive_queue.qlen;
+}
+
+META_COLLECTOR(int_sk_snd_qlen)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_write_queue.qlen;
+}
+
+META_COLLECTOR(int_sk_wmem_queued)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_wmem_queued;
+}
+
+META_COLLECTOR(int_sk_fwd_alloc)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_forward_alloc;
+}
+
+META_COLLECTOR(int_sk_sndbuf)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_sndbuf;
+}
+
+META_COLLECTOR(int_sk_alloc)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_allocation;
+}
+
+META_COLLECTOR(int_sk_route_caps)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_route_caps;
+}
+
+META_COLLECTOR(int_sk_hashent)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_hashent;
+}
+
+META_COLLECTOR(int_sk_lingertime)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_lingertime / HZ;
+}
+
+META_COLLECTOR(int_sk_err_qlen)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_error_queue.qlen;
+}
+
+META_COLLECTOR(int_sk_ack_bl)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_ack_backlog;
+}
+
+META_COLLECTOR(int_sk_max_ack_bl)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_max_ack_backlog;
+}
+
+META_COLLECTOR(int_sk_prio)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_priority;
+}
+
+META_COLLECTOR(int_sk_rcvlowat)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_rcvlowat;
+}
+
+META_COLLECTOR(int_sk_rcvtimeo)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_rcvtimeo / HZ;
+}
+
+META_COLLECTOR(int_sk_sndtimeo)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_sndtimeo / HZ;
+}
+
+META_COLLECTOR(int_sk_sendmsg_off)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_sndmsg_off;
+}
+
+META_COLLECTOR(int_sk_write_pend)
+{
+       SKIP_NONLOCAL(skb);
+       dst->value = skb->sk->sk_write_pending;
+}
+
 /**************************************************************************
  * Meta value collectors assignment table
  **************************************************************************/
@@ -293,41 +502,75 @@ struct meta_ops
                               struct meta_value *, struct meta_obj *, int *);
 };
 
+#define META_ID(name) TCF_META_ID_##name
+#define META_FUNC(name) { .get = meta_##name }
+
 /* Meta value operations table listing all meta value collectors and
  * assigns them to a type and meta id. */
 static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
        [TCF_META_TYPE_VAR] = {
-               [TCF_META_ID_DEV]       = { .get = meta_var_dev },
-               [TCF_META_ID_INDEV]     = { .get = meta_var_indev },
-               [TCF_META_ID_REALDEV]   = { .get = meta_var_realdev }
+               [META_ID(DEV)]                  = META_FUNC(var_dev),
+               [META_ID(INDEV)]                = META_FUNC(var_indev),
+               [META_ID(REALDEV)]              = META_FUNC(var_realdev),
+               [META_ID(SK_BOUND_IF)]          = META_FUNC(var_sk_bound_if),
        },
        [TCF_META_TYPE_INT] = {
-               [TCF_META_ID_RANDOM]    = { .get = meta_int_random },
-               [TCF_META_ID_LOADAVG_0] = { .get = meta_int_loadavg_0 },
-               [TCF_META_ID_LOADAVG_1] = { .get = meta_int_loadavg_1 },
-               [TCF_META_ID_LOADAVG_2] = { .get = meta_int_loadavg_2 },
-               [TCF_META_ID_DEV]       = { .get = meta_int_dev },
-               [TCF_META_ID_INDEV]     = { .get = meta_int_indev },
-               [TCF_META_ID_REALDEV]   = { .get = meta_int_realdev },
-               [TCF_META_ID_PRIORITY]  = { .get = meta_int_priority },
-               [TCF_META_ID_PROTOCOL]  = { .get = meta_int_protocol },
-               [TCF_META_ID_SECURITY]  = { .get = meta_int_security },
-               [TCF_META_ID_PKTTYPE]   = { .get = meta_int_pkttype },
-               [TCF_META_ID_PKTLEN]    = { .get = meta_int_pktlen },
-               [TCF_META_ID_DATALEN]   = { .get = meta_int_datalen },
-               [TCF_META_ID_MACLEN]    = { .get = meta_int_maclen },
+               [META_ID(RANDOM)]               = META_FUNC(int_random),
+               [META_ID(LOADAVG_0)]            = META_FUNC(int_loadavg_0),
+               [META_ID(LOADAVG_1)]            = META_FUNC(int_loadavg_1),
+               [META_ID(LOADAVG_2)]            = META_FUNC(int_loadavg_2),
+               [META_ID(DEV)]                  = META_FUNC(int_dev),
+               [META_ID(INDEV)]                = META_FUNC(int_indev),
+               [META_ID(REALDEV)]              = META_FUNC(int_realdev),
+               [META_ID(PRIORITY)]             = META_FUNC(int_priority),
+               [META_ID(PROTOCOL)]             = META_FUNC(int_protocol),
+               [META_ID(SECURITY)]             = META_FUNC(int_security),
+               [META_ID(PKTTYPE)]              = META_FUNC(int_pkttype),
+               [META_ID(PKTLEN)]               = META_FUNC(int_pktlen),
+               [META_ID(DATALEN)]              = META_FUNC(int_datalen),
+               [META_ID(MACLEN)]               = META_FUNC(int_maclen),
 #ifdef CONFIG_NETFILTER
-               [TCF_META_ID_NFMARK]    = { .get = meta_int_nfmark },
+               [META_ID(NFMARK)]               = META_FUNC(int_nfmark),
 #endif
-               [TCF_META_ID_TCINDEX]   = { .get = meta_int_tcindex },
+               [META_ID(TCINDEX)]              = META_FUNC(int_tcindex),
 #ifdef CONFIG_NET_CLS_ACT
-               [TCF_META_ID_TCVERDICT] = { .get = meta_int_tcverd },
-               [TCF_META_ID_TCCLASSID] = { .get = meta_int_tcclassid },
+               [META_ID(TCVERDICT)]            = META_FUNC(int_tcverd),
+               [META_ID(TCCLASSID)]            = META_FUNC(int_tcclassid),
 #endif
 #ifdef CONFIG_NET_CLS_ROUTE
-               [TCF_META_ID_RTCLASSID] = { .get = meta_int_rtclassid },
+               [META_ID(RTCLASSID)]            = META_FUNC(int_rtclassid),
 #endif
-               [TCF_META_ID_RTIIF]     = { .get = meta_int_rtiif }
+               [META_ID(RTIIF)]                = META_FUNC(int_rtiif),
+               [META_ID(SK_FAMILY)]            = META_FUNC(int_sk_family),
+               [META_ID(SK_STATE)]             = META_FUNC(int_sk_state),
+               [META_ID(SK_REUSE)]             = META_FUNC(int_sk_reuse),
+               [META_ID(SK_BOUND_IF)]          = META_FUNC(int_sk_bound_if),
+               [META_ID(SK_REFCNT)]            = META_FUNC(int_sk_refcnt),
+               [META_ID(SK_RCVBUF)]            = META_FUNC(int_sk_rcvbuf),
+               [META_ID(SK_SNDBUF)]            = META_FUNC(int_sk_sndbuf),
+               [META_ID(SK_SHUTDOWN)]          = META_FUNC(int_sk_shutdown),
+               [META_ID(SK_PROTO)]             = META_FUNC(int_sk_proto),
+               [META_ID(SK_TYPE)]              = META_FUNC(int_sk_type),
+               [META_ID(SK_RMEM_ALLOC)]        = META_FUNC(int_sk_rmem_alloc),
+               [META_ID(SK_WMEM_ALLOC)]        = META_FUNC(int_sk_wmem_alloc),
+               [META_ID(SK_OMEM_ALLOC)]        = META_FUNC(int_sk_omem_alloc),
+               [META_ID(SK_WMEM_QUEUED)]       = META_FUNC(int_sk_wmem_queued),
+               [META_ID(SK_RCV_QLEN)]          = META_FUNC(int_sk_rcv_qlen),
+               [META_ID(SK_SND_QLEN)]          = META_FUNC(int_sk_snd_qlen),
+               [META_ID(SK_ERR_QLEN)]          = META_FUNC(int_sk_err_qlen),
+               [META_ID(SK_FORWARD_ALLOCS)]    = META_FUNC(int_sk_fwd_alloc),
+               [META_ID(SK_ALLOCS)]            = META_FUNC(int_sk_alloc),
+               [META_ID(SK_ROUTE_CAPS)]        = META_FUNC(int_sk_route_caps),
+               [META_ID(SK_HASHENT)]           = META_FUNC(int_sk_hashent),
+               [META_ID(SK_LINGERTIME)]        = META_FUNC(int_sk_lingertime),
+               [META_ID(SK_ACK_BACKLOG)]       = META_FUNC(int_sk_ack_bl),
+               [META_ID(SK_MAX_ACK_BACKLOG)]   = META_FUNC(int_sk_max_ack_bl),
+               [META_ID(SK_PRIO)]              = META_FUNC(int_sk_prio),
+               [META_ID(SK_RCVLOWAT)]          = META_FUNC(int_sk_rcvlowat),
+               [META_ID(SK_RCVTIMEO)]          = META_FUNC(int_sk_rcvtimeo),
+               [META_ID(SK_SNDTIMEO)]          = META_FUNC(int_sk_sndtimeo),
+               [META_ID(SK_SENDMSG_OFF)]       = META_FUNC(int_sk_sendmsg_off),
+               [META_ID(SK_WRITE_PENDING)]     = META_FUNC(int_sk_write_pend),
        }
 };
 
@@ -396,9 +639,9 @@ static int meta_int_compare(struct meta_obj *a, struct meta_obj *b)
        /* Let gcc optimize it, the unlikely is not really based on
         * some numbers but jump free code for mismatches seems
         * more logical. */
-       if (unlikely(a == b))
+       if (unlikely(a->value == b->value))
                return 0;
-       else if (a < b)
+       else if (a->value < b->value)
                return -1;
        else
                return 1;
index 8a3db9d95bab238b99a7018a73b5e9ddbd189835..d8bd2a569c7ca6310f42af3c92510e75eca387cd 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/byteorder.h>
 
 
-#if 1 /* control */
+#if 0 /* control */
 #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
 #else
 #define DPRINTK(format,args...)
@@ -73,8 +73,13 @@ static int dsmark_graft(struct Qdisc *sch,unsigned long arg,
 
        DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new,
            old);
-       if (!new)
-               new = &noop_qdisc;
+
+       if (new == NULL) {
+               new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
+               if (new == NULL)
+                       new = &noop_qdisc;
+       }
+
        sch_tree_lock(sch);
        *old = xchg(&p->q,new);
        if (*old)
@@ -163,14 +168,15 @@ static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker)
                return;
        for (i = 0; i < p->indices; i++) {
                if (p->mask[i] == 0xff && !p->value[i])
-                       continue;
+                       goto ignore;
                if (walker->count >= walker->skip) {
                        if (walker->fn(sch, i+1, walker) < 0) {
                                walker->stop = 1;
                                break;
                        }
                }
-                walker->count++;
+ignore:                
+               walker->count++;
         }
 }
 
index e0c9fbe73b15cee32b44f4469e1ac5eeb9849267..bb9bf8d5003c62d79a4928df12acb59fc05adf67 100644 (file)
@@ -53,7 +53,6 @@
 
 struct netem_sched_data {
        struct Qdisc    *qdisc;
-       struct sk_buff_head delayed;
        struct timer_list timer;
 
        u32 latency;
@@ -63,11 +62,12 @@ struct netem_sched_data {
        u32 gap;
        u32 jitter;
        u32 duplicate;
+       u32 reorder;
 
        struct crndstate {
                unsigned long last;
                unsigned long rho;
-       } delay_cor, loss_cor, dup_cor;
+       } delay_cor, loss_cor, dup_cor, reorder_cor;
 
        struct disttable {
                u32  size;
@@ -137,122 +137,68 @@ static long tabledist(unsigned long mu, long sigma,
        return  x / NETEM_DIST_SCALE + (sigma / NETEM_DIST_SCALE) * t + mu;
 }
 
-/* Put skb in the private delayed queue. */
-static int netem_delay(struct Qdisc *sch, struct sk_buff *skb)
-{
-       struct netem_sched_data *q = qdisc_priv(sch);
-       psched_tdiff_t td;
-       psched_time_t now;
-       
-       PSCHED_GET_TIME(now);
-       td = tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist);
-       
-       /* Always queue at tail to keep packets in order */
-       if (likely(q->delayed.qlen < q->limit)) {
-               struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb;
-       
-               PSCHED_TADD2(now, td, cb->time_to_send);
-
-               pr_debug("netem_delay: skb=%p now=%llu tosend=%llu\n", skb, 
-                        now, cb->time_to_send);
-       
-               __skb_queue_tail(&q->delayed, skb);
-               return NET_XMIT_SUCCESS;
-       }
-
-       pr_debug("netem_delay: queue over limit %d\n", q->limit);
-       sch->qstats.overlimits++;
-       kfree_skb(skb);
-       return NET_XMIT_DROP;
-}
-
 /*
- *  Move a packet that is ready to send from the delay holding
- *  list to the underlying qdisc.
+ * Insert one skb into qdisc.
+ * Note: parent depends on return value to account for queue length.
+ *     NET_XMIT_DROP: queue length didn't change.
+ *      NET_XMIT_SUCCESS: one skb was queued.
  */
-static int netem_run(struct Qdisc *sch)
-{
-       struct netem_sched_data *q = qdisc_priv(sch);
-       struct sk_buff *skb;
-       psched_time_t now;
-
-       PSCHED_GET_TIME(now);
-
-       skb = skb_peek(&q->delayed);
-       if (skb) {
-               const struct netem_skb_cb *cb
-                       = (const struct netem_skb_cb *)skb->cb;
-               long delay 
-                       = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
-               pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay);
-
-               /* if more time remaining? */
-               if (delay > 0) {
-                       mod_timer(&q->timer, jiffies + delay);
-                       return 1;
-               }
-
-               __skb_unlink(skb, &q->delayed);
-               
-               if (q->qdisc->enqueue(skb, q->qdisc)) {
-                       sch->q.qlen--;
-                       sch->qstats.drops++;
-               } 
-       }
-
-       return 0;
-}
-
 static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
+       struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb;
+       struct sk_buff *skb2;
        int ret;
+       int count = 1;
 
        pr_debug("netem_enqueue skb=%p\n", skb);
 
+       /* Random duplication */
+       if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor))
+               ++count;
+
        /* Random packet drop 0 => none, ~0 => all */
-       if (q->loss && q->loss >= get_crandom(&q->loss_cor)) {
-               pr_debug("netem_enqueue: random loss\n");
+       if (q->loss && q->loss >= get_crandom(&q->loss_cor))
+               --count;
+
+       if (count == 0) {
                sch->qstats.drops++;
                kfree_skb(skb);
-               return 0;       /* lie about loss so TCP doesn't know */
+               return NET_XMIT_DROP;
        }
 
-       /* Random duplication */
-       if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) {
-               struct sk_buff *skb2;
-
-               skb2 = skb_clone(skb, GFP_ATOMIC);
-               if (skb2 && netem_delay(sch, skb2) == NET_XMIT_SUCCESS) {
-                       struct Qdisc *qp;
-
-                       /* Since one packet can generate two packets in the
-                        * queue, the parent's qlen accounting gets confused,
-                        * so fix it.
-                        */
-                       qp = qdisc_lookup(sch->dev, TC_H_MAJ(sch->parent));
-                       if (qp)
-                               qp->q.qlen++;
-
-                       sch->q.qlen++;
-                       sch->bstats.bytes += skb2->len;
-                       sch->bstats.packets++;
-               } else
-                       sch->qstats.drops++;
+       /*
+        * If we need to duplicate packet, then re-insert at top of the
+        * qdisc tree, since parent queuer expects that only one
+        * skb will be queued.
+        */
+       if (count > 1 && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
+               struct Qdisc *rootq = sch->dev->qdisc;
+               u32 dupsave = q->duplicate; /* prevent duplicating a dup... */
+               q->duplicate = 0;
+
+               rootq->enqueue(skb2, rootq);
+               q->duplicate = dupsave;
        }
 
-       /* If doing simple delay then gap == 0 so all packets
-        * go into the delayed holding queue
-        * otherwise if doing out of order only "1 out of gap"
-        * packets will be delayed.
-        */
-       if (q->counter < q->gap) {
+       if (q->gap == 0                 /* not doing reordering */
+           || q->counter < q->gap      /* inside last reordering gap */
+           || q->reorder < get_crandom(&q->reorder_cor)) {
+               psched_time_t now;
+               PSCHED_GET_TIME(now);
+               PSCHED_TADD2(now, tabledist(q->latency, q->jitter, 
+                                           &q->delay_cor, q->delay_dist),
+                            cb->time_to_send);
                ++q->counter;
                ret = q->qdisc->enqueue(skb, q->qdisc);
        } else {
+               /* 
+                * Do re-ordering by putting one out of N packets at the front
+                * of the queue.
+                */
+               PSCHED_GET_TIME(cb->time_to_send);
                q->counter = 0;
-               ret = netem_delay(sch, skb);
-               netem_run(sch);
+               ret = q->qdisc->ops->requeue(skb, q->qdisc);
        }
 
        if (likely(ret == NET_XMIT_SUCCESS)) {
@@ -296,22 +242,33 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
        struct sk_buff *skb;
-       int pending;
-
-       pending = netem_run(sch);
 
        skb = q->qdisc->dequeue(q->qdisc);
        if (skb) {
-               pr_debug("netem_dequeue: return skb=%p\n", skb);
-               sch->q.qlen--;
-               sch->flags &= ~TCQ_F_THROTTLED;
-       }
-       else if (pending) {
-               pr_debug("netem_dequeue: throttling\n");
+               const struct netem_skb_cb *cb
+                       = (const struct netem_skb_cb *)skb->cb;
+               psched_time_t now;
+               long delay;
+
+               /* if more time remaining? */
+               PSCHED_GET_TIME(now);
+               delay = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
+               pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay);
+               if (delay <= 0) {
+                       pr_debug("netem_dequeue: return skb=%p\n", skb);
+                       sch->q.qlen--;
+                       sch->flags &= ~TCQ_F_THROTTLED;
+                       return skb;
+               }
+
+               mod_timer(&q->timer, jiffies + delay);
                sch->flags |= TCQ_F_THROTTLED;
-       } 
 
-       return skb;
+               if (q->qdisc->ops->requeue(skb, q->qdisc) != 0)
+                       sch->qstats.drops++;
+       }
+
+       return NULL;
 }
 
 static void netem_watchdog(unsigned long arg)
@@ -328,8 +285,6 @@ static void netem_reset(struct Qdisc *sch)
        struct netem_sched_data *q = qdisc_priv(sch);
 
        qdisc_reset(q->qdisc);
-       skb_queue_purge(&q->delayed);
-
        sch->q.qlen = 0;
        sch->flags &= ~TCQ_F_THROTTLED;
        del_timer_sync(&q->timer);
@@ -397,6 +352,19 @@ static int get_correlation(struct Qdisc *sch, const struct rtattr *attr)
        return 0;
 }
 
+static int get_reorder(struct Qdisc *sch, const struct rtattr *attr)
+{
+       struct netem_sched_data *q = qdisc_priv(sch);
+       const struct tc_netem_reorder *r = RTA_DATA(attr);
+
+       if (RTA_PAYLOAD(attr) != sizeof(*r))
+               return -EINVAL;
+
+       q->reorder = r->probability;
+       init_crandom(&q->reorder_cor, r->correlation);
+       return 0;
+}
+
 static int netem_change(struct Qdisc *sch, struct rtattr *opt)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
@@ -417,9 +385,15 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt)
        q->jitter = qopt->jitter;
        q->limit = qopt->limit;
        q->gap = qopt->gap;
+       q->counter = 0;
        q->loss = qopt->loss;
        q->duplicate = qopt->duplicate;
 
+       /* for compatiablity with earlier versions.
+        * if gap is set, need to assume 100% probablity
+        */
+       q->reorder = ~0;
+
        /* Handle nested options after initial queue options.
         * Should have put all options in nested format but too late now.
         */ 
@@ -441,6 +415,11 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt)
                        if (ret)
                                return ret;
                }
+               if (tb[TCA_NETEM_REORDER-1]) {
+                       ret = get_reorder(sch, tb[TCA_NETEM_REORDER-1]);
+                       if (ret)
+                               return ret;
+               }
        }
 
 
@@ -455,11 +434,9 @@ static int netem_init(struct Qdisc *sch, struct rtattr *opt)
        if (!opt)
                return -EINVAL;
 
-       skb_queue_head_init(&q->delayed);
        init_timer(&q->timer);
        q->timer.function = netem_watchdog;
        q->timer.data = (unsigned long) sch;
-       q->counter = 0;
 
        q->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
        if (!q->qdisc) {
@@ -491,6 +468,7 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
        struct rtattr *rta = (struct rtattr *) b;
        struct tc_netem_qopt qopt;
        struct tc_netem_corr cor;
+       struct tc_netem_reorder reorder;
 
        qopt.latency = q->latency;
        qopt.jitter = q->jitter;
@@ -504,6 +482,11 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
        cor.loss_corr = q->loss_cor.rho;
        cor.dup_corr = q->dup_cor.rho;
        RTA_PUT(skb, TCA_NETEM_CORR, sizeof(cor), &cor);
+
+       reorder.probability = q->reorder;
+       reorder.correlation = q->reorder_cor.rho;
+       RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
+
        rta->rta_len = skb->tail - b;
 
        return skb->len;
index b719a77d66b47e3a553672c1d712e8e53b93e99b..fffc880a646d9a027a690bef279ff81e1e1ee162 100644 (file)
@@ -178,6 +178,37 @@ int sctp_rcv(struct sk_buff *skb)
 
        asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
 
+       if (!asoc)
+               ep = __sctp_rcv_lookup_endpoint(&dest);
+
+       /* Retrieve the common input handling substructure. */
+       rcvr = asoc ? &asoc->base : &ep->base;
+       sk = rcvr->sk;
+
+       /*
+        * If a frame arrives on an interface and the receiving socket is
+        * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB
+        */
+       if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb)))
+       {
+               sock_put(sk);
+               if (asoc) {
+                       sctp_association_put(asoc);
+                       asoc = NULL;
+               } else {
+                       sctp_endpoint_put(ep);
+                       ep = NULL;
+               }
+               sk = sctp_get_ctl_sock();
+               ep = sctp_sk(sk)->ep;
+               sctp_endpoint_hold(ep);
+               sock_hold(sk);
+               rcvr = &ep->base;
+       }
+
+       if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
+               goto discard_release;
+
        /*
         * RFC 2960, 8.4 - Handle "Out of the blue" Packets.
         * An SCTP packet is called an "out of the blue" (OOTB)
@@ -187,22 +218,12 @@ int sctp_rcv(struct sk_buff *skb)
         * packet belongs.
         */
        if (!asoc) {
-               ep = __sctp_rcv_lookup_endpoint(&dest);
                if (sctp_rcv_ootb(skb)) {
                        SCTP_INC_STATS_BH(SCTP_MIB_OUTOFBLUES);
                        goto discard_release;
                }
        }
 
-       /* Retrieve the common input handling substructure. */
-       rcvr = asoc ? &asoc->base : &ep->base;
-       sk = rcvr->sk;
-
-       if ((sk) && (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)) {
-               goto discard_release;
-       }
-
-
        /* SCTP seems to always need a timestamp right now (FIXME) */
        if (skb->stamp.tv_sec == 0) {
                do_gettimeofday(&skb->stamp);
@@ -265,13 +286,11 @@ discard_it:
 
 discard_release:
        /* Release any structures we may be holding. */
-       if (asoc) {
-               sock_put(asoc->base.sk);
+       sock_put(sk);
+       if (asoc)
                sctp_association_put(asoc);
-       } else {
-               sock_put(ep->base.sk);
+       else
                sctp_endpoint_put(ep);
-       }
 
        goto discard_it;
 }
index c9d9ea064734ad58e18c14e03055816b0c219dd7..c7e42d125b9cc544af46e640a725352c5ea1b6a1 100644 (file)
@@ -812,26 +812,23 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
        if (addr->sa.sa_family != AF_INET6)
                af = sctp_get_af_specific(addr->sa.sa_family);
        else {
-               struct sock *sk;
                int type = ipv6_addr_type(&addr->v6.sin6_addr);
-               sk = sctp_opt2sk(opt);
+               struct net_device *dev;
+
                if (type & IPV6_ADDR_LINKLOCAL) {
-                       /* Note: Behavior similar to af_inet6.c:
-                        *  1) Overrides previous bound_dev_if
-                        *  2) Destructive even if bind isn't successful.
-                        */
-
-                       if (addr->v6.sin6_scope_id)
-                               sk->sk_bound_dev_if = addr->v6.sin6_scope_id;
-                       if (!sk->sk_bound_dev_if)
+                       if (!addr->v6.sin6_scope_id)
+                               return 0;
+                       dev = dev_get_by_index(addr->v6.sin6_scope_id);
+                       if (!dev)
                                return 0;
+                       dev_put(dev);
                }
                af = opt->pf->af;
        }
        return af->available(addr, opt);
 }
 
-/* Verify that the provided sockaddr looks bindable.   Common verification,
+/* Verify that the provided sockaddr looks sendable.   Common verification,
  * has already been taken care of.
  */
 static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
@@ -842,19 +839,16 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
        if (addr->sa.sa_family != AF_INET6)
                af = sctp_get_af_specific(addr->sa.sa_family);
        else {
-               struct sock *sk;
                int type = ipv6_addr_type(&addr->v6.sin6_addr);
-               sk = sctp_opt2sk(opt);
+               struct net_device *dev;
+
                if (type & IPV6_ADDR_LINKLOCAL) {
-                       /* Note: Behavior similar to af_inet6.c:
-                        *  1) Overrides previous bound_dev_if
-                        *  2) Destructive even if bind isn't successful.
-                        */
-
-                       if (addr->v6.sin6_scope_id)
-                               sk->sk_bound_dev_if = addr->v6.sin6_scope_id;
-                       if (!sk->sk_bound_dev_if)
+                       if (!addr->v6.sin6_scope_id)
+                               return 0;
+                       dev = dev_get_by_index(addr->v6.sin6_scope_id);
+                       if (!dev)
                                return 0;
+                       dev_put(dev);
                }
                af = opt->pf->af;
        }
index e42fd8c2916b639fb1310dead4ef95a379936715..98d49ec9b74b93a4256f430e83838f2e911baf42 100644 (file)
@@ -132,14 +132,25 @@ void sctp_snmp_proc_exit(void)
 static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb)
 {
        struct list_head *pos;
+       struct sctp_association *asoc;
        struct sctp_sockaddr_entry *laddr;
-       union sctp_addr *addr;
+       struct sctp_transport *peer;
+       union sctp_addr *addr, *primary = NULL;
        struct sctp_af *af;
 
+       if (epb->type == SCTP_EP_TYPE_ASSOCIATION) {
+           asoc = sctp_assoc(epb);
+           peer = asoc->peer.primary_path;
+           primary = &peer->saddr;
+       }
+
        list_for_each(pos, &epb->bind_addr.address_list) {
                laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
                addr = (union sctp_addr *)&laddr->a;
                af = sctp_get_af_specific(addr->sa.sa_family);
+               if (primary && af->cmp_addr(addr, primary)) {
+                       seq_printf(seq, "*");
+               }
                af->seq_dump_addr(seq, addr);
        }
 }
@@ -149,17 +160,54 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa
 {
        struct list_head *pos;
        struct sctp_transport *transport;
-       union sctp_addr *addr;
+       union sctp_addr *addr, *primary;
        struct sctp_af *af;
 
+       primary = &(assoc->peer.primary_addr);
        list_for_each(pos, &assoc->peer.transport_addr_list) {
                transport = list_entry(pos, struct sctp_transport, transports);
                addr = (union sctp_addr *)&transport->ipaddr;
                af = sctp_get_af_specific(addr->sa.sa_family);
+               if (af->cmp_addr(addr, primary)) {
+                       seq_printf(seq, "*");
+               }
                af->seq_dump_addr(seq, addr);
        }
 }
 
+static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       if (*pos > sctp_ep_hashsize)
+               return NULL;
+
+       if (*pos < 0)
+               *pos = 0;
+
+       if (*pos == 0)
+               seq_printf(seq, " ENDPT     SOCK   STY SST HBKT LPORT   UID INODE LADDRS\n");
+
+       ++*pos;
+
+       return (void *)pos;
+}
+
+static void sctp_eps_seq_stop(struct seq_file *seq, void *v)
+{
+       return;
+}
+
+
+static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       if (*pos > sctp_ep_hashsize)
+               return NULL;
+
+       ++*pos;
+
+       return pos;
+}
+
+
 /* Display sctp endpoints (/proc/net/sctp/eps). */
 static int sctp_eps_seq_show(struct seq_file *seq, void *v)
 {
@@ -167,38 +215,50 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
        struct sctp_ep_common *epb;
        struct sctp_endpoint *ep;
        struct sock *sk;
-       int hash;
-
-       seq_printf(seq, " ENDPT     SOCK   STY SST HBKT LPORT LADDRS\n");
-       for (hash = 0; hash < sctp_ep_hashsize; hash++) {
-               head = &sctp_ep_hashtable[hash];
-               read_lock(&head->lock);
-               for (epb = head->chain; epb; epb = epb->next) {
-                       ep = sctp_ep(epb);
-                       sk = epb->sk;
-                       seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d ", ep, sk,
-                                  sctp_sk(sk)->type, sk->sk_state, hash,
-                                  epb->bind_addr.port);
-                       sctp_seq_dump_local_addrs(seq, epb);
-                       seq_printf(seq, "\n");
-               }
-               read_unlock(&head->lock);
+       int    hash = *(int *)v;
+
+       if (hash > sctp_ep_hashsize)
+               return -ENOMEM;
+
+       head = &sctp_ep_hashtable[hash-1];
+       sctp_local_bh_disable();
+       read_lock(&head->lock);
+       for (epb = head->chain; epb; epb = epb->next) {
+               ep = sctp_ep(epb);
+               sk = epb->sk;
+               seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk,
+                          sctp_sk(sk)->type, sk->sk_state, hash-1,
+                          epb->bind_addr.port,
+                          sock_i_uid(sk), sock_i_ino(sk));
+
+               sctp_seq_dump_local_addrs(seq, epb);
+               seq_printf(seq, "\n");
        }
+       read_unlock(&head->lock);
+       sctp_local_bh_enable();
 
        return 0;
 }
 
+static struct seq_operations sctp_eps_ops = {
+       .start = sctp_eps_seq_start,
+       .next  = sctp_eps_seq_next,
+       .stop  = sctp_eps_seq_stop,
+       .show  = sctp_eps_seq_show,
+};
+
+
 /* Initialize the seq file operations for 'eps' object. */
 static int sctp_eps_seq_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, sctp_eps_seq_show, NULL);
+       return seq_open(file, &sctp_eps_ops);
 }
 
 static struct file_operations sctp_eps_seq_fops = {
        .open    = sctp_eps_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = single_release,
+       .release = seq_release,
 };
 
 /* Set up the proc fs entry for 'eps' object. */
@@ -221,6 +281,40 @@ void sctp_eps_proc_exit(void)
        remove_proc_entry("eps", proc_net_sctp);
 }
 
+
+static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       if (*pos > sctp_assoc_hashsize)
+               return NULL;
+
+       if (*pos < 0)
+               *pos = 0;
+
+       if (*pos == 0)
+               seq_printf(seq, " ASSOC     SOCK   STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT "
+                               "RPORT LADDRS <-> RADDRS\n");
+
+       ++*pos;
+
+       return (void *)pos;
+}
+
+static void sctp_assocs_seq_stop(struct seq_file *seq, void *v)
+{
+       return;
+}
+
+
+static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       if (*pos > sctp_assoc_hashsize)
+               return NULL;
+
+       ++*pos;
+
+       return pos;
+}
+
 /* Display sctp associations (/proc/net/sctp/assocs). */
 static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
 {
@@ -228,43 +322,57 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
        struct sctp_ep_common *epb;
        struct sctp_association *assoc;
        struct sock *sk;
-       int hash;
-
-       seq_printf(seq, " ASSOC     SOCK   STY SST ST HBKT LPORT RPORT "
-                       "LADDRS <-> RADDRS\n");
-       for (hash = 0; hash < sctp_assoc_hashsize; hash++) {
-               head = &sctp_assoc_hashtable[hash];
-               read_lock(&head->lock);
-               for (epb = head->chain; epb; epb = epb->next) {
-                       assoc = sctp_assoc(epb);
-                       sk = epb->sk;
-                       seq_printf(seq,
-                                  "%8p %8p %-3d %-3d %-2d %-4d %-5d %-5d ",
-                                  assoc, sk, sctp_sk(sk)->type, sk->sk_state,
-                                  assoc->state, hash, epb->bind_addr.port,
-                                  assoc->peer.port);
-                       sctp_seq_dump_local_addrs(seq, epb);
-                       seq_printf(seq, "<-> ");
-                       sctp_seq_dump_remote_addrs(seq, assoc);
-                       seq_printf(seq, "\n");
-               }
-               read_unlock(&head->lock);
+       int    hash = *(int *)v;
+
+       if (hash > sctp_assoc_hashsize)
+               return -ENOMEM;
+
+       head = &sctp_assoc_hashtable[hash-1];
+       sctp_local_bh_disable();
+       read_lock(&head->lock);
+       for (epb = head->chain; epb; epb = epb->next) {
+               assoc = sctp_assoc(epb);
+               sk = epb->sk;
+               seq_printf(seq,
+                          "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ",
+                          assoc, sk, sctp_sk(sk)->type, sk->sk_state,
+                          assoc->state, hash-1, assoc->assoc_id,
+                          (sk->sk_rcvbuf - assoc->rwnd),
+                          assoc->sndbuf_used,
+                          sock_i_uid(sk), sock_i_ino(sk),
+                          epb->bind_addr.port,
+                          assoc->peer.port);
+
+               seq_printf(seq, " ");
+               sctp_seq_dump_local_addrs(seq, epb);
+               seq_printf(seq, "<-> ");
+               sctp_seq_dump_remote_addrs(seq, assoc);
+               seq_printf(seq, "\n");
        }
+       read_unlock(&head->lock);
+       sctp_local_bh_enable();
 
        return 0;
 }
 
+static struct seq_operations sctp_assoc_ops = {
+       .start = sctp_assocs_seq_start,
+       .next  = sctp_assocs_seq_next,
+       .stop  = sctp_assocs_seq_stop,
+       .show  = sctp_assocs_seq_show,
+};
+
 /* Initialize the seq file operations for 'assocs' object. */
 static int sctp_assocs_seq_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, sctp_assocs_seq_show, NULL);
+       return seq_open(file, &sctp_assoc_ops);
 }
 
 static struct file_operations sctp_assocs_seq_fops = {
        .open    = sctp_assocs_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = single_release,
+       .release = seq_release,
 };
 
 /* Set up the proc fs entry for 'assocs' object. */
index 2e1f9c3556f5922a9018c30055949f7a64f333be..5135e1a25d25c1413984520c7204f6df3d7d2df4 100644 (file)
@@ -378,10 +378,13 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
 {
        int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
 
-       /* FIXME: ip_nonlocal_bind sysctl support. */
 
-       if (addr->v4.sin_addr.s_addr != INADDR_ANY && ret != RTN_LOCAL)
+       if (addr->v4.sin_addr.s_addr != INADDR_ANY &&
+          ret != RTN_LOCAL &&
+          !sp->inet.freebind &&
+          !sysctl_ip_nonlocal_bind)
                return 0;
+
        return 1;
 }
 
index 0b338eca6dc0b1559e2392af2964f5d7fcfe1820..2a3c0e08a090eedf7c9a41d96cc7f263e002730b 100644 (file)
@@ -4686,6 +4686,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
        struct sctp_endpoint *newep = newsp->ep;
        struct sk_buff *skb, *tmp;
        struct sctp_ulpevent *event;
+       int flags = 0;
 
        /* Migrate socket buffer sizes and all the socket level options to the
         * new socket.
@@ -4707,6 +4708,17 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
        sctp_sk(newsk)->bind_hash = pp;
        inet_sk(newsk)->num = inet_sk(oldsk)->num;
 
+       /* Copy the bind_addr list from the original endpoint to the new
+        * endpoint so that we can handle restarts properly
+        */
+       if (assoc->peer.ipv4_address)
+               flags |= SCTP_ADDR4_PEERSUPP;
+       if (assoc->peer.ipv6_address)
+               flags |= SCTP_ADDR6_PEERSUPP;
+       sctp_bind_addr_copy(&newsp->ep->base.bind_addr,
+                            &oldsp->ep->base.bind_addr,
+                            SCTP_SCOPE_GLOBAL, GFP_KERNEL, flags);
+
        /* Move any messages in the old socket's receive queue that are for the
         * peeled off association to the new socket's receive queue.
         */
index 2cd44990d8d3daa6ce0495422549ea4745a56e1b..cec0cb38b9ce2454abf80b73b003b9ad7227415c 100644 (file)
@@ -4,7 +4,7 @@
  * Version:    @(#)socket.c    1.1.93  18/02/95
  *
  * Authors:    Orest Zborowski, <obz@Kodak.COM>
- *             Ross Biro, <bir7@leland.Stanford.Edu>
+ *             Ross Biro
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
  * Fixes:
index c478fc8db7768428580d23381856fa53fa31add2..c420eba4876b50fd853b816c78f04e5c5f127674 100644 (file)
@@ -770,33 +770,12 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                err = path_lookup(sunaddr->sun_path, LOOKUP_PARENT, &nd);
                if (err)
                        goto out_mknod_parent;
-               /*
-                * Yucky last component or no last component at all?
-                * (foo/., foo/.., /////)
-                */
-               err = -EEXIST;
-               if (nd.last_type != LAST_NORM)
-                       goto out_mknod;
-               /*
-                * Lock the directory.
-                */
-               down(&nd.dentry->d_inode->i_sem);
-               /*
-                * Do the final lookup.
-                */
-               dentry = lookup_hash(&nd.last, nd.dentry);
+
+               dentry = lookup_create(&nd, 0);
                err = PTR_ERR(dentry);
                if (IS_ERR(dentry))
                        goto out_mknod_unlock;
-               err = -ENOENT;
-               /*
-                * Special case - lookup gave negative, but... we had foo/bar/
-                * From the vfs_mknod() POV we just have a negative dentry -
-                * all is fine. Let's be bastards - you had / on the end, you've
-                * been asking for (non-existent) directory. -ENOENT for you.
-                */
-               if (nd.last.name[nd.last.len] && !dentry->d_inode)
-                       goto out_mknod_dput;
+
                /*
                 * All right, let's create it.
                 */
@@ -845,7 +824,6 @@ out_mknod_dput:
        dput(dentry);
 out_mknod_unlock:
        up(&nd.dentry->d_inode->i_sem);
-out_mknod:
        path_release(&nd);
 out_mknod_parent:
        if (err==-EEXIST)
index 080aae243ce091d134b837799c9ae7837bcdf0bb..2f4531fcaca23d43e8b49702b84dd5288acedf1e 100644 (file)
@@ -698,7 +698,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
                                return -ENOMEM;
 
                        if (skb1->sk)
-                               skb_set_owner_w(skb, skb1->sk);
+                               skb_set_owner_w(skb2, skb1->sk);
 
                        /* Looking around. Are we still alive?
                         * OK, link new skb, drop old one */
index 55ed979db1445f3d60b329ca1c35f4e3f7a8c37b..d07f5ce31824f0f887a737cd544c4dbbb035344b 100644 (file)
@@ -1136,7 +1136,7 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
        struct xfrm_dst *last;
        u32 mtu;
 
-       if (!dst_check(dst->path, 0) ||
+       if (!dst_check(dst->path, ((struct xfrm_dst *)dst)->path_cookie) ||
            (dst->dev && !netif_running(dst->dev)))
                return 0;
 
@@ -1156,7 +1156,7 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
                        xdst->child_mtu_cached = mtu;
                }
 
-               if (!dst_check(xdst->route, 0))
+               if (!dst_check(xdst->route, xdst->route_cookie))
                        return 0;
                mtu = dst_mtu(xdst->route);
                if (xdst->route_mtu_cached != mtu) {
index 5ddda2c98af9c8258562f926735fe16fa83025c2..97509011c274c7c0f1c698acc24fed817f861a2d 100644 (file)
@@ -34,14 +34,21 @@ static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
 {
        struct rtattr *rt = xfrma[type - 1];
        struct xfrm_algo *algp;
+       int len;
 
        if (!rt)
                return 0;
 
-       if ((rt->rta_len - sizeof(*rt)) < sizeof(*algp))
+       len = (rt->rta_len - sizeof(*rt)) - sizeof(*algp);
+       if (len < 0)
                return -EINVAL;
 
        algp = RTA_DATA(rt);
+
+       len -= (algp->alg_key_len + 7U) / 8; 
+       if (len < 0)
+               return -EINVAL;
+
        switch (type) {
        case XFRMA_ALG_AUTH:
                if (!algp->alg_key_len &&
@@ -162,6 +169,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
        struct rtattr *rta = u_arg;
        struct xfrm_algo *p, *ualg;
        struct xfrm_algo_desc *algo;
+       int len;
 
        if (!rta)
                return 0;
@@ -173,11 +181,12 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
                return -ENOSYS;
        *props = algo->desc.sadb_alg_id;
 
-       p = kmalloc(sizeof(*ualg) + ualg->alg_key_len, GFP_KERNEL);
+       len = sizeof(*ualg) + (ualg->alg_key_len + 7U) / 8;
+       p = kmalloc(len, GFP_KERNEL);
        if (!p)
                return -ENOMEM;
 
-       memcpy(p, ualg, sizeof(*ualg) + ualg->alg_key_len);
+       memcpy(p, ualg, len);
        *algpp = p;
        return 0;
 }
index fe11df83d1fc91b3e6de8a7bdc4a06e25f3d0e2f..d3d2e5341051809b01d13b75b352ed3d41f01d5c 100644 (file)
@@ -67,7 +67,7 @@ struct sym_entry {
 
 static struct sym_entry *table;
 static int size, cnt;
-static unsigned long long _stext, _etext, _sinittext, _einittext;
+static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext;
 static int all_symbols = 0;
 static char symbol_prefix_char = '\0';
 
@@ -139,6 +139,10 @@ read_symbol(FILE *in, struct sym_entry *s)
                _sinittext = s->addr;
        else if (strcmp(sym, "_einittext") == 0)
                _einittext = s->addr;
+       else if (strcmp(sym, "_sextratext") == 0)
+               _sextratext = s->addr;
+       else if (strcmp(sym, "_eextratext") == 0)
+               _eextratext = s->addr;
        else if (toupper(s->type) == 'A')
        {
                /* Keep these useful absolute symbols */
@@ -194,16 +198,18 @@ symbol_valid(struct sym_entry *s)
         * and inittext sections are discarded */
        if (!all_symbols) {
                if ((s->addr < _stext || s->addr > _etext)
-                   && (s->addr < _sinittext || s->addr > _einittext))
+                   && (s->addr < _sinittext || s->addr > _einittext)
+                   && (s->addr < _sextratext || s->addr > _eextratext))
                        return 0;
                /* Corner case.  Discard any symbols with the same value as
-                * _etext or _einittext, they can move between pass 1 and 2
-                * when the kallsyms data is added.  If these symbols move then
-                * they may get dropped in pass 2, which breaks the kallsyms
-                * rules.
+                * _etext _einittext or _eextratext; they can move between pass
+                * 1 and 2 when the kallsyms data are added.  If these symbols
+                * move then they may get dropped in pass 2, which breaks the
+                * kallsyms rules.
                 */
                if ((s->addr == _etext && strcmp(s->sym + offset, "_etext")) ||
-                   (s->addr == _einittext && strcmp(s->sym + offset, "_einittext")))
+                   (s->addr == _einittext && strcmp(s->sym + offset, "_einittext")) ||
+                   (s->addr == _eextratext && strcmp(s->sym + offset, "_eextratext")))
                        return 0;
        }
 
index 5a5ddc40f36ce0b5112fc16c8d341821650e5b38..09abb891d11f2eb5741b41a66307a13fe2d8a203 100644 (file)
@@ -2,7 +2,7 @@
 # Kernel configuration targets
 # These targets are used from top-level makefile
 
-.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig
+.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
 
 xconfig: $(obj)/qconf
        $< arch/$(ARCH)/Kconfig
@@ -23,6 +23,13 @@ oldconfig: $(obj)/conf
 silentoldconfig: $(obj)/conf
        $< -s arch/$(ARCH)/Kconfig
 
+update-po-config: $(obj)/kxgettext
+       xgettext --default-domain=linux \
+          --add-comments --keyword=_ --keyword=N_ \
+          --files-from=scripts/kconfig/POTFILES.in \
+       -o scripts/kconfig/linux.pot
+       scripts/kconfig/kxgettext arch/$(ARCH)/Kconfig >> scripts/kconfig/linux.pot
+
 .PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig
 
 randconfig: $(obj)/conf
@@ -72,9 +79,10 @@ help:
 #         Based on GTK which needs to be installed to compile it
 # object files used by all kconfig flavours
 
-hostprogs-y    := conf mconf qconf gconf
+hostprogs-y    := conf mconf qconf gconf kxgettext
 conf-objs      := conf.o  zconf.tab.o
 mconf-objs     := mconf.o zconf.tab.o
+kxgettext-objs := kxgettext.o zconf.tab.o
 
 ifeq ($(MAKECMDGOALS),xconfig)
        qconf-target := 1
@@ -107,7 +115,7 @@ HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
 HOSTCFLAGS_gconf.o     = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \
                           -D LKC_DIRECT_LINK
 
-$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o: $(obj)/zconf.tab.h
+$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o $(obj)/kxgettext: $(obj)/zconf.tab.h
 
 $(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped
 $(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped
diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in
new file mode 100644 (file)
index 0000000..cc94e46
--- /dev/null
@@ -0,0 +1,5 @@
+scripts/kconfig/mconf.c
+scripts/kconfig/conf.c
+scripts/kconfig/confdata.c
+scripts/kconfig/gconf.c
+scripts/kconfig/qconf.cc
index a494d1aeb9f9c62c80e5d66e9ced24dc6c45b434..70e7264c69420427097ca27788efd31053ad632d 100644 (file)
@@ -34,7 +34,7 @@ static int conf_cnt;
 static signed char line[128];
 static struct menu *rootEntry;
 
-static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
+static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
 
 static void strip(signed char *str)
 {
@@ -56,9 +56,9 @@ static void strip(signed char *str)
 static void check_stdin(void)
 {
        if (!valid_stdin && input_mode == ask_silent) {
-               printf("aborted!\n\n");
-               printf("Console input/output is redirected. ");
-               printf("Run 'make oldconfig' to update configuration.\n\n");
+               printf(_("aborted!\n\n"));
+               printf(_("Console input/output is redirected. "));
+               printf(_("Run 'make oldconfig' to update configuration.\n\n"));
                exit(1);
        }
 }
@@ -470,7 +470,7 @@ static void check_conf(struct menu *menu)
        if (sym) {
                if (sym_is_changable(sym) && !sym_has_value(sym)) {
                        if (!conf_cnt++)
-                               printf("*\n* Restart config...\n*\n");
+                               printf(_("*\n* Restart config...\n*\n"));
                        rootEntry = menu_get_parent_menu(menu);
                        conf(rootEntry);
                }
@@ -504,7 +504,7 @@ int main(int ac, char **av)
                        input_mode = set_default;
                        defconfig_file = av[i++];
                        if (!defconfig_file) {
-                               printf("%s: No default config file specified\n",
+                               printf(_("%s: No default config file specified\n"),
                                        av[0]);
                                exit(1);
                        }
@@ -530,7 +530,7 @@ int main(int ac, char **av)
        }
        name = av[i];
        if (!name) {
-               printf("%s: Kconfig file missing\n", av[0]);
+               printf(_("%s: Kconfig file missing\n"), av[0]);
        }
        conf_parse(name);
        //zconfdump(stdout);
@@ -547,12 +547,12 @@ int main(int ac, char **av)
                break;
        case ask_silent:
                if (stat(".config", &tmpstat)) {
-                       printf("***\n"
+                       printf(_("***\n"
                                "*** You have not yet configured your kernel!\n"
                                "***\n"
                                "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
                                "*** \"make menuconfig\" or \"make xconfig\").\n"
-                               "***\n");
+                               "***\n"));
                        exit(1);
                }
        case ask_all:
@@ -576,7 +576,7 @@ int main(int ac, char **av)
                check_conf(&rootmenu);
        } while (conf_cnt);
        if (conf_write(NULL)) {
-               fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n");
+               fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
                return 1;
        }
        return 0;
index 1e82ae390a69d7d62be88338ac805b59609a117d..2755c459d780b48e1c067be5d81a14528c2e3b90 100644 (file)
@@ -88,9 +88,9 @@ int conf_read(const char *name)
                        name = conf_expand_value(name);
                        in = zconf_fopen(name);
                        if (in) {
-                               printf("#\n"
-                                      "# using defaults found in %s\n"
-                                      "#\n", name);
+                               printf(_("#\n"
+                                        "# using defaults found in %s\n"
+                                        "#\n"), name);
                                break;
                        }
                }
@@ -312,11 +312,11 @@ int conf_write(const char *name)
        if (env && *env)
                use_timestamp = 0;
 
-       fprintf(out, "#\n"
-                    "# Automatically generated make config: don't edit\n"
-                    "# Linux kernel version: %s\n"
-                    "%s%s"
-                    "#\n",
+       fprintf(out, _("#\n"
+                      "# Automatically generated make config: don't edit\n"
+                      "# Linux kernel version: %s\n"
+                      "%s%s"
+                      "#\n"),
                     sym_get_string_value(sym),
                     use_timestamp ? "# " : "",
                     use_timestamp ? ctime(&now) : "");
index 6fdbe6e3ce0dc6a0319c302bfb326d7901df197f..ad6b120438748e1604c6c2115e4d08218538a55d 100644 (file)
@@ -41,7 +41,7 @@ static gboolean resizeable = FALSE;
 static gboolean config_changed = FALSE;
 
 static char nohelp_text[] =
-    "Sorry, no help available for this option yet.\n";
+    N_("Sorry, no help available for this option yet.\n");
 
 GtkWidget *main_wnd = NULL;
 GtkWidget *tree1_w = NULL;     // left  frame
@@ -193,7 +193,7 @@ void init_main_window(const gchar * glade_file)
 
        xml = glade_xml_new(glade_file, "window1", NULL);
        if (!xml)
-               g_error("GUI loading failed !\n");
+               g_error(_("GUI loading failed !\n"));
        glade_xml_signal_autoconnect(xml);
 
        main_wnd = glade_xml_get_widget(xml, "window1");
@@ -275,7 +275,7 @@ void init_main_window(const gchar * glade_file)
                                          /*"style", PANGO_STYLE_OBLIQUE, */
                                          NULL);
 
-       sprintf(title, "Linux Kernel v%s Configuration",
+       sprintf(title, _("Linux Kernel v%s Configuration"),
                getenv("KERNELRELEASE"));
        gtk_window_set_title(GTK_WINDOW(main_wnd), title);
 
@@ -325,7 +325,7 @@ void init_left_tree(void)
        
        column = gtk_tree_view_column_new();
        gtk_tree_view_append_column(view, column);
-       gtk_tree_view_column_set_title(column, "Options");
+       gtk_tree_view_column_set_title(column, _("Options"));
 
        renderer = gtk_cell_renderer_toggle_new();
        gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -370,7 +370,7 @@ void init_right_tree(void)
 
        column = gtk_tree_view_column_new();
        gtk_tree_view_append_column(view, column);
-       gtk_tree_view_column_set_title(column, "Options");
+       gtk_tree_view_column_set_title(column, _("Options"));
 
        renderer = gtk_cell_renderer_pixbuf_new();
        gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -401,7 +401,7 @@ void init_right_tree(void)
 
        renderer = gtk_cell_renderer_text_new();
        gtk_tree_view_insert_column_with_attributes(view, -1,
-                                                   "Name", renderer,
+                                                   _("Name"), renderer,
                                                    "text", COL_NAME,
                                                    "foreground-gdk",
                                                    COL_COLOR, NULL);
@@ -425,7 +425,7 @@ void init_right_tree(void)
                                                    COL_COLOR, NULL);
        renderer = gtk_cell_renderer_text_new();
        gtk_tree_view_insert_column_with_attributes(view, -1,
-                                                   "Value", renderer,
+                                                   _("Value"), renderer,
                                                    "text", COL_VALUE,
                                                    "editable",
                                                    COL_EDIT,
@@ -466,15 +466,15 @@ static void text_insert_help(struct menu *menu)
        GtkTextIter start, end;
        const char *prompt = menu_get_prompt(menu);
        gchar *name;
-       const char *help = nohelp_text;
+       const char *help = _(nohelp_text);
 
        if (!menu->sym)
                help = "";
        else if (menu->sym->help)
-               help = menu->sym->help;
+               help = _(menu->sym->help);
 
        if (menu->sym && menu->sym->name)
-               name = g_strdup_printf(menu->sym->name);
+               name = g_strdup_printf(_(menu->sym->name));
        else
                name = g_strdup("");
 
@@ -530,7 +530,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
        if (config_changed == FALSE)
                return FALSE;
 
-       dialog = gtk_dialog_new_with_buttons("Warning !",
+       dialog = gtk_dialog_new_with_buttons(_("Warning !"),
                                             GTK_WINDOW(main_wnd),
                                             (GtkDialogFlags)
                                             (GTK_DIALOG_MODAL |
@@ -544,7 +544,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
        gtk_dialog_set_default_response(GTK_DIALOG(dialog),
                                        GTK_RESPONSE_CANCEL);
 
-       label = gtk_label_new("\nSave configuration ?\n");
+       label = gtk_label_new(_("\nSave configuration ?\n"));
        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
        gtk_widget_show(label);
 
@@ -604,7 +604,7 @@ load_filename(GtkFileSelection * file_selector, gpointer user_data)
                                             (user_data));
 
        if (conf_read(fn))
-               text_insert_msg("Error", "Unable to load configuration !");
+               text_insert_msg(_("Error"), _("Unable to load configuration !"));
        else
                display_tree(&rootmenu);
 }
@@ -613,7 +613,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
        GtkWidget *fs;
 
-       fs = gtk_file_selection_new("Load file...");
+       fs = gtk_file_selection_new(_("Load file..."));
        g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
                         "clicked",
                         G_CALLBACK(load_filename), (gpointer) fs);
@@ -632,7 +632,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
 void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
        if (conf_write(NULL))
-               text_insert_msg("Error", "Unable to save configuration !");
+               text_insert_msg(_("Error"), _("Unable to save configuration !"));
 
        config_changed = FALSE;
 }
@@ -647,7 +647,7 @@ store_filename(GtkFileSelection * file_selector, gpointer user_data)
                                             (user_data));
 
        if (conf_write(fn))
-               text_insert_msg("Error", "Unable to save configuration !");
+               text_insert_msg(_("Error"), _("Unable to save configuration !"));
 
        gtk_widget_destroy(GTK_WIDGET(user_data));
 }
@@ -656,7 +656,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
        GtkWidget *fs;
 
-       fs = gtk_file_selection_new("Save file as...");
+       fs = gtk_file_selection_new(_("Save file as..."));
        g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
                         "clicked",
                         G_CALLBACK(store_filename), (gpointer) fs);
@@ -740,7 +740,7 @@ on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
 void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
        GtkWidget *dialog;
-       const gchar *intro_text =
+       const gchar *intro_text = _(
            "Welcome to gkc, the GTK+ graphical kernel configuration tool\n"
            "for Linux.\n"
            "For each option, a blank box indicates the feature is disabled, a\n"
@@ -756,7 +756,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
            "option.\n"
            "\n"
            "Toggling Show Debug Info under the Options menu will show \n"
-           "the dependencies, which you can then match by examining other options.";
+           "the dependencies, which you can then match by examining other options.");
 
        dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
                                        GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -773,8 +773,8 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
        GtkWidget *dialog;
        const gchar *about_text =
-           "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
-           "Based on the source code from Roman Zippel.\n";
+           _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
+             "Based on the source code from Roman Zippel.\n");
 
        dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
                                        GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -791,9 +791,9 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
        GtkWidget *dialog;
        const gchar *license_text =
-           "gkc is released under the terms of the GNU GPL v2.\n"
-           "For more information, please see the source code or\n"
-           "visit http://www.fsf.org/licenses/licenses.html\n";
+           _("gkc is released under the terms of the GNU GPL v2.\n"
+             "For more information, please see the source code or\n"
+             "visit http://www.fsf.org/licenses/licenses.html\n");
 
        dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
                                        GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -1579,6 +1579,10 @@ int main(int ac, char *av[])
        kconfig_load();
 #endif
 
+       bindtextdomain(PACKAGE, LOCALEDIR);
+       bind_textdomain_codeset(PACKAGE, "UTF-8");
+       textdomain(PACKAGE);
+
        /* GTK stuffs */
        gtk_set_locale();
        gtk_init(&ac, &av);
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
new file mode 100644 (file)
index 0000000..1c88d7c
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
+ *
+ * Released under the terms of the GNU GPL v2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+static char *escape(const char* text, char *bf, int len)
+{
+       char *bfp = bf;
+       int multiline = strchr(text, '\n') != NULL;
+
+       *bfp++ = '"';
+       --len;
+
+       if (multiline) {
+               *bfp++ = '"';
+               *bfp++ = '\n';
+               *bfp++ = '"';
+               len -= 3;
+       }
+
+       while (*text != '\0' && len > 1) {
+               if (*text == '"')
+                       *bfp++ = '\\';
+               else if (*text == '\n') {
+                       *bfp++ = '\\';
+                       *bfp++ = 'n';
+                       *bfp++ = '"';
+                       *bfp++ = '\n';
+                       *bfp++ = '"';
+                       len -= 5;
+                       ++text;
+                       goto next;
+               }
+               *bfp++ = *text++;
+next:
+               --len;
+       }
+
+       if (multiline)
+               bfp -= 3;
+
+       *bfp++ = '"';
+       *bfp = '\0';
+
+       return bf;
+}
+
+struct file_line {
+       struct file_line *next;
+       char*            file;
+       int              lineno;
+};
+
+static struct file_line *file_line__new(char *file, int lineno)
+{
+       struct file_line *self = malloc(sizeof(*self));
+
+       if (self == NULL)
+               goto out;
+
+       self->file   = file;
+       self->lineno = lineno;
+       self->next   = NULL;
+out:
+       return self;
+}
+
+struct message {
+       const char       *msg;
+       const char       *option;
+       struct message   *next;
+       struct file_line *files;
+};
+
+static struct message *message__list;
+
+static struct message *message__new(const char *msg, char *option, char *file, int lineno)
+{
+       struct message *self = malloc(sizeof(*self));
+
+       if (self == NULL)
+               goto out;
+
+       self->files = file_line__new(file, lineno);
+       if (self->files == NULL)
+               goto out_fail;
+
+       self->msg = strdup(msg);
+       if (self->msg == NULL)
+               goto out_fail_msg;
+
+       self->option = option;
+       self->next = NULL;
+out:
+       return self;
+out_fail_msg:
+       free(self->files);
+out_fail:
+       free(self);
+       self = NULL;
+       goto out;
+}
+
+static struct message *mesage__find(const char *msg)
+{
+       struct message *m = message__list;
+
+       while (m != NULL) {
+               if (strcmp(m->msg, msg) == 0)
+                       break;
+               m = m->next;
+       }
+
+       return m;
+}
+
+static int message__add_file_line(struct message *self, char *file, int lineno)
+{
+       int rc = -1;
+       struct file_line *fl = file_line__new(file, lineno);
+
+       if (fl == NULL)
+               goto out;
+
+       fl->next    = self->files;
+       self->files = fl;
+       rc = 0;
+out:
+       return rc;
+}
+
+static int message__add(const char *msg, char *option, char *file, int lineno)
+{
+       int rc = 0;
+       char bf[16384];
+       char *escaped = escape(msg, bf, sizeof(bf));
+       struct message *m = mesage__find(escaped);
+
+       if (m != NULL)
+               rc = message__add_file_line(m, file, lineno);
+       else {
+               m = message__new(escaped, option, file, lineno);
+
+               if (m != NULL) {
+                       m->next       = message__list;
+                       message__list = m;
+               } else
+                       rc = -1;
+       }
+       return rc;
+}
+
+void menu_build_message_list(struct menu *menu)
+{
+       struct menu *child;
+
+       message__add(menu_get_prompt(menu), NULL,
+                    menu->file == NULL ? "Root Menu" : menu->file->name,
+                    menu->lineno);
+
+       if (menu->sym != NULL && menu->sym->help != NULL)
+               message__add(menu->sym->help, menu->sym->name,
+                            menu->file == NULL ? "Root Menu" : menu->file->name,
+                            menu->lineno);
+
+       for (child = menu->list; child != NULL; child = child->next)
+               if (child->prompt != NULL)
+                       menu_build_message_list(child);
+}
+
+static void message__print_file_lineno(struct message *self)
+{
+       struct file_line *fl = self->files;
+
+       printf("\n#: %s:%d", fl->file, fl->lineno);
+       fl = fl->next;
+
+       while (fl != NULL) {
+               printf(", %s:%d", fl->file, fl->lineno);
+               fl = fl->next;
+       }
+
+       if (self->option != NULL)
+               printf(", %s:00000", self->option);
+
+       putchar('\n');
+}
+
+static void message__print_gettext_msgid_msgstr(struct message *self)
+{
+       message__print_file_lineno(self);
+
+       printf("msgid %s\n"
+              "msgstr \"\"\n", self->msg);
+}
+
+void menu__xgettext(void)
+{
+       struct message *m = message__list;
+
+       while (m != NULL) {
+               message__print_gettext_msgid_msgstr(m);
+               m = m->next;
+       }
+}
+
+int main(int ac, char **av)
+{
+       conf_parse(av[1]);
+
+       menu_build_message_list(menu_get_root_menu(NULL));
+       menu__xgettext();
+       return 0;
+}
index b8a67fc9d6476d4b4b812f4226f7376f4c08584d..8b84c42b49b5bdd0e191b044434c488e5e9af064 100644 (file)
@@ -8,6 +8,8 @@
 
 #include "expr.h"
 
+#include <libintl.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -23,6 +25,12 @@ extern "C" {
 
 #define SRCTREE "srctree"
 
+#define PACKAGE "linux"
+#define LOCALEDIR "/usr/share/locale"
+
+#define _(text) gettext(text)
+#define N_(text) (text)
+
 int zconfparse(void);
 void zconfdump(FILE *out);
 
index 730d316fe7fe8949788966015143ca0d2dcfdcca..e5db10ca956420f8a3ba8159597f3c537ef963f5 100644 (file)
@@ -4,6 +4,8 @@
  *
  * Introduced single menu mode (show all sub-menus in one large tree).
  * 2002-11-06 Petr Baudis <pasky@ucw.cz>
+ *
+ * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  */
 
 #include <sys/ioctl.h>
@@ -23,7 +25,7 @@
 #include "lkc.h"
 
 static char menu_backtitle[128];
-static const char mconf_readme[] =
+static const char mconf_readme[] = N_(
 "Overview\n"
 "--------\n"
 "Some kernel features may be built directly into the kernel.\n"
@@ -156,39 +158,39 @@ static const char mconf_readme[] =
 "\n"
 "Note that this mode can eventually be a little more CPU expensive\n"
 "(especially with a larger number of unrolled categories) than the\n"
-"default mode.\n",
-menu_instructions[] =
+"default mode.\n"),
+menu_instructions[] = N_(
        "Arrow keys navigate the menu.  "
        "<Enter> selects submenus --->.  "
        "Highlighted letters are hotkeys.  "
        "Pressing <Y> includes, <N> excludes, <M> modularizes features.  "
        "Press <Esc><Esc> to exit, <?> for Help, </> for Search.  "
-       "Legend: [*] built-in  [ ] excluded  <M> module  < > module capable",
-radiolist_instructions[] =
+       "Legend: [*] built-in  [ ] excluded  <M> module  < > module capable"),
+radiolist_instructions[] = N_(
        "Use the arrow keys to navigate this window or "
        "press the hotkey of the item you wish to select "
        "followed by the <SPACE BAR>. "
-       "Press <?> for additional information about this option.",
-inputbox_instructions_int[] =
+       "Press <?> for additional information about this option."),
+inputbox_instructions_int[] = N_(
        "Please enter a decimal value. "
        "Fractions will not be accepted.  "
-       "Use the <TAB> key to move from the input field to the buttons below it.",
-inputbox_instructions_hex[] =
+       "Use the <TAB> key to move from the input field to the buttons below it."),
+inputbox_instructions_hex[] = N_(
        "Please enter a hexadecimal value. "
-       "Use the <TAB> key to move from the input field to the buttons below it.",
-inputbox_instructions_string[] =
+       "Use the <TAB> key to move from the input field to the buttons below it."),
+inputbox_instructions_string[] = N_(
        "Please enter a string value. "
-       "Use the <TAB> key to move from the input field to the buttons below it.",
-setmod_text[] =
+       "Use the <TAB> key to move from the input field to the buttons below it."),
+setmod_text[] = N_(
        "This feature depends on another which has been configured as a module.\n"
-       "As a result, this feature will be built as a module.",
-nohelp_text[] =
-       "There is no help available for this kernel option.\n",
-load_config_text[] =
+       "As a result, this feature will be built as a module."),
+nohelp_text[] = N_(
+       "There is no help available for this kernel option.\n"),
+load_config_text[] = N_(
        "Enter the name of the configuration file you wish to load.  "
        "Accept the name shown to restore the configuration you "
-       "last retrieved.  Leave blank to abort.",
-load_config_help[] =
+       "last retrieved.  Leave blank to abort."),
+load_config_help[] = N_(
        "\n"
        "For various reasons, one may wish to keep several different kernel\n"
        "configurations available on a single machine.\n"
@@ -198,11 +200,11 @@ load_config_help[] =
        "to modify that configuration.\n"
        "\n"
        "If you are uncertain, then you have probably never used alternate\n"
-       "configuration files.  You should therefor leave this blank to abort.\n",
-save_config_text[] =
+       "configuration files.  You should therefor leave this blank to abort.\n"),
+save_config_text[] = N_(
        "Enter a filename to which this configuration should be saved "
-       "as an alternate.  Leave blank to abort.",
-save_config_help[] =
+       "as an alternate.  Leave blank to abort."),
+save_config_help[] = N_(
        "\n"
        "For various reasons, one may wish to keep different kernel\n"
        "configurations available on a single machine.\n"
@@ -212,8 +214,8 @@ save_config_help[] =
        "configuration options you have selected at that time.\n"
        "\n"
        "If you are uncertain what all this means then you should probably\n"
-       "leave this blank.\n",
-search_help[] =
+       "leave this blank.\n"),
+search_help[] = N_(
        "\n"
        "Search for CONFIG_ symbols and display their relations.\n"
        "Example: search for \"^FOO\"\n"
@@ -250,7 +252,7 @@ search_help[] =
        "Examples: USB  => find all CONFIG_ symbols containing USB\n"
        "          ^USB => find all CONFIG_ symbols starting with USB\n"
        "          USB$ => find all CONFIG_ symbols ending with USB\n"
-       "\n";
+       "\n");
 
 static signed char buf[4096], *bufptr = buf;
 static signed char input_buf[4096];
@@ -305,8 +307,8 @@ static void init_wsize(void)
        }
 
        if (rows < 19 || cols < 80) {
-               fprintf(stderr, "Your display is too small to run Menuconfig!\n");
-               fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
+               fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
+               fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
                exit(1);
        }
 
@@ -526,9 +528,9 @@ static void search_conf(void)
 again:
        cprint_init();
        cprint("--title");
-       cprint("Search Configuration Parameter");
+       cprint(_("Search Configuration Parameter"));
        cprint("--inputbox");
-       cprint("Enter Keyword");
+       cprint(_("Enter Keyword"));
        cprint("10");
        cprint("75");
        cprint("");
@@ -539,7 +541,7 @@ again:
        case 0:
                break;
        case 1:
-               show_helptext("Search Configuration", search_help);
+               show_helptext(_("Search Configuration"), search_help);
                goto again;
        default:
                return;
@@ -548,7 +550,7 @@ again:
        sym_arr = sym_re_search(input_buf);
        res = get_relations_str(sym_arr);
        free(sym_arr);
-       show_textbox("Search Results", str_get(&res), 0, 0);
+       show_textbox(_("Search Results"), str_get(&res), 0, 0);
        str_free(&res);
 }
 
@@ -721,9 +723,9 @@ static void conf(struct menu *menu)
        while (1) {
                cprint_init();
                cprint("--title");
-               cprint("%s", prompt ? prompt : "Main Menu");
+               cprint("%s", prompt ? prompt : _("Main Menu"));
                cprint("--menu");
-               cprint(menu_instructions);
+               cprint(_(menu_instructions));
                cprint("%d", rows);
                cprint("%d", cols);
                cprint("%d", rows - 10);
@@ -736,9 +738,9 @@ static void conf(struct menu *menu)
                        cprint(":");
                        cprint("--- ");
                        cprint("L");
-                       cprint("    Load an Alternate Configuration File");
+                       cprint(_("    Load an Alternate Configuration File"));
                        cprint("S");
-                       cprint("    Save Configuration to an Alternate File");
+                       cprint(_("    Save Configuration to an Alternate File"));
                }
                stat = exec_conf();
                if (stat < 0)
@@ -793,7 +795,7 @@ static void conf(struct menu *menu)
                        if (sym)
                                show_help(submenu);
                        else
-                               show_helptext("README", mconf_readme);
+                               show_helptext("README", _(mconf_readme));
                        break;
                case 3:
                        if (type == 't') {
@@ -849,7 +851,7 @@ static void show_help(struct menu *menu)
        {
                if (sym->name) {
                        str_printf(&help, "CONFIG_%s:\n\n", sym->name);
-                       str_append(&help, sym->help);
+                       str_append(&help, _(sym->help));
                        str_append(&help, "\n");
                }
        } else {
@@ -886,9 +888,9 @@ static void conf_choice(struct menu *menu)
        while (1) {
                cprint_init();
                cprint("--title");
-               cprint("%s", prompt ? prompt : "Main Menu");
+               cprint("%s", prompt ? prompt : _("Main Menu"));
                cprint("--radiolist");
-               cprint(radiolist_instructions);
+               cprint(_(radiolist_instructions));
                cprint("15");
                cprint("70");
                cprint("6");
@@ -935,17 +937,17 @@ static void conf_string(struct menu *menu)
        while (1) {
                cprint_init();
                cprint("--title");
-               cprint("%s", prompt ? prompt : "Main Menu");
+               cprint("%s", prompt ? prompt : _("Main Menu"));
                cprint("--inputbox");
                switch (sym_get_type(menu->sym)) {
                case S_INT:
-                       cprint(inputbox_instructions_int);
+                       cprint(_(inputbox_instructions_int));
                        break;
                case S_HEX:
-                       cprint(inputbox_instructions_hex);
+                       cprint(_(inputbox_instructions_hex));
                        break;
                case S_STRING:
-                       cprint(inputbox_instructions_string);
+                       cprint(_(inputbox_instructions_string));
                        break;
                default:
                        /* panic? */;
@@ -958,7 +960,7 @@ static void conf_string(struct menu *menu)
                case 0:
                        if (sym_set_string_value(menu->sym, input_buf))
                                return;
-                       show_textbox(NULL, "You have made an invalid entry.", 5, 43);
+                       show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
                        break;
                case 1:
                        show_help(menu);
@@ -987,10 +989,10 @@ static void conf_load(void)
                                return;
                        if (!conf_read(input_buf))
                                return;
-                       show_textbox(NULL, "File does not exist!", 5, 38);
+                       show_textbox(NULL, _("File does not exist!"), 5, 38);
                        break;
                case 1:
-                       show_helptext("Load Alternate Configuration", load_config_help);
+                       show_helptext(_("Load Alternate Configuration"), load_config_help);
                        break;
                case 255:
                        return;
@@ -1016,10 +1018,10 @@ static void conf_save(void)
                                return;
                        if (!conf_write(input_buf))
                                return;
-                       show_textbox(NULL, "Can't create file!  Probably a nonexistent directory.", 5, 60);
+                       show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60);
                        break;
                case 1:
-                       show_helptext("Save Alternate Configuration", save_config_help);
+                       show_helptext(_("Save Alternate Configuration"), save_config_help);
                        break;
                case 255:
                        return;
@@ -1040,12 +1042,16 @@ int main(int ac, char **av)
        char *mode;
        int stat;
 
+       setlocale(LC_ALL, "");
+       bindtextdomain(PACKAGE, LOCALEDIR);
+       textdomain(PACKAGE);
+
        conf_parse(av[1]);
        conf_read(NULL);
 
        sym = sym_lookup("KERNELRELEASE", 0);
        sym_calc_value(sym);
-       sprintf(menu_backtitle, "Linux Kernel v%s Configuration",
+       sprintf(menu_backtitle, _("Linux Kernel v%s Configuration"),
                sym_get_string_value(sym));
 
        mode = getenv("MENUCONFIG_MODE");
@@ -1062,7 +1068,7 @@ int main(int ac, char **av)
        do {
                cprint_init();
                cprint("--yesno");
-               cprint("Do you wish to save your new kernel configuration?");
+               cprint(_("Do you wish to save your new kernel configuration?"));
                cprint("5");
                cprint("60");
                stat = exec_conf();
@@ -1070,20 +1076,20 @@ int main(int ac, char **av)
 
        if (stat == 0) {
                if (conf_write(NULL)) {
-                       fprintf(stderr, "\n\n"
+                       fprintf(stderr, _("\n\n"
                                "Error during writing of the kernel configuration.\n"
                                "Your kernel configuration changes were NOT saved."
-                               "\n\n");
+                               "\n\n"));
                        return 1;
                }
-               printf("\n\n"
+               printf(_("\n\n"
                        "*** End of Linux kernel configuration.\n"
                        "*** Execute 'make' to build the kernel or try 'make help'."
-                       "\n\n");
+                       "\n\n"));
        } else {
-               fprintf(stderr, "\n\n"
+               fprintf(stderr, _("\n\n"
                        "Your kernel configuration changes were NOT saved."
-                       "\n\n");
+                       "\n\n"));
        }
 
        return 0;
index 0c13156f33441fc8fc787b92ab038b752c87a563..8c59b212722dc21bb66e695ebdef09bf339f5e72 100644 (file)
@@ -365,9 +365,9 @@ bool menu_is_visible(struct menu *menu)
 const char *menu_get_prompt(struct menu *menu)
 {
        if (menu->prompt)
-               return menu->prompt->text;
+               return _(menu->prompt->text);
        else if (menu->sym)
-               return menu->sym->name;
+               return _(menu->sym->name);
        return NULL;
 }
 
index 0cdbf9dbbd510b27d419a25ab29589515489c794..4590cd31623fd89791cd213eeb9ab15ca499753b 100644 (file)
 #include "qconf.moc"
 #include "images.c"
 
+#ifdef _
+# undef _
+# define _ qgettext
+#endif
+
 static QApplication *configApp;
 
+static inline QString qgettext(const char* str)
+{
+  return QString::fromLocal8Bit(gettext(str));
+}
+
+static inline QString qgettext(const QString& str)
+{
+  return QString::fromLocal8Bit(gettext(str.latin1()));
+}
+
 ConfigSettings::ConfigSettings()
        : showAll(false), showName(false), showRange(false), showData(false)
 {
@@ -177,7 +192,7 @@ void ConfigItem::updateMenu(void)
 
        sym = menu->sym;
        prop = menu->prompt;
-       prompt = menu_get_prompt(menu);
+       prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
 
        if (prop) switch (prop->type) {
        case P_MENU:
@@ -203,7 +218,7 @@ void ConfigItem::updateMenu(void)
        if (!sym)
                goto set_prompt;
 
-       setText(nameColIdx, sym->name);
+       setText(nameColIdx, QString::fromLocal8Bit(sym->name));
 
        type = sym_get_type(sym);
        switch (type) {
@@ -213,9 +228,9 @@ void ConfigItem::updateMenu(void)
 
                if (!sym_is_changable(sym) && !list->showAll) {
                        setPixmap(promptColIdx, 0);
-                       setText(noColIdx, 0);
-                       setText(modColIdx, 0);
-                       setText(yesColIdx, 0);
+                       setText(noColIdx, QString::null);
+                       setText(modColIdx, QString::null);
+                       setText(yesColIdx, QString::null);
                        break;
                }
                expr = sym_get_tristate_value(sym);
@@ -257,6 +272,7 @@ void ConfigItem::updateMenu(void)
                const char* data;
 
                data = sym_get_string_value(sym);
+
 #if QT_VERSION >= 300
                int i = list->mapIdx(dataColIdx);
                if (i >= 0)
@@ -264,9 +280,9 @@ void ConfigItem::updateMenu(void)
 #endif
                setText(dataColIdx, data);
                if (type == S_STRING)
-                       prompt.sprintf("%s: %s", prompt.latin1(), data);
+                       prompt = QString("%1: %2").arg(prompt).arg(data);
                else
-                       prompt.sprintf("(%s) %s", data, prompt.latin1());
+                       prompt = QString("(%2) %1").arg(prompt).arg(data);
                break;
        }
        if (!sym_has_value(sym) && visible)
@@ -343,9 +359,9 @@ void ConfigLineEdit::show(ConfigItem* i)
 {
        item = i;
        if (sym_get_string_value(item->menu->sym))
-               setText(sym_get_string_value(item->menu->sym));
+               setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
        else
-               setText(0);
+               setText(QString::null);
        Parent::show();
        setFocus();
 }
@@ -961,7 +977,7 @@ ConfigMainWindow::ConfigMainWindow(void)
        delete configSettings;
 }
 
-static QString print_filter(const char *str)
+static QString print_filter(const QString &str)
 {
        QRegExp re("[<>&\"\\n]");
        QString res = str;
@@ -994,7 +1010,7 @@ static QString print_filter(const char *str)
 
 static void expr_print_help(void *data, const char *str)
 {
-       ((QString*)data)->append(print_filter(str));
+       reinterpret_cast<QString*>(data)->append(print_filter(str));
 }
 
 /*
@@ -1009,7 +1025,7 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
        if (item)
                menu = ((ConfigItem*)item)->menu;
        if (!menu) {
-               helpText->setText(NULL);
+               helpText->setText(QString::null);
                return;
        }
 
@@ -1019,16 +1035,16 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
        if (sym) {
                if (menu->prompt) {
                        head += "<big><b>";
-                       head += print_filter(menu->prompt->text);
+                       head += print_filter(_(menu->prompt->text));
                        head += "</b></big>";
                        if (sym->name) {
                                head += " (";
-                               head += print_filter(sym->name);
+                               head += print_filter(_(sym->name));
                                head += ")";
                        }
                } else if (sym->name) {
                        head += "<big><b>";
-                       head += print_filter(sym->name);
+                       head += print_filter(_(sym->name));
                        head += "</b></big>";
                }
                head += "<br><br>";
@@ -1049,7 +1065,7 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
                                case P_PROMPT:
                                case P_MENU:
                                        debug += "prompt: ";
-                                       debug += print_filter(prop->text);
+                                       debug += print_filter(_(prop->text));
                                        debug += "<br>";
                                        break;
                                case P_DEFAULT:
@@ -1088,10 +1104,10 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
                        debug += "<br>";
                }
 
-               help = print_filter(sym->help);
+               help = print_filter(_(sym->help));
        } else if (menu->prompt) {
                head += "<big><b>";
-               head += print_filter(menu->prompt->text);
+               head += print_filter(_(menu->prompt->text));
                head += "</b></big><br><br>";
                if (showDebug) {
                        if (menu->prompt->visible.expr) {
@@ -1111,7 +1127,7 @@ void ConfigMainWindow::loadConfig(void)
        QString s = QFileDialog::getOpenFileName(".config", NULL, this);
        if (s.isNull())
                return;
-       if (conf_read(s.latin1()))
+       if (conf_read(QFile::encodeName(s)))
                QMessageBox::information(this, "qconf", "Unable to load configuration!");
        ConfigView::updateListAll();
 }
@@ -1127,7 +1143,7 @@ void ConfigMainWindow::saveConfigAs(void)
        QString s = QFileDialog::getSaveFileName(".config", NULL, this);
        if (s.isNull())
                return;
-       if (conf_write(s.latin1()))
+       if (conf_write(QFile::encodeName(s)))
                QMessageBox::information(this, "qconf", "Unable to save configuration!");
 }
 
@@ -1372,6 +1388,9 @@ int main(int ac, char** av)
        ConfigMainWindow* v;
        const char *name;
 
+       bindtextdomain(PACKAGE, LOCALEDIR);
+       textdomain(PACKAGE);
+
 #ifndef LKC_DIRECT_LINK
        kconfig_load();
 #endif
index 43af01075612a5b663616c468930b401c972e0fb..f2d47ca9c8facb232bc41263d87bdaa667fc1292 100755 (executable)
 # fix some whitespace damage;
 # be smarter about stopping when current version is larger than requested;
 #      Randy Dunlap <rddunlap@osdl.org>, 2004-AUG-18.
+#
+# Add better support for (non-incremental) 2.6.x.y patches;
+# If an ending version number if not specified, the script automatically
+# increments the SUBLEVEL (x in 2.6.x.y) until no more patch files are found;
+# however, EXTRAVERSION (y in 2.6.x.y) is never automatically incremented
+# but must be specified fully.
+#
+# patch-kernel does not normally support reverse patching, but does so when
+# applying EXTRAVERSION (x.y) patches, so that moving from 2.6.11.y to 2.6.11.z
+# is easy and handled by the script (reverse 2.6.11.y and apply 2.6.11.z).
+#      Randy Dunlap <rddunlap@osdl.org>, 2005-APR-08.
+
+PNAME=patch-kernel
 
 # Set directories from arguments, or use defaults.
 sourcedir=${1-/usr/src/linux}
@@ -54,7 +67,7 @@ stopvers=${3-default}
 
 if [ "$1" == -h -o "$1" == --help -o ! -r "$sourcedir/Makefile" ]; then
 cat << USAGE
-usage: patch-kernel [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
+usage: $PNAME [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
   source directory defaults to /usr/src/linux,
   patch directory defaults to the current directory,
   stopversion defaults to <all in patchdir>.
@@ -72,6 +85,19 @@ do
        esac;
 done
 
+# ---------------------------------------------------------------------------
+# arg1 is filename
+noFile () {
+       echo "cannot find patch file: ${patch}"
+       exit 1
+}
+
+# ---------------------------------------------------------------------------
+backwards () {
+       echo "$PNAME does not support reverse patching"
+       exit 1
+}
+
 # ---------------------------------------------------------------------------
 # Find a file, first parameter is basename of file
 # it tries many compression mechanisms and sets variables to say how to get it
@@ -133,6 +159,28 @@ applyPatch () {
   return 0;
 }
 
+# ---------------------------------------------------------------------------
+# arg1 is patch filename
+reversePatch () {
+       echo -n "Reversing $1 (${name}) ... "
+       if $uncomp ${patchdir}/"$1"${ext} | patch -p1 -Rs -N -E -d $sourcedir
+       then
+               echo "done."
+       else
+               echo "failed.  Clean it up."
+               exit 1
+       fi
+       if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ]
+       then
+               echo "Aborting.  Reject files found."
+               return 1
+       fi
+       # Remove backup files
+       find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \;
+
+       return 0
+}
+
 # set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
 TMPFILE=`mktemp .tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; }
 grep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE
@@ -160,53 +208,57 @@ then
                EXTRAVER=$EXTRAVERSION
        fi
        EXTRAVER=${EXTRAVER%%[[:punct:]]*}
-       #echo "patch-kernel: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER"
+       #echo "$PNAME: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER"
 fi
 
 #echo "stopvers=$stopvers"
 if [ $stopvers != "default" ]; then
        STOPSUBLEVEL=`echo $stopvers | cut -d. -f3`
        STOPEXTRA=`echo $stopvers | cut -d. -f4`
-       #echo "STOPSUBLEVEL=$STOPSUBLEVEL, STOPEXTRA=$STOPEXTRA"
+       #echo "#___STOPSUBLEVEL=/$STOPSUBLEVEL/, STOPEXTRA=/$STOPEXTRA/"
 else
        STOPSUBLEVEL=9999
        STOPEXTRA=9999
 fi
 
-while :                                # incrementing SUBLEVEL (s in v.p.s)
-do
-    if [ x$EXTRAVER != "x" ]; then
+# This all assumes a 2.6.x[.y] kernel tree.
+# Don't allow backwards/reverse patching.
+if [ $STOPSUBLEVEL -lt $SUBLEVEL ]; then
+       backwards
+fi
+
+if [ x$EXTRAVER != "x" ]; then
        CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
-    else
+else
        CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
-    fi
+fi
+
+if [ x$EXTRAVER != "x" ]; then
+       echo "backing up to: $VERSION.$PATCHLEVEL.$SUBLEVEL"
+       patch="patch-${CURRENTFULLVERSION}"
+       findFile $patchdir/${patch} || noFile ${patch}
+       reversePatch ${patch} || exit 1
+fi
 
+# now current is 2.6.x, with no EXTRA applied,
+# so update to target SUBLEVEL (2.6.SUBLEVEL)
+# and then to target EXTRAVER (2.6.SUB.EXTRAVER) if requested.
+# If not ending sublevel is specified, it is incremented until
+# no further sublevels are found.
+
+if [ $STOPSUBLEVEL -gt $SUBLEVEL ]; then
+while :                                # incrementing SUBLEVEL (s in v.p.s)
+do
+    CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
+    EXTRAVER=
     if [ $stopvers == $CURRENTFULLVERSION ]; then
         echo "Stopping at $CURRENTFULLVERSION base as requested."
         break
     fi
 
-    while :                    # incrementing EXTRAVER (x in v.p.s.x)
-    do
-       EXTRAVER=$((EXTRAVER + 1))
-       FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
-       #echo "... trying $FULLVERSION ..."
-
-       patch=patch-$FULLVERSION
-
-       # See if the file exists and find extension
-       findFile $patchdir/${patch} || break
-
-       # Apply the patch and check all is OK
-       applyPatch $patch || break
-
-       continue 2
-    done
-
-    EXTRAVER=
     SUBLEVEL=$((SUBLEVEL + 1))
     FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
-    #echo "___ trying $FULLVERSION ___"
+    #echo "#___ trying $FULLVERSION ___"
 
     if [ $((SUBLEVEL)) -gt $((STOPSUBLEVEL)) ]; then
        echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)"
@@ -214,14 +266,33 @@ do
     fi
 
     patch=patch-$FULLVERSION
-
     # See if the file exists and find extension
-    findFile $patchdir/${patch} || break
+    findFile $patchdir/${patch} || noFile ${patch}
 
     # Apply the patch and check all is OK
     applyPatch $patch || break
 done
-#echo "base all done"
+#echo "#___sublevel all done"
+fi
+
+# There is no incremental searching for extraversion...
+if [ "$STOPEXTRA" != "" ]; then
+while :                                # just to allow break
+do
+# apply STOPEXTRA directly (not incrementally) (x in v.p.s.x)
+       FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$STOPEXTRA"
+       #echo "#... trying $FULLVERSION ..."
+       patch=patch-$FULLVERSION
+
+       # See if the file exists and find extension
+       findFile $patchdir/${patch} || noFile ${patch}
+
+       # Apply the patch and check all is OK
+       applyPatch $patch || break
+       #echo "#___extraver all done"
+       break
+done
+fi
 
 if [ x$gotac != x ]; then
   # Out great user wants the -ac patches
index 5a820cf88c9c985be9108eaf01936f32bd7bf8ce..8449d667b062f7bd81b5301846435358bcaa2788 100644 (file)
@@ -476,8 +476,8 @@ int security_compute_av(u32 ssid,
        int rc = 0;
 
        if (!ss_initialized) {
-               avd->allowed = requested;
-               avd->decided = requested;
+               avd->allowed = 0xffffffff;
+               avd->decided = 0xffffffff;
                avd->auditallow = 0;
                avd->auditdeny = 0xffffffff;
                avd->seqno = latest_granting;
@@ -1196,9 +1196,11 @@ int security_load_policy(void *data, size_t len)
                }
                policydb_loaded_version = policydb.policyvers;
                ss_initialized = 1;
-
+               seqno = ++latest_granting;
                LOAD_UNLOCK;
                selinux_complete_init();
+               avc_ss_reset(seqno);
+               selnl_notify_policyload(seqno);
                return 0;
        }
 
index 4a6be966bd9ffcf3ec034eb96d88d5ecd5d3b758..3a3228b18726c9aaae432f7d3ecec06df3c4afa3 100644 (file)
@@ -164,6 +164,7 @@ config SND_INTERWAVE
        select SND_RAWMIDI
        select SND_CS4231_LIB
        select SND_GUS_SYNTH
+       select ISAPNP
        help
          Say Y here to include support for AMD InterWave based
          soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
index a9602f89d6b1c4bfaaf6bb36b5e2bc508745141e..e537bd66a707795e1e2edcec4483fbe0977f87dd 100644 (file)
@@ -112,7 +112,7 @@ config SOUND_BCM_CS4297A
 
 config SOUND_ES1370
        tristate "Ensoniq AudioPCI (ES1370)"
-       depends on SOUND_PRIME!=n && SOUND && PCI && SOUND_GAMEPORT
+       depends on SOUND_PRIME!=n && SOUND && PCI
        help
          Say Y or M if you have a PCI sound card utilizing the Ensoniq
          ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find
@@ -125,7 +125,7 @@ config SOUND_ES1370
 
 config SOUND_ES1371
        tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
-       depends on SOUND_PRIME!=n && SOUND && PCI && SOUND_GAMEPORT
+       depends on SOUND_PRIME!=n && SOUND && PCI
        help
          Say Y or M if you have a PCI sound card utilizing the Ensoniq
          ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if
@@ -138,7 +138,7 @@ config SOUND_ES1371
 
 config SOUND_ESSSOLO1
        tristate "ESS Technology Solo1" 
-       depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT && PCI
+       depends on SOUND_PRIME!=n && SOUND && PCI
        help
          Say Y or M if you have a PCI sound card utilizing the ESS Technology
          Solo1 chip. To find out if your sound card uses a
@@ -179,7 +179,7 @@ config SOUND_HARMONY
 
 config SOUND_SONICVIBES
        tristate "S3 SonicVibes"
-       depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT
+       depends on SOUND_PRIME!=n && SOUND
        help
          Say Y or M if you have a PCI sound card utilizing the S3
          SonicVibes chipset. To find out if your sound card uses a
@@ -226,7 +226,7 @@ config SOUND_AU1550_AC97
 
 config SOUND_TRIDENT
        tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core"
-       depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT
+       depends on SOUND_PRIME!=n && SOUND
        ---help---
          Say Y or M if you have a PCI sound card utilizing the Trident
          4DWave-DX/NX chipset or your mother board chipset has SiS 7018
@@ -739,7 +739,7 @@ config SOUND_NM256
 
 config SOUND_MAD16
        tristate "OPTi MAD16 and/or Mozart based cards"
-       depends on SOUND_OSS && SOUND_GAMEPORT
+       depends on SOUND_OSS
        ---help---
          Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi
          82C928 or 82C929 or 82C931) audio interface chip. These chips are
index 124b1e10a13d959f946446b95d752ba1e869a6d9..3ecef4689f1b23d6a2454f443413c447e2a72bbc 100644 (file)
@@ -155,6 +155,7 @@ static const struct {
        {0x43525931, "Cirrus Logic CS4299 rev A", &crystal_digital_ops},
        {0x43525933, "Cirrus Logic CS4299 rev C", &crystal_digital_ops},
        {0x43525934, "Cirrus Logic CS4299 rev D", &crystal_digital_ops},
+       {0x43585430, "CXT48",                   &default_ops,           AC97_DELUDED_MODEM },
        {0x43585442, "CXT66",                   &default_ops,           AC97_DELUDED_MODEM },
        {0x44543031, "Diamond Technology DT0893", &default_ops},
        {0x45838308, "ESS Allegro ES1988",      &null_ops},
index d143d2c78988574263cf699f7530c629c4cae995..8b33b12fa5dc7e65fa438efebcbdd88ab65be118 100644 (file)
@@ -125,8 +125,8 @@ MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 c
 #ifndef PCI_DEVICE_ID_INTEL_ICH7_20
 #define PCI_DEVICE_ID_INTEL_ICH7_20    0x27de
 #endif
-#ifndef PCI_DEVICE_ID_INTEL_ESB2_13
-#define PCI_DEVICE_ID_INTEL_ESB2_13    0x2698
+#ifndef PCI_DEVICE_ID_INTEL_ESB2_14
+#define PCI_DEVICE_ID_INTEL_ESB2_14    0x2698
 #endif
 #ifndef PCI_DEVICE_ID_SI_7012
 #define PCI_DEVICE_ID_SI_7012          0x7012
@@ -2741,7 +2741,7 @@ static struct shortname_table {
        { PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" },
        { PCI_DEVICE_ID_INTEL_ICH6_18, "Intel ICH6" },
        { PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" },
-       { PCI_DEVICE_ID_INTEL_ESB2_13, "Intel ESB2" },
+       { PCI_DEVICE_ID_INTEL_ESB2_14, "Intel ESB2" },
        { PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
        { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" },
        { PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" },
index f1ce808501da54e60039fd5a9ab99af30d77a0c5..9b4d74d49f984c9d6a19bc9fd4ccd5c35df1d49b 100644 (file)
@@ -1836,7 +1836,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip)
  *
  */
 
-static int __devinit snd_via82xx_chip_init(via82xx_t *chip)
+static int snd_via82xx_chip_init(via82xx_t *chip)
 {
        unsigned int val;
        int max_count;
index 32d94754acf814a243840bda4cdc1979d984f73c..080ef3928465cd1c55256b131d4cb9eaf2fee089 100644 (file)
@@ -876,7 +876,7 @@ static void __init detect_byte_swap(pmac_t *chip)
  */
 static int __init snd_pmac_detect(pmac_t *chip)
 {
-       struct device_node *sound;
+       struct device_node *sound = NULL;
        unsigned int *prop, l;
        struct macio_chip* macio;
 
@@ -906,20 +906,22 @@ static int __init snd_pmac_detect(pmac_t *chip)
                chip->is_pbook_G3 = 1;
        chip->node = find_devices("awacs");
        if (chip->node)
-               return 0; /* ok */
+               sound = chip->node;
 
        /*
         * powermac G3 models have a node called "davbus"
         * with a child called "sound".
         */
-       chip->node = find_devices("davbus");
+       if (!chip->node)
+               chip->node = find_devices("davbus");
        /*
         * if we didn't find a davbus device, try 'i2s-a' since
         * this seems to be what iBooks have
         */
        if (! chip->node) {
                chip->node = find_devices("i2s-a");
-               if (chip->node && chip->node->parent && chip->node->parent->parent) {
+               if (chip->node && chip->node->parent &&
+                   chip->node->parent->parent) {
                        if (device_is_compatible(chip->node->parent->parent,
                                                 "K2-Keylargo"))
                                chip->is_k2 = 1;
@@ -928,9 +930,11 @@ static int __init snd_pmac_detect(pmac_t *chip)
        if (! chip->node)
                return -ENODEV;
 
-       sound = find_devices("sound");
-       while (sound && sound->parent != chip->node)
-               sound = sound->next;
+       if (!sound) {
+               sound = find_devices("sound");
+               while (sound && sound->parent != chip->node)
+                       sound = sound->next;
+       }
        if (! sound)
                return -ENODEV;
        prop = (unsigned int *) get_property(sound, "sub-frame", NULL);
@@ -1019,7 +1023,8 @@ static int __init snd_pmac_detect(pmac_t *chip)
                }
        }
        if (chip->pdev == NULL)
-               printk(KERN_WARNING "snd-powermac: can't locate macio PCI device !\n");
+               printk(KERN_WARNING "snd-powermac: can't locate macio PCI"
+                      " device !\n");
 
        detect_byte_swap(chip);
 
@@ -1027,7 +1032,8 @@ static int __init snd_pmac_detect(pmac_t *chip)
           are available */
        prop = (unsigned int *) get_property(sound, "sample-rates", &l);
        if (! prop)
-               prop = (unsigned int *) get_property(sound, "output-frame-rates", &l);
+               prop = (unsigned int *) get_property(sound,
+                                                    "output-frame-rates", &l);
        if (prop) {
                int i;
                chip->freqs_ok = 0;
@@ -1054,7 +1060,8 @@ static int __init snd_pmac_detect(pmac_t *chip)
 /*
  * exported - boolean info callbacks for ease of programming
  */
-int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol,
+                                snd_ctl_elem_info_t *uinfo)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
        uinfo->count = 2;
@@ -1063,7 +1070,8 @@ int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
        return 0;
 }
 
-int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol,
+                              snd_ctl_elem_info_t *uinfo)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
        uinfo->count = 1;
index 84b0bbddbd226f8716a06459aa9fa67892da6b6e..aae66144d411ce579eee7185b8e3cca84e730d9e 100644 (file)
@@ -3289,7 +3289,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
                }
                usb_chip[chip->index] = NULL;
                up(&register_mutex);
-               snd_card_free_in_thread(card);
+               snd_card_free(card);
        } else {
                up(&register_mutex);
        }
index b06a267e5dac22d5350942cdfa2cfcfdb74c62b2..89ee8b7320134fdf97b02a03f9e30457d32099f3 100644 (file)
@@ -1,6 +1,11 @@
 /*
  * usbusy2y.c - ALSA USB US-428 Driver
  *
+2005-04-14 Karsten Wiese
+       Version 0.8.7.2:
+       Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom.
+       Tested ok with kernel 2.6.12-rc2.
+
 2004-12-14 Karsten Wiese
        Version 0.8.7.1:
        snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open.
 
 
 MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
-MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.1");
+MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}");
 
@@ -430,8 +435,6 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr)
        if (ptr) {
                usX2Ydev_t* usX2Y = usX2Y((snd_card_t*)ptr);
                struct list_head* p;
-               if (usX2Y->chip_status == USX2Y_STAT_CHIP_HUP)  // on 2.6.1 kernel snd_usbmidi_disconnect()
-                       return;                                 // calls us back. better leave :-) .
                usX2Y->chip.shutdown = 1;
                usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;
                usX2Y_unlinkSeq(&usX2Y->AS04);
@@ -443,7 +446,7 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr)
                }
                if (usX2Y->us428ctls_sharedmem) 
                        wake_up(&usX2Y->us428ctls_wait_queue_head);
-               snd_card_free_in_thread((snd_card_t*)ptr);
+               snd_card_free((snd_card_t*)ptr);
        }
 }