aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS13
-rw-r--r--Documentation/00-INDEX2
-rw-r--r--Documentation/BK-usage/00-INDEX51
-rw-r--r--Documentation/BK-usage/bk-kernel-howto.txt283
-rwxr-xr-xDocumentation/BK-usage/bk-make-sum34
-rwxr-xr-xDocumentation/BK-usage/bksend36
-rwxr-xr-xDocumentation/BK-usage/bz64wrap41
-rwxr-xr-xDocumentation/BK-usage/cpcset36
-rwxr-xr-xDocumentation/BK-usage/cset-to-linus49
-rwxr-xr-xDocumentation/BK-usage/csets-to-patches44
-rwxr-xr-xDocumentation/BK-usage/gcapatch8
-rwxr-xr-xDocumentation/BK-usage/unbz64wrap25
-rw-r--r--Documentation/DocBook/libata.tmpl156
-rw-r--r--Documentation/SubmittingPatches8
-rw-r--r--Documentation/aoe/aoe.txt40
-rw-r--r--Documentation/aoe/status.sh4
-rw-r--r--Documentation/cpu-freq/cpufreq-stats.txt128
-rw-r--r--Documentation/cpusets.txt3
-rw-r--r--Documentation/dontdiff3
-rw-r--r--Documentation/dvb/README.flexcop205
-rw-r--r--Documentation/dvb/bt8xx.txt69
-rw-r--r--Documentation/dvb/ci.txt219
-rw-r--r--Documentation/dvb/get_dvb_firmware4
-rw-r--r--Documentation/feature-removal-schedule.txt20
-rw-r--r--Documentation/filesystems/sysfs-pci.txt6
-rw-r--r--Documentation/networking/DLINK.txt7
-rw-r--r--Documentation/networking/vortex.txt2
-rw-r--r--Documentation/pci.txt1
-rw-r--r--Documentation/power/devices.txt21
-rw-r--r--Documentation/power/pci.txt35
-rw-r--r--Documentation/powerpc/hvcs.txt4
-rw-r--r--Documentation/x86_64/boot-options.txt3
-rw-r--r--MAINTAINERS62
-rw-r--r--Makefile4
-rw-r--r--arch/alpha/Kconfig4
-rw-r--r--arch/alpha/kernel/osf_sys.c7
-rw-r--r--arch/arm/Kconfig28
-rw-r--r--arch/arm/boot/compressed/head-xscale.S7
-rw-r--r--arch/arm/configs/badge4_defconfig29
-rw-r--r--arch/arm/configs/h3600_defconfig24
-rw-r--r--arch/arm/configs/hackkit_defconfig22
-rw-r--r--arch/arm/kernel/entry-armv.S30
-rw-r--r--arch/arm/kernel/head.S3
-rw-r--r--arch/arm/kernel/process.c25
-rw-r--r--arch/arm/kernel/sys_arm.c2
-rw-r--r--arch/arm/kernel/traps.c63
-rw-r--r--arch/arm/kernel/vmlinux.lds.S3
-rw-r--r--arch/arm/lib/io-writesw-armv4.S6
-rw-r--r--arch/arm/mach-clps711x/Kconfig3
-rw-r--r--arch/arm/mach-footbridge/Kconfig12
-rw-r--r--arch/arm/mach-imx/Kconfig1
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c10
-rw-r--r--arch/arm/mach-pxa/mainstone.c9
-rw-r--r--arch/arm/mach-pxa/pm.c32
-rw-r--r--arch/arm/mach-pxa/pxa25x.c33
-rw-r--r--arch/arm/mach-pxa/pxa27x.c36
-rw-r--r--arch/arm/mach-s3c2410/clock.c2
-rw-r--r--arch/arm/mach-s3c2410/dma.c4
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.c6
-rw-r--r--arch/arm/mach-sa1100/Kconfig2
-rw-r--r--arch/arm/mm/Kconfig38
-rw-r--r--arch/arm/mm/Makefile2
-rw-r--r--arch/arm/mm/copypage-v4mc.S80
-rw-r--r--arch/arm/mm/copypage-v4mc.c111
-rw-r--r--arch/arm/mm/copypage-v6.c28
-rw-r--r--arch/arm/mm/copypage-xscale.S113
-rw-r--r--arch/arm/mm/copypage-xscale.c131
-rw-r--r--arch/arm/mm/flush.c37
-rw-r--r--arch/arm/mm/minicache.c73
-rw-r--r--arch/arm/mm/mm-armv.c27
-rw-r--r--arch/arm26/Kconfig4
-rw-r--r--arch/h8300/kernel/process.c2
-rw-r--r--arch/i386/Kconfig26
-rw-r--r--arch/i386/Makefile6
-rw-r--r--arch/i386/boot/bootsect.S2
-rw-r--r--arch/i386/boot/video.S18
-rw-r--r--arch/i386/kernel/Makefile2
-rw-r--r--arch/i386/kernel/acpi/boot.c2
-rw-r--r--arch/i386/kernel/apm.c2
-rw-r--r--arch/i386/kernel/cpu/amd.c12
-rw-r--r--arch/i386/kernel/cpu/common.c4
-rw-r--r--arch/i386/kernel/cpu/cpufreq/Kconfig14
-rw-r--r--arch/i386/kernel/cpu/cpufreq/Makefile1
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c58
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k7.c11
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c113
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.h15
-rw-r--r--arch/i386/kernel/cpu/cpufreq/sc520_freq.c186
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c6
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-lib.c6
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-smi.c3
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c2
-rw-r--r--arch/i386/kernel/cpu/mtrr/cyrix.c4
-rw-r--r--arch/i386/kernel/i386_ksyms.c4
-rw-r--r--arch/i386/kernel/kprobes.c7
-rw-r--r--arch/i386/kernel/process.c13
-rw-r--r--arch/i386/kernel/ptrace.c19
-rw-r--r--arch/i386/kernel/setup.c2
-rw-r--r--arch/i386/kernel/smpboot.c5
-rw-r--r--arch/i386/kernel/timers/common.c6
-rw-r--r--arch/i386/kernel/timers/timer_tsc.c20
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c17
-rw-r--r--arch/i386/mm/ioremap.c10
-rw-r--r--arch/i386/pci/fixup.c2
-rw-r--r--arch/i386/pci/irq.c5
-rw-r--r--arch/ia64/Kconfig23
-rw-r--r--arch/ia64/configs/tiger_defconfig96
-rw-r--r--arch/ia64/hp/common/sba_iommu.c34
-rw-r--r--arch/ia64/ia32/ia32_ioctl.c1
-rw-r--r--arch/ia64/ia32/sys_ia32.c2
-rw-r--r--arch/ia64/kernel/acpi.c23
-rw-r--r--arch/ia64/kernel/entry.S6
-rw-r--r--arch/ia64/kernel/fsys.S4
-rw-r--r--arch/ia64/kernel/mca.c8
-rw-r--r--arch/ia64/kernel/mca_drv.c4
-rw-r--r--arch/ia64/kernel/mca_drv_asm.S18
-rw-r--r--arch/ia64/kernel/minstate.h3
-rw-r--r--arch/ia64/kernel/module.c10
-rw-r--r--arch/ia64/kernel/perfmon.c218
-rw-r--r--arch/ia64/kernel/process.c55
-rw-r--r--arch/ia64/kernel/ptrace.c47
-rw-r--r--arch/ia64/kernel/setup.c3
-rw-r--r--arch/ia64/kernel/signal.c3
-rw-r--r--arch/ia64/kernel/smpboot.c2
-rw-r--r--arch/ia64/kernel/sys_ia64.c7
-rw-r--r--arch/ia64/kernel/traps.c29
-rw-r--r--arch/ia64/lib/flush.S6
-rw-r--r--arch/ia64/lib/memcpy_mck.S2
-rw-r--r--arch/ia64/lib/memset.S2
-rw-r--r--arch/ia64/mm/init.c19
-rw-r--r--arch/ia64/sn/kernel/Makefile7
-rw-r--r--arch/ia64/sn/kernel/io_init.c10
-rw-r--r--arch/ia64/sn/kernel/mca.c34
-rw-r--r--arch/ia64/sn/kernel/setup.c46
-rw-r--r--arch/ia64/sn/kernel/tiocx.c60
-rw-r--r--arch/ia64/sn/kernel/xp_main.c289
-rw-r--r--arch/ia64/sn/kernel/xp_nofault.S31
-rw-r--r--arch/ia64/sn/kernel/xpc.h991
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c2297
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c1064
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c984
-rw-r--r--arch/ia64/sn/kernel/xpnet.c715
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c2
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c2
-rw-r--r--arch/m68k/configs/amiga_defconfig15
-rw-r--r--arch/m68k/configs/apollo_defconfig7
-rw-r--r--arch/m68k/configs/atari_defconfig7
-rw-r--r--arch/m68k/configs/bvme6000_defconfig7
-rw-r--r--arch/m68k/configs/hp300_defconfig7
-rw-r--r--arch/m68k/configs/mac_defconfig7
-rw-r--r--arch/m68k/configs/mvme147_defconfig7
-rw-r--r--arch/m68k/configs/mvme16x_defconfig7
-rw-r--r--arch/m68k/configs/q40_defconfig15
-rw-r--r--arch/m68k/configs/sun3_defconfig8
-rw-r--r--arch/m68k/configs/sun3x_defconfig7
-rw-r--r--arch/m68k/defconfig7
-rw-r--r--arch/m68knommu/Kconfig5
-rw-r--r--arch/m68knommu/kernel/process.c17
-rw-r--r--arch/mips/Kconfig4
-rw-r--r--arch/mips/kernel/ptrace.c38
-rw-r--r--arch/mips/vr41xx/common/pmu.c55
-rw-r--r--arch/parisc/Kconfig4
-rw-r--r--arch/ppc/Kconfig14
-rw-r--r--arch/ppc/boot/images/Makefile3
-rw-r--r--arch/ppc/configs/mpc8555_cds_defconfig117
-rw-r--r--arch/ppc/kernel/cputable.c11
-rw-r--r--arch/ppc/kernel/head_44x.S15
-rw-r--r--arch/ppc/kernel/head_fsl_booke.S15
-rw-r--r--arch/ppc/kernel/misc.S6
-rw-r--r--arch/ppc/kernel/setup.c41
-rw-r--r--arch/ppc/kernel/traps.c7
-rw-r--r--arch/ppc/kernel/vmlinux.lds.S2
-rw-r--r--arch/ppc/lib/string.S7
-rw-r--r--arch/ppc/mm/init.c1
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c1
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.h7
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.c3
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c143
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.h3
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.c3
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c43
-rw-r--r--arch/ppc/platforms/pq2ads.h41
-rw-r--r--arch/ppc/syslib/Makefile4
-rw-r--r--arch/ppc/syslib/ipic.c2
-rw-r--r--arch/ppc/syslib/m8260_pci.c193
-rw-r--r--arch/ppc/syslib/m8260_pci.h76
-rw-r--r--arch/ppc/syslib/m8260_pci_erratum9.c10
-rw-r--r--arch/ppc/syslib/m8260_setup.c11
-rw-r--r--arch/ppc/syslib/m82xx_pci.c383
-rw-r--r--arch/ppc/syslib/m82xx_pci.h92
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c1
-rw-r--r--arch/ppc/syslib/mpc85xx_devices.c1
-rw-r--r--arch/ppc/syslib/open_pic.c6
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.c28
-rw-r--r--arch/ppc/syslib/ppc85xx_setup.c16
-rw-r--r--arch/ppc/syslib/prom_init.c10
-rw-r--r--arch/ppc64/Kconfig8
-rw-r--r--arch/ppc64/Kconfig.debug3
-rw-r--r--arch/ppc64/boot/main.c1
-rw-r--r--arch/ppc64/boot/prom.c28
-rw-r--r--arch/ppc64/boot/start.c654
-rw-r--r--arch/ppc64/configs/g5_defconfig76
-rw-r--r--arch/ppc64/configs/iSeries_defconfig62
-rw-r--r--arch/ppc64/configs/maple_defconfig70
-rw-r--r--arch/ppc64/configs/pSeries_defconfig102
-rw-r--r--arch/ppc64/defconfig104
-rw-r--r--arch/ppc64/kernel/entry.S9
-rw-r--r--arch/ppc64/kernel/head.S10
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c22
-rw-r--r--arch/ppc64/kernel/idle.c8
-rw-r--r--arch/ppc64/kernel/kprobes.c18
-rw-r--r--arch/ppc64/kernel/mf.c85
-rw-r--r--arch/ppc64/kernel/misc.S4
-rw-r--r--arch/ppc64/kernel/pSeries_reconfig.c8
-rw-r--r--arch/ppc64/kernel/pSeries_smp.c7
-rw-r--r--arch/ppc64/kernel/pci.c2
-rw-r--r--arch/ppc64/kernel/pmac_smp.c28
-rw-r--r--arch/ppc64/kernel/process.c3
-rw-r--r--arch/ppc64/kernel/prom.c2
-rw-r--r--arch/ppc64/kernel/prom_init.c154
-rw-r--r--arch/ppc64/kernel/ptrace.c15
-rw-r--r--arch/ppc64/kernel/rtc.c39
-rw-r--r--arch/ppc64/kernel/setup.c56
-rw-r--r--arch/ppc64/kernel/signal.c6
-rw-r--r--arch/ppc64/kernel/smp.c3
-rw-r--r--arch/ppc64/kernel/sys_ppc32.c70
-rw-r--r--arch/ppc64/kernel/syscalls.c33
-rw-r--r--arch/ppc64/kernel/sysfs.c8
-rw-r--r--arch/ppc64/kernel/time.c3
-rw-r--r--arch/ppc64/kernel/xics.c16
-rw-r--r--arch/ppc64/mm/hash_native.c3
-rw-r--r--arch/ppc64/mm/hash_utils.c11
-rw-r--r--arch/ppc64/mm/imalloc.c5
-rw-r--r--arch/ppc64/mm/init.c3
-rw-r--r--arch/ppc64/mm/stab.c5
-rw-r--r--arch/s390/appldata/appldata_base.c72
-rw-r--r--arch/s390/appldata/appldata_mem.c2
-rw-r--r--arch/s390/appldata/appldata_net_sum.c2
-rw-r--r--arch/s390/appldata/appldata_os.c4
-rw-r--r--arch/s390/kernel/ptrace.c76
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sh/Kconfig4
-rw-r--r--arch/sparc/kernel/process.c5
-rw-r--r--arch/sparc/prom/memory.c28
-rw-r--r--arch/sparc/prom/sun4prom.c2
-rw-r--r--arch/sparc64/kernel/irq.c6
-rw-r--r--arch/sparc64/kernel/pci_iommu.c221
-rw-r--r--arch/sparc64/kernel/pci_psycho.c2
-rw-r--r--arch/sparc64/kernel/pci_sabre.c2
-rw-r--r--arch/sparc64/kernel/pci_schizo.c2
-rw-r--r--arch/sparc64/kernel/process.c4
-rw-r--r--arch/sparc64/kernel/sbus.c41
-rw-r--r--arch/sparc64/kernel/setup.c11
-rw-r--r--arch/sparc64/kernel/smp.c3
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c2
-rw-r--r--arch/sparc64/kernel/traps.c19
-rw-r--r--arch/sparc64/mm/init.c2
-rw-r--r--arch/um/Kconfig.debug4
-rw-r--r--arch/um/Kconfig_char6
-rw-r--r--arch/um/Kconfig_x86_644
-rw-r--r--arch/um/Makefile80
-rw-r--r--arch/um/Makefile-i3864
-rw-r--r--arch/um/Makefile-x86_644
-rw-r--r--arch/um/drivers/Makefile6
-rw-r--r--arch/um/drivers/chan_kern.c22
-rw-r--r--arch/um/drivers/chan_user.c26
-rw-r--r--arch/um/drivers/line.c41
-rw-r--r--arch/um/drivers/mcast_kern.c4
-rw-r--r--arch/um/drivers/mcast_user.c47
-rw-r--r--arch/um/drivers/mmapper_kern.c24
-rw-r--r--arch/um/drivers/net_user.c2
-rw-r--r--arch/um/drivers/random.c16
-rw-r--r--arch/um/drivers/slip.h23
-rw-r--r--arch/um/drivers/slip_common.c54
-rw-r--r--arch/um/drivers/slip_common.h (renamed from arch/um/drivers/slip_proto.h)47
-rw-r--r--arch/um/drivers/slip_kern.c12
-rw-r--r--arch/um/drivers/slip_user.c152
-rw-r--r--arch/um/drivers/slirp.h26
-rw-r--r--arch/um/drivers/slirp_kern.c5
-rw-r--r--arch/um/drivers/slirp_user.c104
-rw-r--r--arch/um/drivers/ssl.c1
-rw-r--r--arch/um/drivers/stderr_console.c6
-rw-r--r--arch/um/drivers/stdio_console.c1
-rw-r--r--arch/um/drivers/ubd_kern.c303
-rw-r--r--arch/um/drivers/xterm_kern.c1
-rw-r--r--arch/um/include/2_5compat.h24
-rw-r--r--arch/um/include/common-offsets.h14
-rw-r--r--arch/um/include/kern_util.h7
-rw-r--r--arch/um/include/mconsole.h2
-rw-r--r--arch/um/include/net_user.h2
-rw-r--r--arch/um/include/os.h3
-rw-r--r--arch/um/include/skas_ptrace.h15
-rw-r--r--arch/um/include/sysdep-i386/checksum.h39
-rw-r--r--arch/um/include/sysdep-i386/faultinfo.h29
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h26
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h19
-rw-r--r--arch/um/include/sysdep-i386/signal.h2
-rw-r--r--arch/um/include/sysdep-i386/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-ia64/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-ppc/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-x86_64/checksum.h26
-rw-r--r--arch/um/include/sysdep-x86_64/faultinfo.h29
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h78
-rw-r--r--arch/um/include/sysdep-x86_64/sigcontext.h15
-rw-r--r--arch/um/include/sysdep-x86_64/signal.h2
-rw-r--r--arch/um/include/sysdep-x86_64/skas_ptrace.h22
-rw-r--r--arch/um/include/sysrq.h3
-rw-r--r--arch/um/include/user_util.h4
-rw-r--r--arch/um/kernel/Makefile14
-rw-r--r--arch/um/kernel/checksum.c36
-rw-r--r--arch/um/kernel/exec_kern.c1
-rw-r--r--arch/um/kernel/initrd.c (renamed from arch/um/kernel/initrd_kern.c)21
-rw-r--r--arch/um/kernel/initrd_user.c46
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/irq_user.c10
-rw-r--r--arch/um/kernel/ksyms.c4
-rw-r--r--arch/um/kernel/main.c42
-rw-r--r--arch/um/kernel/mem.c40
-rw-r--r--arch/um/kernel/process.c51
-rw-r--r--arch/um/kernel/process_kern.c56
-rw-r--r--arch/um/kernel/ptrace.c128
-rw-r--r--arch/um/kernel/sigio_user.c1
-rw-r--r--arch/um/kernel/skas/include/mode_kern-skas.h1
-rw-r--r--arch/um/kernel/skas/include/skas.h3
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h4
-rw-r--r--arch/um/kernel/skas/process.c68
-rw-r--r--arch/um/kernel/skas/process_kern.c11
-rw-r--r--arch/um/kernel/skas/trap_user.c24
-rw-r--r--arch/um/kernel/skas/uaccess.c7
-rw-r--r--arch/um/kernel/skas/util/Makefile1
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-i386.c46
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-x86_64.c60
-rw-r--r--arch/um/kernel/syscall_kern.c1
-rw-r--r--arch/um/kernel/sysrq.c21
-rw-r--r--arch/um/kernel/time_kern.c18
-rw-r--r--arch/um/kernel/trap_kern.c64
-rw-r--r--arch/um/kernel/trap_user.c13
-rw-r--r--arch/um/kernel/tt/Makefile1
-rw-r--r--arch/um/kernel/tt/include/mode_kern-tt.h1
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h4
-rw-r--r--arch/um/kernel/tt/ksyms.c1
-rw-r--r--arch/um/kernel/tt/mem.c8
-rw-r--r--arch/um/kernel/tt/process_kern.c26
-rw-r--r--arch/um/kernel/tt/syscall_user.c4
-rw-r--r--arch/um/kernel/tt/tracer.c8
-rw-r--r--arch/um/kernel/tt/trap_user.c6
-rw-r--r--arch/um/kernel/um_arch.c14
-rw-r--r--arch/um/kernel/uml.lds.S2
-rw-r--r--arch/um/kernel/vmlinux.lds.S6
-rw-r--r--arch/um/os-Linux/elf_aux.c6
-rw-r--r--arch/um/os-Linux/file.c2
-rw-r--r--arch/um/os-Linux/process.c5
-rw-r--r--arch/um/os-Linux/signal.c4
-rw-r--r--arch/um/os-Linux/util/Makefile2
-rw-r--r--arch/um/os-Linux/util/mk_user_constants.c10
-rw-r--r--arch/um/scripts/Makefile.rules25
-rw-r--r--arch/um/sys-i386/Makefile13
-rw-r--r--arch/um/sys-i386/checksum.S6
-rw-r--r--arch/um/sys-i386/delay.c26
-rw-r--r--arch/um/sys-i386/kernel-offsets.c25
-rw-r--r--arch/um/sys-i386/ksyms.c8
-rw-r--r--arch/um/sys-i386/ldt.c5
-rw-r--r--arch/um/sys-i386/ptrace.c40
-rw-r--r--arch/um/sys-i386/signal.c17
-rw-r--r--arch/um/sys-i386/sysrq.c80
-rw-r--r--arch/um/sys-i386/user-offsets.c69
-rw-r--r--arch/um/sys-i386/util/Makefile7
-rw-r--r--arch/um/sys-i386/util/mk_sc.c75
-rw-r--r--arch/um/sys-i386/util/mk_thread.c22
-rw-r--r--arch/um/sys-i386/util/mk_thread_kern.c22
-rw-r--r--arch/um/sys-i386/util/mk_thread_user.c30
-rw-r--r--arch/um/sys-ppc/ptrace.c40
-rw-r--r--arch/um/sys-ppc/sysrq.c14
-rw-r--r--arch/um/sys-x86_64/Makefile22
-rw-r--r--arch/um/sys-x86_64/delay.c39
-rw-r--r--arch/um/sys-x86_64/kernel-offsets.c24
-rw-r--r--arch/um/sys-x86_64/ksyms.c19
-rw-r--r--arch/um/sys-x86_64/ptrace.c53
-rw-r--r--arch/um/sys-x86_64/signal.c12
-rw-r--r--arch/um/sys-x86_64/syscalls.c21
-rw-r--r--arch/um/sys-x86_64/sysrq.c11
-rw-r--r--arch/um/sys-x86_64/um_module.c19
-rw-r--r--arch/um/sys-x86_64/user-offsets.c86
-rw-r--r--arch/um/sys-x86_64/util/Makefile6
-rw-r--r--arch/um/sys-x86_64/util/mk_sc.c79
-rw-r--r--arch/um/sys-x86_64/util/mk_thread.c20
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_kern.c21
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_user.c30
-rw-r--r--arch/um/util/Makefile7
-rw-r--r--arch/um/util/mk_constants.c32
-rw-r--r--arch/um/util/mk_constants_kern.c28
-rw-r--r--arch/um/util/mk_constants_user.c28
-rw-r--r--arch/um/util/mk_task.c (renamed from arch/um/util/mk_task_user.c)18
-rw-r--r--arch/um/util/mk_task_kern.c17
-rw-r--r--arch/x86_64/Kconfig22
-rw-r--r--arch/x86_64/boot/bootsect.S4
-rw-r--r--arch/x86_64/defconfig58
-rw-r--r--arch/x86_64/kernel/Makefile1
-rw-r--r--arch/x86_64/kernel/aperture.c41
-rw-r--r--arch/x86_64/kernel/apic.c5
-rw-r--r--arch/x86_64/kernel/entry.S11
-rw-r--r--arch/x86_64/kernel/io_apic.c82
-rw-r--r--arch/x86_64/kernel/kprobes.c7
-rw-r--r--arch/x86_64/kernel/module.c4
-rw-r--r--arch/x86_64/kernel/mpparse.c23
-rw-r--r--arch/x86_64/kernel/nmi.c248
-rw-r--r--arch/x86_64/kernel/pmtimer.c101
-rw-r--r--arch/x86_64/kernel/ptrace.c38
-rw-r--r--arch/x86_64/kernel/setup.c30
-rw-r--r--arch/x86_64/kernel/signal.c5
-rw-r--r--arch/x86_64/kernel/smpboot.c263
-rw-r--r--arch/x86_64/kernel/time.c64
-rw-r--r--arch/x86_64/kernel/traps.c2
-rw-r--r--arch/x86_64/kernel/vsyscall.c5
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c16
-rw-r--r--arch/x86_64/mm/fault.c11
-rw-r--r--arch/x86_64/mm/ioremap.c29
-rw-r--r--crypto/crypto_null.c28
-rw-r--r--crypto/internal.h2
-rw-r--r--drivers/acpi/Kconfig5
-rw-r--r--drivers/acpi/pci_irq.c4
-rw-r--r--drivers/atm/Makefile3
-rw-r--r--drivers/atm/fore200e.c6
-rw-r--r--drivers/atm/he.c6
-rw-r--r--drivers/atm/nicstar.c20
-rw-r--r--drivers/atm/zatm.c11
-rw-r--r--drivers/base/Makefile2
-rw-r--r--drivers/base/bus.c6
-rw-r--r--drivers/base/core.c9
-rw-r--r--drivers/base/interface.c51
-rw-r--r--drivers/base/power/power.h11
-rw-r--r--drivers/base/power/resume.c11
-rw-r--r--drivers/base/power/shutdown.c23
-rw-r--r--drivers/base/power/suspend.c17
-rw-r--r--drivers/block/DAC960.c132
-rw-r--r--drivers/block/DAC960.h317
-rw-r--r--drivers/block/Kconfig2
-rw-r--r--drivers/block/aoe/aoe.h2
-rw-r--r--drivers/block/aoe/aoeblk.c13
-rw-r--r--drivers/block/aoe/aoedev.c11
-rw-r--r--drivers/block/aoe/aoenet.c17
-rw-r--r--drivers/block/floppy.c2
-rw-r--r--drivers/block/genhd.c4
-rw-r--r--drivers/block/ioctl.c2
-rw-r--r--drivers/block/pktcdvd.c16
-rw-r--r--drivers/block/ub.c598
-rw-r--r--drivers/cdrom/cdu31a.c6
-rw-r--r--drivers/cdrom/mcdx.c28
-rw-r--r--drivers/cdrom/sbpcd.c2
-rw-r--r--drivers/cdrom/viocd.c14
-rw-r--r--drivers/char/Kconfig6
-rw-r--r--drivers/char/agp/agp.h2
-rw-r--r--drivers/char/agp/ali-agp.c4
-rw-r--r--drivers/char/agp/amd-k7-agp.c6
-rw-r--r--drivers/char/agp/amd64-agp.c4
-rw-r--r--drivers/char/agp/ati-agp.c6
-rw-r--r--drivers/char/agp/backend.c6
-rw-r--r--drivers/char/agp/efficeon-agp.c2
-rw-r--r--drivers/char/agp/generic.c36
-rw-r--r--drivers/char/agp/hp-agp.c4
-rw-r--r--drivers/char/agp/i460-agp.c4
-rw-r--r--drivers/char/agp/intel-agp.c21
-rw-r--r--drivers/char/agp/sgi-agp.c12
-rw-r--r--drivers/char/agp/sworks-agp.c8
-rw-r--r--drivers/char/agp/uninorth-agp.c2
-rw-r--r--drivers/char/drm/drm_pciids.h1
-rw-r--r--drivers/char/drm/radeon_irq.c5
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c20
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c32
-rw-r--r--drivers/char/ipmi/ipmi_si_sm.h2
-rw-r--r--drivers/char/keyboard.c3
-rw-r--r--drivers/char/mbcs.c4
-rw-r--r--drivers/char/mbcs.h4
-rw-r--r--drivers/char/mxser.c38
-rw-r--r--drivers/char/raw.c2
-rw-r--r--drivers/char/sonypi.c6
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/char/watchdog/i8xx_tco.c1
-rw-r--r--drivers/cpufreq/Kconfig24
-rw-r--r--drivers/cpufreq/Makefile1
-rw-r--r--drivers/cpufreq/cpufreq.c8
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c586
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c180
-rw-r--r--drivers/cpufreq/cpufreq_stats.c47
-rw-r--r--drivers/firmware/pcdp.c1
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c46
-rw-r--r--drivers/i2c/busses/i2c-keywest.c5
-rw-r--r--drivers/ide/ide-cd.c52
-rw-r--r--drivers/ide/ide-disk.c41
-rw-r--r--drivers/ide/ide-floppy.c42
-rw-r--r--drivers/ide/ide-probe.c51
-rw-r--r--drivers/ide/ide-proc.c54
-rw-r--r--drivers/ide/ide-tape.c51
-rw-r--r--drivers/ide/ide.c307
-rw-r--r--drivers/ide/pci/amd74xx.c3
-rw-r--r--drivers/ide/pci/sis5513.c6
-rw-r--r--drivers/ieee1394/Kconfig5
-rw-r--r--drivers/ieee1394/ieee1394_core.c3
-rw-r--r--drivers/ieee1394/ieee1394_transactions.c3
-rw-r--r--drivers/ieee1394/ieee1394_transactions.h7
-rw-r--r--drivers/ieee1394/nodemgr.c3
-rw-r--r--drivers/ieee1394/ohci1394.c2
-rw-r--r--drivers/ieee1394/ohci1394.h3
-rw-r--r--drivers/ieee1394/pcilynx.c394
-rw-r--r--drivers/ieee1394/pcilynx.h49
-rw-r--r--drivers/ieee1394/video1394.c139
-rw-r--r--drivers/infiniband/core/sa_query.c35
-rw-r--r--drivers/infiniband/core/user_mad.c4
-rw-r--r--drivers/infiniband/include/ib_sa.h4
-rw-r--r--drivers/input/gameport/Kconfig20
-rw-r--r--drivers/input/joydev.c2
-rw-r--r--drivers/input/keyboard/atkbd.c14
-rw-r--r--drivers/input/mouse/alps.c4
-rw-r--r--drivers/input/mouse/psmouse-base.c7
-rw-r--r--drivers/input/mouse/synaptics.c39
-rw-r--r--drivers/input/mousedev.c15
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h32
-rw-r--r--drivers/input/serio/i8042.c50
-rw-r--r--drivers/input/serio/serio.c25
-rw-r--r--drivers/input/serio/serport.c98
-rw-r--r--drivers/input/touchscreen/gunze.c3
-rw-r--r--drivers/macintosh/therm_adt746x.c125
-rw-r--r--drivers/macintosh/via-pmu.c12
-rw-r--r--drivers/md/dm-emc.c6
-rw-r--r--drivers/md/dm-hw-handler.c2
-rw-r--r--drivers/md/dm-mpath.c35
-rw-r--r--drivers/md/dm-path-selector.c2
-rw-r--r--drivers/md/dm-table.c2
-rw-r--r--drivers/md/dm-zero.c4
-rw-r--r--drivers/md/dm.c96
-rw-r--r--drivers/md/linear.c5
-rw-r--r--drivers/md/md.c14
-rw-r--r--drivers/md/multipath.c11
-rw-r--r--drivers/md/raid1.c7
-rw-r--r--drivers/md/raid10.c6
-rw-r--r--drivers/md/raid5.c7
-rw-r--r--drivers/md/raid6main.c6
-rw-r--r--drivers/media/common/saa7146_core.c4
-rw-r--r--drivers/media/dvb/Kconfig2
-rw-r--r--drivers/media/dvb/b2c2/Kconfig50
-rw-r--r--drivers/media/dvb/b2c2/Makefile12
-rw-r--r--drivers/media/dvb/b2c2/b2c2-common.c214
-rw-r--r--drivers/media/dvb/b2c2/b2c2-usb-core.c549
-rw-r--r--drivers/media/dvb/b2c2/flexcop-common.h164
-rw-r--r--drivers/media/dvb/b2c2/flexcop-dma.c149
-rw-r--r--drivers/media/dvb/b2c2/flexcop-eeprom.c153
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c403
-rw-r--r--drivers/media/dvb/b2c2/flexcop-hw-filter.c204
-rw-r--r--drivers/media/dvb/b2c2/flexcop-i2c.c210
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c66
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c381
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h701
-rw-r--r--drivers/media/dvb/b2c2/flexcop-sram.c403
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.c577
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.h119
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c286
-rw-r--r--drivers/media/dvb/b2c2/flexcop.h30
-rw-r--r--drivers/media/dvb/b2c2/skystar2.c20
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig3
-rw-r--r--drivers/media/dvb/bt8xx/Makefile4
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c54
-rw-r--r--drivers/media/dvb/bt8xx/bt878.h6
-rw-r--r--drivers/media/dvb/bt8xx/dst.c969
-rw-r--r--drivers/media/dvb/bt8xx/dst.h40
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c861
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.h58
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h153
-rw-r--r--drivers/media/dvb/bt8xx/dst_priv.h1
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c121
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h4
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c12
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-dvb.c10
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c4
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb.h2
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c32
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c38
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c36
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c75
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c9
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h2
-rw-r--r--drivers/media/dvb/frontends/Kconfig22
-rw-r--r--drivers/media/dvb/frontends/at76c651.c18
-rw-r--r--drivers/media/dvb/frontends/cx22700.c20
-rw-r--r--drivers/media/dvb/frontends/cx22702.c20
-rw-r--r--drivers/media/dvb/frontends/cx24110.c31
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c28
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c26
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h10
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c8
-rw-r--r--drivers/media/dvb/frontends/l64781.c22
-rw-r--r--drivers/media/dvb/frontends/mt312.c32
-rw-r--r--drivers/media/dvb/frontends/mt352.c40
-rw-r--r--drivers/media/dvb/frontends/mt352.h7
-rw-r--r--drivers/media/dvb/frontends/nxt2002.c22
-rw-r--r--drivers/media/dvb/frontends/nxt6000.c56
-rw-r--r--drivers/media/dvb/frontends/nxt6000_priv.h21
-rw-r--r--drivers/media/dvb/frontends/or51132.c14
-rw-r--r--drivers/media/dvb/frontends/sp8870.c20
-rw-r--r--drivers/media/dvb/frontends/sp887x.c22
-rw-r--r--drivers/media/dvb/frontends/stv0297.c24
-rw-r--r--drivers/media/dvb/frontends/stv0299.c114
-rw-r--r--drivers/media/dvb/frontends/tda10021.c22
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c284
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h7
-rw-r--r--drivers/media/dvb/frontends/tda8083.c26
-rw-r--r--drivers/media/dvb/frontends/tda80xx.c36
-rw-r--r--drivers/media/dvb/frontends/ves1820.c23
-rw-r--r--drivers/media/dvb/frontends/ves1x93.c24
-rw-r--r--drivers/media/dvb/ttpci/av7110.c144
-rw-r--r--drivers/media/dvb/ttpci/av7110.h3
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c12
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c4
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c20
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h5
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c16
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c226
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c6
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c12
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c4
-rw-r--r--drivers/media/dvb/ttpci/budget.c4
-rw-r--r--drivers/media/dvb/ttpci/budget.h5
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c22
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c28
-rw-r--r--drivers/media/video/Kconfig1
-rw-r--r--drivers/media/video/bttv-cards.c1
-rw-r--r--drivers/media/video/bttv-i2c.c17
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c89
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c20
-rw-r--r--drivers/media/video/tuner-core.c14
-rw-r--r--drivers/media/video/video-buf-dvb.c12
-rw-r--r--drivers/message/i2o/i2o_block.c1
-rw-r--r--drivers/mmc/Kconfig2
-rw-r--r--drivers/mmc/mmc_block.c5
-rw-r--r--drivers/mmc/wbsd.c716
-rw-r--r--drivers/mmc/wbsd.h12
-rw-r--r--drivers/net/3c59x.c9
-rw-r--r--drivers/net/Kconfig20
-rw-r--r--drivers/net/Makefile3
-rw-r--r--drivers/net/Space.c2
-rwxr-xr-xdrivers/net/amd8111e.c24
-rw-r--r--drivers/net/appletalk/Kconfig2
-rw-r--r--drivers/net/appletalk/cops.c4
-rw-r--r--drivers/net/appletalk/cops_ffdrv.h2
-rw-r--r--drivers/net/appletalk/cops_ltdrv.h2
-rw-r--r--drivers/net/appletalk/ltpc.c2
-rw-r--r--drivers/net/arcnet/capmode.c2
-rw-r--r--drivers/net/bnx2.c5530
-rw-r--r--drivers/net/bnx2.h4352
-rw-r--r--drivers/net/bnx2_fw.h2468
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--drivers/net/e100.c165
-rw-r--r--drivers/net/e1000/e1000.h37
-rw-r--r--drivers/net/e1000/e1000_ethtool.c105
-rw-r--r--drivers/net/e1000/e1000_hw.c1987
-rw-r--r--drivers/net/e1000/e1000_hw.h570
-rw-r--r--drivers/net/e1000/e1000_main.c1147
-rw-r--r--drivers/net/e1000/e1000_osdep.h32
-rw-r--r--drivers/net/e1000/e1000_param.c3
-rw-r--r--drivers/net/forcedeth.c103
-rw-r--r--drivers/net/hamradio/Kconfig4
-rw-r--r--drivers/net/hamradio/baycom_epp.c126
-rw-r--r--drivers/net/ibm_emac/ibm_emac_core.c2
-rw-r--r--drivers/net/irda/Kconfig12
-rw-r--r--drivers/net/iseries_veth.c41
-rw-r--r--drivers/net/ixgb/ixgb.h2
-rw-r--r--drivers/net/ixgb/ixgb_ee.c24
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c4
-rw-r--r--drivers/net/ixgb/ixgb_main.c153
-rw-r--r--drivers/net/ixgb/ixgb_osdep.h3
-rw-r--r--drivers/net/loopback.c2
-rw-r--r--drivers/net/natsemi.c6
-rw-r--r--drivers/net/ns83820.c69
-rw-r--r--drivers/net/pcmcia/3c574_cs.c3
-rw-r--r--drivers/net/pcnet32.c7
-rw-r--r--drivers/net/r8169.c33
-rw-r--r--drivers/net/shaper.c86
-rw-r--r--drivers/net/sis900.c52
-rw-r--r--drivers/net/tg3.c1147
-rw-r--r--drivers/net/tg3.h8
-rw-r--r--drivers/net/tlan.c12
-rw-r--r--drivers/net/tulip/media.c1
-rw-r--r--drivers/net/tulip/tulip_core.c2
-rw-r--r--drivers/net/wan/Kconfig6
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/airo.c150
-rw-r--r--drivers/net/wireless/atmel_cs.c1
-rw-r--r--drivers/parport/Kconfig2
-rw-r--r--drivers/parport/parport_pc.c34
-rw-r--r--drivers/pci/hotplug.c119
-rw-r--r--drivers/pci/hotplug/cpci_hotplug.h2
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c429
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c483
-rw-r--r--drivers/pci/hotplug/ibmphp.h2
-rw-r--r--drivers/pci/hotplug/ibmphp_hpc.c6
-rw-r--r--drivers/pci/hotplug/ibmphp_pci.c7
-rw-r--r--drivers/pci/hotplug/pci_hotplug.h2
-rw-r--r--drivers/pci/hotplug/pciehp.h1
-rw-r--r--drivers/pci/hotplug/pciehp_core.c25
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c156
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c2
-rw-r--r--drivers/pci/hotplug/shpchp_core.c2
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c30
-rw-r--r--drivers/pci/hotplug/shpchprm_acpi.c4
-rw-r--r--drivers/pci/msi.c6
-rw-r--r--drivers/pci/pci-acpi.c2
-rw-r--r--drivers/pci/pci-driver.c11
-rw-r--r--drivers/pci/pci-sysfs.c94
-rw-r--r--drivers/pci/pci.c20
-rw-r--r--drivers/pci/pci.h27
-rw-r--r--drivers/pci/pci.ids1
-rw-r--r--drivers/pci/pcie/portdrv_bus.c3
-rw-r--r--drivers/pci/probe.c3
-rw-r--r--drivers/pci/proc.c1
-rw-r--r--drivers/pci/quirks.c61
-rw-r--r--drivers/pcmcia/ds.c4
-rw-r--r--drivers/pcmcia/pd6729.c2
-rw-r--r--drivers/pcmcia/ti113x.h40
-rw-r--r--drivers/s390/block/dasd.c16
-rw-r--r--drivers/s390/net/Makefile3
-rw-r--r--drivers/s390/net/ctcdbug.h12
-rw-r--r--drivers/s390/net/ctcmain.c616
-rw-r--r--drivers/s390/net/ctcmain.h276
-rw-r--r--drivers/s390/net/ctctty.c5
-rw-r--r--drivers/s390/net/cu3088.c4
-rw-r--r--drivers/s390/net/cu3088.h3
-rw-r--r--drivers/s390/net/iucv.c10
-rw-r--r--drivers/s390/net/lcs.c33
-rw-r--r--drivers/s390/net/qeth.h35
-rw-r--r--drivers/s390/net/qeth_eddp.c51
-rw-r--r--drivers/s390/net/qeth_main.c316
-rw-r--r--drivers/s390/net/qeth_tso.c285
-rw-r--r--drivers/s390/net/qeth_tso.h166
-rw-r--r--drivers/s390/scsi/zfcp_aux.c2
-rw-r--r--drivers/s390/scsi/zfcp_def.h1
-rw-r--r--drivers/sbus/char/aurora.c8
-rw-r--r--drivers/scsi/Kconfig14
-rw-r--r--drivers/scsi/NCR53C9x.c5
-rw-r--r--drivers/scsi/aacraid/linit.c2
-rw-r--r--drivers/scsi/ahci.c3
-rw-r--r--drivers/scsi/aic7xxx/aic7770_osm.c52
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c2
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c1405
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h175
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm_pci.c11
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_proc.c13
-rw-r--r--drivers/scsi/aic7xxx/aiclib.c1
-rw-r--r--drivers/scsi/ata_piix.c18
-rw-r--r--drivers/scsi/ide-scsi.c86
-rw-r--r--drivers/scsi/libata-core.c512
-rw-r--r--drivers/scsi/libata-scsi.c7
-rw-r--r--drivers/scsi/libata.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c27
-rw-r--r--drivers/scsi/sata_nv.c2
-rw-r--r--drivers/scsi/sata_promise.c3
-rw-r--r--drivers/scsi/sata_qstor.c2
-rw-r--r--drivers/scsi/sata_sil.c10
-rw-r--r--drivers/scsi/sata_sis.c1
-rw-r--r--drivers/scsi/sata_svw.c3
-rw-r--r--drivers/scsi/sata_sx4.c2
-rw-r--r--drivers/scsi/sata_uli.c1
-rw-r--r--drivers/scsi/sata_via.c1
-rw-r--r--drivers/scsi/sata_vsc.c2
-rw-r--r--drivers/scsi/scsi.c2
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/scsi_transport_spi.c237
-rw-r--r--drivers/scsi/sr_ioctl.c3
-rw-r--r--drivers/scsi/sym53c416.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c5
-rw-r--r--drivers/serial/21285.c14
-rw-r--r--drivers/serial/8250.c32
-rw-r--r--drivers/serial/8250_pci.c2
-rw-r--r--drivers/serial/amba-pl010.c14
-rw-r--r--drivers/serial/amba-pl011.c14
-rw-r--r--drivers/serial/clps711x.c5
-rw-r--r--drivers/serial/pxa.c16
-rw-r--r--drivers/serial/s3c2410.c15
-rw-r--r--drivers/serial/sa1100.c7
-rw-r--r--drivers/serial/serial_cs.c4
-rw-r--r--drivers/serial/serial_lh7a40x.c13
-rw-r--r--drivers/serial/serial_txx9.c15
-rw-r--r--drivers/serial/sunsab.c109
-rw-r--r--drivers/serial/sunsab.h1
-rw-r--r--drivers/serial/vr41xx_siu.c72
-rw-r--r--drivers/telephony/ixj.c18
-rw-r--r--drivers/telephony/ixj.h2
-rw-r--r--drivers/usb/atm/speedtch.c2
-rw-r--r--drivers/usb/core/message.c4
-rw-r--r--drivers/usb/core/sysfs.c32
-rw-r--r--drivers/usb/core/urb.c6
-rw-r--r--drivers/usb/gadget/ether.c2
-rw-r--r--drivers/usb/gadget/inode.c2
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c2
-rw-r--r--drivers/usb/gadget/serial.c2
-rw-r--r--drivers/usb/host/Kconfig11
-rw-r--r--drivers/usb/host/Makefile1
-rw-r--r--drivers/usb/host/ehci-hcd.c65
-rw-r--r--drivers/usb/host/ehci-hub.c8
-rw-r--r--drivers/usb/host/ehci.h19
-rw-r--r--drivers/usb/host/hc_crisv10.c2
-rw-r--r--drivers/usb/host/sl811-hcd.c150
-rw-r--r--drivers/usb/host/sl811_cs.c442
-rw-r--r--drivers/usb/image/mdc800.c2
-rw-r--r--drivers/usb/input/aiptek.c2
-rw-r--r--drivers/usb/input/hid-core.c18
-rw-r--r--drivers/usb/input/mtouchusb.c2
-rw-r--r--drivers/usb/media/ov511.c2
-rw-r--r--drivers/usb/media/pwc/ChangeLog143
-rw-r--r--drivers/usb/media/pwc/Makefile2
-rw-r--r--drivers/usb/media/pwc/pwc-ctrl.c16
-rw-r--r--drivers/usb/media/pwc/pwc-dec1.c42
-rw-r--r--drivers/usb/media/pwc/pwc-dec1.h36
-rw-r--r--drivers/usb/media/pwc/pwc-dec23.c623
-rw-r--r--drivers/usb/media/pwc/pwc-dec23.h58
-rw-r--r--drivers/usb/media/pwc/pwc-if.c19
-rw-r--r--drivers/usb/media/pwc/pwc-ioctl.h2
-rw-r--r--drivers/usb/media/pwc/pwc-kiara.c573
-rw-r--r--drivers/usb/media/pwc/pwc-timon.c1130
-rw-r--r--drivers/usb/media/pwc/pwc-uncompress.c4
-rw-r--r--drivers/usb/misc/legousbtower.c2
-rw-r--r--drivers/usb/net/Kconfig14
-rw-r--r--drivers/usb/net/usbnet.c50
-rw-r--r--drivers/usb/net/zd1201.c8
-rw-r--r--drivers/usb/serial/Kconfig20
-rw-r--r--drivers/usb/serial/Makefile2
-rw-r--r--drivers/usb/serial/airprime.c63
-rw-r--r--drivers/usb/serial/cp2101.c363
-rw-r--r--drivers/usb/serial/cypress_m8.c189
-rw-r--r--drivers/usb/serial/cypress_m8.h1
-rw-r--r--drivers/usb/serial/ftdi_sio.c167
-rw-r--r--drivers/usb/serial/ftdi_sio.h38
-rw-r--r--drivers/usb/serial/io_usbvend.h2
-rw-r--r--drivers/usb/serial/keyspan_usa90msg.h2
-rw-r--r--drivers/usb/serial/option.c729
-rw-r--r--drivers/usb/serial/usb-serial.c20
-rw-r--r--drivers/usb/storage/debug.c1
-rw-r--r--drivers/usb/storage/shuttle_usbat.c2
-rw-r--r--drivers/usb/storage/unusual_devs.h26
-rw-r--r--drivers/video/aty/radeon_base.c7
-rw-r--r--drivers/video/fbmem.c2
-rw-r--r--drivers/video/fbsysfs.c4
-rw-r--r--drivers/video/i810/i810_main.c6
-rw-r--r--drivers/video/intelfb/intelfbdrv.c22
-rw-r--r--drivers/video/macmodes.c1
-rw-r--r--drivers/video/sis/init.c4
-rw-r--r--drivers/video/sis/init.h3
-rw-r--r--drivers/video/sis/init301.c9
-rw-r--r--drivers/video/sis/init301.h4
-rw-r--r--drivers/video/sis/sis_main.c5
-rw-r--r--fs/bad_inode.c2
-rw-r--r--fs/binfmt_elf.c4
-rw-r--r--fs/binfmt_flat.c6
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/buffer.c28
-rw-r--r--fs/char_dev.c2
-rw-r--r--fs/cifs/CHANGES3
-rw-r--r--fs/cifs/README10
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c56
-rw-r--r--fs/cifs/dir.c3
-rw-r--r--fs/cifs/file.c2
-rw-r--r--fs/cifs/inode.c48
-rw-r--r--fs/cifs/misc.c1
-rw-r--r--fs/dcache.c2
-rw-r--r--fs/eventpoll.c2
-rw-r--r--fs/exec.c7
-rw-r--r--fs/ext3/inode.c46
-rw-r--r--fs/ext3/super.c10
-rw-r--r--fs/hostfs/hostfs_kern.c11
-rw-r--r--fs/inode.c23
-rw-r--r--fs/jbd/checkpoint.c5
-rw-r--r--fs/jffs2/compr_rubin.c18
-rw-r--r--fs/jffs2/compr_zlib.c12
-rw-r--r--fs/jfs/jfs_xtree.c6
-rw-r--r--fs/locks.c6
-rw-r--r--fs/mbcache.c2
-rw-r--r--fs/mpage.c19
-rw-r--r--fs/namei.c182
-rw-r--r--fs/nfs/dir.c49
-rw-r--r--fs/nfs/file.c42
-rw-r--r--fs/nfs/idmap.c4
-rw-r--r--fs/nfs/inode.c4
-rw-r--r--fs/nls/nls_base.c2
-rw-r--r--fs/partitions/msdos.c5
-rw-r--r--fs/proc/base.c2
-rw-r--r--fs/proc/mmu.c14
-rw-r--r--fs/proc/proc_devtree.c105
-rw-r--r--fs/reiserfs/namei.c2
-rw-r--r--fs/reiserfs/stree.c1
-rw-r--r--fs/reiserfs/super.c4
-rw-r--r--fs/select.c6
-rw-r--r--fs/udf/udftime.c4
-rw-r--r--fs/xfs/Makefile2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c80
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c50
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c29
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.h6
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c3
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c3
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c5
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h10
-rw-r--r--fs/xfs/xfs_dfrag.c2
-rw-r--r--fs/xfs/xfs_iget.c51
-rw-r--r--fs/xfs/xfs_inode.c2
-rw-r--r--fs/xfs/xfs_inode.h6
-rw-r--r--fs/xfs/xfs_iomap.c30
-rw-r--r--fs/xfs/xfs_iomap.h25
-rw-r--r--fs/xfs/xfs_mount.c9
-rw-r--r--fs/xfs/xfs_mount.h19
-rw-r--r--fs/xfs/xfs_types.h1
-rw-r--r--fs/xfs/xfs_utils.c2
-rw-r--r--fs/xfs/xfs_utils.h2
-rw-r--r--fs/xfs/xfs_vfsops.c67
-rw-r--r--fs/xfs/xfs_vnodeops.c11
-rw-r--r--include/asm-alpha/agp.h10
-rw-r--r--include/asm-alpha/signal.h11
-rw-r--r--include/asm-arm/arch-imx/imx-regs.h24
-rw-r--r--include/asm-arm/arch-imx/imxfb.h35
-rw-r--r--include/asm-arm/arch-ixp2000/io.h16
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h2
-rw-r--r--include/asm-arm/arch-s3c2410/regs-nand.h44
-rw-r--r--include/asm-arm/elf.h4
-rw-r--r--include/asm-arm/page.h18
-rw-r--r--include/asm-arm/processor.h7
-rw-r--r--include/asm-arm/signal.h15
-rw-r--r--include/asm-arm/thread_info.h6
-rw-r--r--include/asm-arm26/elf.h2
-rw-r--r--include/asm-arm26/signal.h14
-rw-r--r--include/asm-cris/signal.h11
-rw-r--r--include/asm-frv/signal.h11
-rw-r--r--include/asm-generic/sections.h2
-rw-r--r--include/asm-generic/signal.h21
-rw-r--r--include/asm-h8300/kmap_types.h6
-rw-r--r--include/asm-h8300/mman.h3
-rw-r--r--include/asm-h8300/signal.h11
-rw-r--r--include/asm-i386/agp.h10
-rw-r--r--include/asm-i386/floppy.h2
-rw-r--r--include/asm-i386/linkage.h4
-rw-r--r--include/asm-i386/mach-numaq/mach_ipi.h2
-rw-r--r--include/asm-i386/module.h4
-rw-r--r--include/asm-i386/signal.h15
-rw-r--r--include/asm-i386/timer.h1
-rw-r--r--include/asm-ia64/agp.h10
-rw-r--r--include/asm-ia64/ioctl32.h1
-rw-r--r--include/asm-ia64/perfmon.h8
-rw-r--r--include/asm-ia64/pgtable.h8
-rw-r--r--include/asm-ia64/processor.h10
-rw-r--r--include/asm-ia64/signal.h11
-rw-r--r--include/asm-ia64/sn/addrs.h8
-rw-r--r--include/asm-ia64/sn/arch.h17
-rw-r--r--include/asm-ia64/sn/fetchop.h85
-rw-r--r--include/asm-ia64/sn/l1.h3
-rw-r--r--include/asm-ia64/sn/nodepda.h15
-rw-r--r--include/asm-ia64/sn/pda.h9
-rw-r--r--include/asm-ia64/sn/shub_mmr.h24
-rw-r--r--include/asm-ia64/sn/shubio.h3116
-rw-r--r--include/asm-ia64/sn/sn_cpuid.h25
-rw-r--r--include/asm-ia64/sn/sn_fru.h44
-rw-r--r--include/asm-ia64/sn/sn_sal.h93
-rw-r--r--include/asm-ia64/sn/sndrv.h47
-rw-r--r--include/asm-ia64/sn/xp.h436
-rw-r--r--include/asm-m32r/signal.h15
-rw-r--r--include/asm-m68k/signal.h15
-rw-r--r--include/asm-m68knommu/signal.h11
-rw-r--r--include/asm-mips/signal.h9
-rw-r--r--include/asm-parisc/floppy.h2
-rw-r--r--include/asm-ppc/agp.h10
-rw-r--r--include/asm-ppc/cpm2.h46
-rw-r--r--include/asm-ppc/m8260_pci.h1
-rw-r--r--include/asm-ppc/mpc8260.h2
-rw-r--r--include/asm-ppc/sigcontext.h2
-rw-r--r--include/asm-ppc/signal.h15
-rw-r--r--include/asm-ppc64/agp.h10
-rw-r--r--include/asm-ppc64/elf.h4
-rw-r--r--include/asm-ppc64/iSeries/mf.h1
-rw-r--r--include/asm-ppc64/imalloc.h24
-rw-r--r--include/asm-ppc64/mmu.h193
-rw-r--r--include/asm-ppc64/mmu_context.h82
-rw-r--r--include/asm-ppc64/page.h15
-rw-r--r--include/asm-ppc64/pgtable.h117
-rw-r--r--include/asm-ppc64/processor.h186
-rw-r--r--include/asm-ppc64/prom.h13
-rw-r--r--include/asm-ppc64/signal.h20
-rw-r--r--include/asm-ppc64/thread_info.h4
-rw-r--r--include/asm-ppc64/xics.h3
-rw-r--r--include/asm-s390/signal.h11
-rw-r--r--include/asm-s390/user.h2
-rw-r--r--include/asm-sh/floppy.h2
-rw-r--r--include/asm-sh/signal.h11
-rw-r--r--include/asm-sh/thread_info.h2
-rw-r--r--include/asm-sh64/signal.h11
-rw-r--r--include/asm-sh64/thread_info.h2
-rw-r--r--include/asm-sparc/floppy.h2
-rw-r--r--include/asm-sparc/signal.h11
-rw-r--r--include/asm-sparc/uaccess.h5
-rw-r--r--include/asm-sparc64/agp.h10
-rw-r--r--include/asm-sparc64/iommu.h2
-rw-r--r--include/asm-sparc64/parport.h6
-rw-r--r--include/asm-sparc64/pbm.h8
-rw-r--r--include/asm-sparc64/pgalloc.h9
-rw-r--r--include/asm-sparc64/signal.h16
-rw-r--r--include/asm-sparc64/spitfire.h3
-rw-r--r--include/asm-um/arch-signal-i386.h24
-rw-r--r--include/asm-um/archparam-i386.h137
-rw-r--r--include/asm-um/archparam-ppc.h20
-rw-r--r--include/asm-um/archparam-x86_64.h36
-rw-r--r--include/asm-um/delay.h2
-rw-r--r--include/asm-um/elf-i386.h169
-rw-r--r--include/asm-um/elf-ppc.h (renamed from include/asm-um/elf.h)25
-rw-r--r--include/asm-um/elf-x86_64.h95
-rw-r--r--include/asm-um/fixmap.h1
-rw-r--r--include/asm-um/ipc.h7
-rw-r--r--include/asm-um/linkage.h7
-rw-r--r--include/asm-um/page.h11
-rw-r--r--include/asm-um/pgtable-3level.h2
-rw-r--r--include/asm-um/pgtable.h10
-rw-r--r--include/asm-um/processor-generic.h5
-rw-r--r--include/asm-um/processor-i386.h7
-rw-r--r--include/asm-um/processor-x86_64.h12
-rw-r--r--include/asm-um/ptrace-i386.h2
-rw-r--r--include/asm-um/ptrace-x86_64.h2
-rw-r--r--include/asm-um/setup.h3
-rw-r--r--include/asm-um/thread_info.h13
-rw-r--r--include/asm-v850/signal.h12
-rw-r--r--include/asm-x86_64/agp.h10
-rw-r--r--include/asm-x86_64/apicdef.h2
-rw-r--r--include/asm-x86_64/bug.h2
-rw-r--r--include/asm-x86_64/floppy.h2
-rw-r--r--include/asm-x86_64/io_apic.h1
-rw-r--r--include/asm-x86_64/ioctl32.h1
-rw-r--r--include/asm-x86_64/nmi.h2
-rw-r--r--include/asm-x86_64/processor.h5
-rw-r--r--include/asm-x86_64/proto.h5
-rw-r--r--include/asm-x86_64/signal.h14
-rw-r--r--include/asm-x86_64/vsyscall.h3
-rw-r--r--include/linux/acpi.h7
-rw-r--r--include/linux/audit.h64
-rw-r--r--include/linux/awe_voice.h6
-rw-r--r--include/linux/binfmts.h1
-rw-r--r--include/linux/cpufreq.h2
-rw-r--r--include/linux/device.h3
-rw-r--r--include/linux/err.h4
-rw-r--r--include/linux/etherdevice.h24
-rw-r--r--include/linux/ethtool.h1
-rw-r--r--include/linux/fddidevice.h2
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/gameport.h28
-rw-r--r--include/linux/hardirq.h6
-rw-r--r--include/linux/hippidevice.h2
-rw-r--r--include/linux/ide.h20
-rw-r--r--include/linux/if.h2
-rw-r--r--include/linux/if_arp.h2
-rw-r--r--include/linux/if_ltalk.h2
-rw-r--r--include/linux/if_shaper.h3
-rw-r--r--include/linux/if_tr.h45
-rw-r--r--include/linux/inetdevice.h2
-rw-r--r--include/linux/ixjuser.h2
-rw-r--r--include/linux/kprobes.h3
-rw-r--r--include/linux/libata.h66
-rw-r--r--include/linux/mii.h8
-rw-r--r--include/linux/mm.h4
-rw-r--r--include/linux/mmc/protocol.h27
-rw-r--r--include/linux/mpage.h3
-rw-r--r--include/linux/net.h3
-rw-r--r--include/linux/netdevice.h9
-rw-r--r--include/linux/netlink.h1
-rw-r--r--include/linux/notifier.h1
-rw-r--r--include/linux/patchkey.h45
-rw-r--r--include/linux/pci.h3
-rw-r--r--include/linux/pci_ids.h13
-rw-r--r--include/linux/pkt_sched.h9
-rw-r--r--include/linux/sched.h7
-rw-r--r--include/linux/serial_core.h19
-rw-r--r--include/linux/signal.h2
-rw-r--r--include/linux/sockios.h2
-rw-r--r--include/linux/soundcard.h34
-rw-r--r--include/linux/spinlock.h8
-rw-r--r--include/linux/sysctl.h2
-rw-r--r--include/linux/tc_ematch/tc_em_meta.h30
-rw-r--r--include/linux/trdevice.h2
-rw-r--r--include/linux/usb.h6
-rw-r--r--include/linux/vmalloc.h1
-rw-r--r--include/linux/wait.h4
-rw-r--r--include/media/video-buf-dvb.h2
-rw-r--r--include/net/act_generic.h4
-rw-r--r--include/net/addrconf.h3
-rw-r--r--include/net/icmp.h2
-rw-r--r--include/net/ip.h3
-rw-r--r--include/net/route.h5
-rw-r--r--include/net/sock.h4
-rw-r--r--include/net/tcp.h2
-rw-r--r--include/net/udp.h2
-rw-r--r--include/net/xfrm.h2
-rw-r--r--include/scsi/scsi_transport_spi.h6
-rw-r--r--init/Kconfig4
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/audit.c93
-rw-r--r--kernel/auditsc.c47
-rw-r--r--kernel/cpuset.c24
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/irq/handle.c3
-rw-r--r--kernel/itimer.c6
-rw-r--r--kernel/kallsyms.c13
-rw-r--r--kernel/kprobes.c142
-rw-r--r--kernel/module.c6
-rw-r--r--kernel/power/main.c6
-rw-r--r--kernel/printk.c72
-rw-r--r--kernel/profile.c16
-rw-r--r--kernel/sched.c9
-rw-r--r--kernel/signal.c11
-rw-r--r--kernel/spinlock.c8
-rw-r--r--kernel/sys.c2
-rw-r--r--lib/Kconfig.debug3
-rw-r--r--lib/sort.c2
-rw-r--r--lib/string.c8
-rw-r--r--mm/filemap.c15
-rw-r--r--mm/memory.c17
-rw-r--r--mm/mmap.c63
-rw-r--r--mm/mremap.c7
-rw-r--r--mm/nommu.c3
-rw-r--r--mm/page_alloc.c2
-rw-r--r--mm/rmap.c8
-rw-r--r--mm/swapfile.c2
-rw-r--r--mm/vmalloc.c33
-rw-r--r--net/802/fddi.c2
-rw-r--r--net/802/hippi.c2
-rw-r--r--net/802/tr.c26
-rw-r--r--net/appletalk/dev.c22
-rw-r--r--net/bridge/br_device.c15
-rw-r--r--net/bridge/br_if.c23
-rw-r--r--net/bridge/br_input.c8
-rw-r--r--net/bridge/br_notify.c9
-rw-r--r--net/bridge/br_private.h1
-rw-r--r--net/bridge/br_stp_bpdu.c3
-rw-r--r--net/core/dev.c15
-rw-r--r--net/core/ethtool.c22
-rw-r--r--net/core/net-sysfs.c20
-rw-r--r--net/core/sock.c14
-rw-r--r--net/decnet/dn_dev.c2
-rw-r--r--net/ethernet/eth.c2
-rw-r--r--net/ipv4/af_inet.c3
-rw-r--r--net/ipv4/devinet.c36
-rw-r--r--net/ipv4/esp4.c2
-rw-r--r--net/ipv4/icmp.c9
-rw-r--r--net/ipv4/ip_input.c2
-rw-r--r--net/ipv4/ip_output.c10
-rw-r--r--net/ipv4/ipvs/Makefile2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto.c3
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_icmp.c182
-rw-r--r--net/ipv4/ipvs/ip_vs_xmit.c1
-rw-r--r--net/ipv4/multipath_drr.c20
-rw-r--r--net/ipv4/multipath_random.c2
-rw-r--r--net/ipv4/multipath_rr.c22
-rw-r--r--net/ipv4/multipath_wrandom.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c28
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c1
-rw-r--r--net/ipv4/netfilter/ip_queue.c10
-rw-r--r--net/ipv4/protocol.c2
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/route.c2
-rw-r--r--net/ipv4/sysctl_net_ipv4.c9
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_input.c13
-rw-r--r--net/ipv4/tcp_minisocks.c2
-rw-r--r--net/ipv4/tcp_output.c2
-rw-r--r--net/ipv4/tcp_timer.c2
-rw-r--r--net/ipv4/udp.c14
-rw-r--r--net/ipv6/addrconf.c1
-rw-r--r--net/ipv6/icmp.c14
-rw-r--r--net/ipv6/ip6_flowlabel.c10
-rw-r--r--net/ipv6/ip6_output.c14
-rw-r--r--net/ipv6/ip6_tunnel.c1
-rw-r--r--net/ipv6/ipv6_syms.c1
-rw-r--r--net/ipv6/xfrm6_output.c1
-rw-r--r--net/ipv6/xfrm6_policy.c4
-rw-r--r--net/irda/irda_device.c2
-rw-r--r--net/netlink/af_netlink.c16
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/sched/Kconfig2
-rw-r--r--net/sched/act_api.c2
-rw-r--r--net/sched/cls_basic.c3
-rw-r--r--net/sched/em_meta.c295
-rw-r--r--net/sched/sch_dsmark.c16
-rw-r--r--net/sched/sch_netem.c209
-rw-r--r--net/sctp/input.c49
-rw-r--r--net/sctp/ipv6.c36
-rw-r--r--net/sctp/proc.c194
-rw-r--r--net/sctp/protocol.c7
-rw-r--r--net/sctp/socket.c12
-rw-r--r--net/socket.c2
-rw-r--r--net/unix/af_unix.c28
-rw-r--r--net/xfrm/xfrm_algo.c2
-rw-r--r--net/xfrm/xfrm_policy.c4
-rw-r--r--net/xfrm/xfrm_user.c15
-rw-r--r--scripts/kallsyms.c20
-rw-r--r--scripts/kconfig/Makefile14
-rw-r--r--scripts/kconfig/POTFILES.in5
-rw-r--r--scripts/kconfig/conf.c20
-rw-r--r--scripts/kconfig/confdata.c16
-rw-r--r--scripts/kconfig/gconf.c52
-rw-r--r--scripts/kconfig/kxgettext.c221
-rw-r--r--scripts/kconfig/lkc.h8
-rw-r--r--scripts/kconfig/mconf.c120
-rw-r--r--scripts/kconfig/menu.c4
-rw-r--r--scripts/kconfig/qconf.cc59
-rwxr-xr-xscripts/patch-kernel131
-rw-r--r--security/selinux/ss/services.c8
-rw-r--r--sound/isa/Kconfig1
-rw-r--r--sound/oss/Kconfig12
-rw-r--r--sound/oss/ac97_codec.c1
-rw-r--r--sound/pci/intel8x0.c6
-rw-r--r--sound/pci/via82xx.c2
-rw-r--r--sound/ppc/pmac.c30
-rw-r--r--sound/usb/usbaudio.c2
-rw-r--r--sound/usb/usx2y/usbusx2y.c11
1219 files changed, 51469 insertions, 21951 deletions
diff --git a/CREDITS b/CREDITS
index c9068febcffc..d65ffe5a4d08 100644
--- 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
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 72dc90f8f4a7..8de8a01a2474 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -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
index 82768784ea52..000000000000
--- a/Documentation/BK-usage/00-INDEX
+++ /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
index b7b9075d2910..000000000000
--- a/Documentation/BK-usage/bk-kernel-howto.txt
+++ /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
index 58ca46a0fcc6..000000000000
--- a/Documentation/BK-usage/bk-make-sum
+++ /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
index 836ca943694f..000000000000
--- a/Documentation/BK-usage/bksend
+++ /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
index be780876849f..000000000000
--- a/Documentation/BK-usage/bz64wrap
+++ /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
index b8faca97dab9..000000000000
--- a/Documentation/BK-usage/cpcset
+++ /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
index d28a96f8c618..000000000000
--- a/Documentation/BK-usage/cset-to-linus
+++ /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
index e2b81c35883f..000000000000
--- a/Documentation/BK-usage/csets-to-patches
+++ /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
index aaeb17dc7c7f..000000000000
--- a/Documentation/BK-usage/gcapatch
+++ /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
index 4fc3e73e9a81..000000000000
--- a/Documentation/BK-usage/unbz64wrap
+++ /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
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index cf2fce7707da..6df1dfd18b65 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -14,7 +14,7 @@
</authorgroup>
<copyright>
- <year>2003</year>
+ <year>2003-2005</year>
<holder>Jeff Garzik</holder>
</copyright>
@@ -44,30 +44,38 @@
<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>
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 9838d32b2fe7..4d35562b1cf9 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -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>
diff --git a/Documentation/aoe/aoe.txt b/Documentation/aoe/aoe.txt
index 43e50108d0e2..3a4dbe4663c9 100644
--- a/Documentation/aoe/aoe.txt
+++ b/Documentation/aoe/aoe.txt
@@ -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"
diff --git a/Documentation/aoe/status.sh b/Documentation/aoe/status.sh
index 6628116d4a9f..751f3be514b8 100644
--- a/Documentation/aoe/status.sh
+++ b/Documentation/aoe/status.sh
@@ -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
index 000000000000..e2d1e760b4ba
--- /dev/null
+++ b/Documentation/cpu-freq/cpufreq-stats.txt
@@ -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.
+
+
+
+
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index 1ad26d2c20ae..2f8f24eaefd9 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -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
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 7c2496426ab9..9a33bb94f74f 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -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
index 000000000000..a50c70f9ca72
--- /dev/null
+++ b/Documentation/dvb/README.flexcop
@@ -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.
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt
index e3cacf4f2345..d64430bf4bb6 100644
--- a/Documentation/dvb/bt8xx.txt
+++ b/Documentation/dvb/bt8xx.txt
@@ -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
index 000000000000..62e0701b542a
--- /dev/null
+++ b/Documentation/dvb/ci.txt
@@ -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.
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index 3ffdcb394299..a750f0101d9d 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -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);
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index d3c52dd24a2a..b9eb209318ab 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -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>
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
index e97d024eae77..988a62fae11f 100644
--- a/Documentation/filesystems/sysfs-pci.txt
+++ b/Documentation/filesystems/sysfs-pci.txt
@@ -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.
diff --git a/Documentation/networking/DLINK.txt b/Documentation/networking/DLINK.txt
index 083d24752b83..55d24433d151 100644
--- a/Documentation/networking/DLINK.txt
+++ b/Documentation/networking/DLINK.txt
@@ -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>
diff --git a/Documentation/networking/vortex.txt b/Documentation/networking/vortex.txt
index fa12a9e4abdd..80e1cb19609f 100644
--- a/Documentation/networking/vortex.txt
+++ b/Documentation/networking/vortex.txt
@@ -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
diff --git a/Documentation/pci.txt b/Documentation/pci.txt
index 67514bf87ccd..62b1dc5d97e2 100644
--- a/Documentation/pci.txt
+++ b/Documentation/pci.txt
@@ -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)_*()
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index 5d4ae9a39f1d..f987afe43e28 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -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
diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt
index c85428e7ad92..35b1a7dae342 100644
--- a/Documentation/power/pci.txt
+++ b/Documentation/power/pci.txt
@@ -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
diff --git a/Documentation/powerpc/hvcs.txt b/Documentation/powerpc/hvcs.txt
index c0a62e116e6e..dca75cbda6f8 100644
--- a/Documentation/powerpc/hvcs.txt
+++ b/Documentation/powerpc/hvcs.txt
@@ -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
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index 44b6eea60ece..b9e6be00cadf 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -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
diff --git a/MAINTAINERS b/MAINTAINERS
index f384a9758fc0..86ba94f16e83 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -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
diff --git a/Makefile b/Makefile
index f7eb55878f11..9e005e18c71c 100644
--- 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
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 0c79b9d95f74..f7c96635d3b4 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -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
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 64e450dddb49..167fd89f8707 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -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;
}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4055115ae0e2..475950c8a831 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -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
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index 665bd2c20743..d3fe2533907e 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -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
+
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
index 2b4059d2f8e4..5d92af975d87 100644
--- a/arch/arm/configs/badge4_defconfig
+++ b/arch/arm/configs/badge4_defconfig
@@ -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
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index b4e297dd54b2..b9de07de80fe 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -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
#
diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig
index 6987c8c5ddb4..fb41a36a5a68 100644
--- a/arch/arm/configs/hackkit_defconfig
+++ b/arch/arm/configs/hackkit_defconfig
@@ -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
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 080df907f242..e14278d59882 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -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
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 171b3e811c71..4733877296d4 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -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
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 26eacd3e5def..8f146a4b4752 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -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))
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index ef32577da304..f897ce2ccf0d 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -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");
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 3a001fe5540b..45d2a032d890 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -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)
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index a39c6a42d68a..ad2d66c93a5c 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -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
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
index 6d1d7c27806e..5e240e452af6 100644
--- a/arch/arm/lib/io-writesw-armv4.S
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -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
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index f6e676322ca9..45c930ccd064 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -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.
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
index 1090c680b6dd..324d9edeec38 100644
--- a/arch/arm/mach-footbridge/Kconfig
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -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:
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index ec85813ee5dc..cddd194ac6eb 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -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
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 94bcdb933e41..aa92e3708838 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -502,15 +502,6 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask)
}
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)
{
if (mask >= SZ_64M - 1 )
@@ -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);
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 3f952237ae3d..6823ae28ae6a 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -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)")
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 82a4bf34c251..9799fe80df23 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -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);
}
/*
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index e887b7175ef3..7869c3b4e62f 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -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
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 7e863afefb53..893964fb9659 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -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.
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index e23f534d4e1d..8d986b8401c2 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -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));
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index bc229fab86d4..c7c28890d406 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -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;
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index 9a8cc5ae2255..d4c8281b55f6 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -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:
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 50cde576dadf..6923316b3d0d 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -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
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 27892e34b060..3fefb43c67f7 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -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.
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index ccf316c11e02..59f47d4c2dfe 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -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
index 305af3dab3d8..000000000000
--- a/arch/arm/mm/copypage-v4mc.S
+++ /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
index 000000000000..fc69dccdace1
--- /dev/null
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -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,
+};
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 694ac8208858..a8c00236bd3d 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -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
index bb277316ef52..000000000000
--- a/arch/arm/mm/copypage-xscale.S
+++ /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
index 000000000000..42a6ee255ce0
--- /dev/null
+++ b/arch/arm/mm/copypage-xscale.c
@@ -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,
+};
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index c6de48d89503..4085ed983e46 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -13,6 +13,29 @@
#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)
{
@@ -37,6 +60,18 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
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
* data in the current VM view associated with this page.
@@ -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
index dedf2ab01b2a..000000000000
--- a/arch/arm/mm/minicache.c
+++ /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);
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 585dfb8e20b9..2c2b93d77d43 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -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);
}
/*
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index 3955de5af4c0..6caed90661fc 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -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
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index 134aec1c6d19..b5f83e9f04db 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -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();
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 99b4f294a52d..dfd904f6883b 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -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)
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 04783ceb050c..1c36ca332a96 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -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
#
diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S
index ba9fe14db6a9..011b7a4993d4 100644
--- a/arch/i386/boot/bootsect.S
+++ b/arch/i386/boot/bootsect.S
@@ -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
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 925d3f5a3824..0587477c99f2 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -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
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 0fbcfe00dd8d..51ecd512603d 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -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 $@
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 53eb5cfd5b63..848bb97af7ca 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -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;
}
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 45641a872550..0ff65abcd56c 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -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);
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 16dbc4151be4..73aeaf5a9d4e 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -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]);
}
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 6be0310e3cd3..d199e525680a 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -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)
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
index f25ffd74235c..0f1eb507233b 100644
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig
@@ -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
diff --git a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile
index a922e97aeedd..2e894f1c8910 100644
--- a/arch/i386/kernel/cpu/cpufreq/Makefile
+++ b/arch/i386/kernel/cpu/cpufreq/Makefile
@@ -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
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index ab0f9f5aac11..04e3563da4fe 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -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);
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
index 913f652623d9..5c530064eb74 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
@@ -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");
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index a65ff7e32e5d..10cc096c0ade 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -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
@@ -15,12 +15,13 @@
*
* 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);
+
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
index 63ebc8470f52..9ed5bf221cb7 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
@@ -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
index 000000000000..ef457d50f4ac
--- /dev/null
+++ b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c
@@ -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);
+
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 07d5612dc00f..7dcbf70fc16f 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -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, }
};
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
index 8ba430a9c3a2..d368b3f5fce8 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
@@ -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;
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
index 79440b3f087e..b25fb6b635ae 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
@@ -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;
}
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index aeb5b4ef8c8b..a710dc4eb20e 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -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)
{
diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/i386/kernel/cpu/mtrr/cyrix.c
index 933b0dd62f48..9027a987006b 100644
--- a/arch/i386/kernel/cpu/mtrr/cyrix.c
+++ b/arch/i386/kernel/cpu/mtrr/cyrix.c
@@ -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)
{
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 14ec354bec92..903190a4b3ff 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -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);
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 671681659243..59ff9b455069 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -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;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 85bd56d44314..96e3ea6b17c7 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -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;
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index e8c965ce86eb..e34f651fa13c 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -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);
+
}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 945ec73163c8..2bfbddebdbf8 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -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)
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index cbea7ac582e5..bc1bb6919e6a 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -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++) {
diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c
index f7f90005e22e..8e201219f525 100644
--- a/arch/i386/kernel/timers/common.c
+++ b/arch/i386/kernel/timers/common.c
@@ -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)
}
}
}
+
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index 7926d967be00..180444d87824 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -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;
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 903d739ca74a..a6e0ddd65bd0 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -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);
@@ -126,6 +125,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)
{
if(voyager_quad_processors & (1<<cpu))
@@ -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.
*
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index db06f7399913..ab542792b27b 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -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);
}
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index be52c5ac4e05..8e8e895e1b5a 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -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)
{
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index d6598da4b67b..da21b1d07c15 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -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;
}
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 468dbe8a6b9c..3ad2c4af099c 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -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
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 99830e8fc9ba..9086b789f6ac 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -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
@@ -152,10 +158,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
@@ -566,25 +566,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# 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
#
CONFIG_INPUT_KEYBOARD=y
@@ -602,6 +583,24 @@ CONFIG_MOUSE_PS2=y
# 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
#
CONFIG_VT=y
@@ -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
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 6a8fcba7a853..b8db6e3e5e81 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -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;
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c
index 9845dabe2613..164b211f4174 100644
--- a/arch/ia64/ia32/ia32_ioctl.c
+++ b/arch/ia64/ia32/ia32_ioctl.c
@@ -13,7 +13,6 @@
#define INCLUDES
#include "compat_ioctl.c"
-#include <asm/ioctl32.h>
#define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 247a21c64aea..c1e20d65dd6c 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -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;
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index a8e99c56a768..72dfd9e7de0f 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -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)))
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 9353adc18956..8ebfcc0c813a 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -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
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index f566ff43a389..7d7684a369d3 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -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,r8 // update failed?
(p6) br.cond.spnt.few 1b // yes -> retry
#ifdef CONFIG_SMP
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 4d6c7b8f667b..736e328b5e61 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -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;
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index ab478172c349..abc0113a821d 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -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;
}
diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S
index bcfa05acc561..2d7e0217638d 100644
--- a/arch/ia64/kernel/mca_drv_asm.S
+++ b/arch/ia64/kernel/mca_drv_asm.S
@@ -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
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
index 1dbc7b2497c9..f6d8a010d99b 100644
--- a/arch/ia64/kernel/minstate.h
+++ b/arch/ia64/kernel/minstate.h
@@ -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; \
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index febc091c2f02..f1aca7cffd12 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -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);
}
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 376fcbc3f8da..6407bff6bfd7 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -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
*/
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 7c43aea5f7f7..ebb71f3d6d19 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -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;
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 9e730c7bf0cd..4c1d2f5442b3 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -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))
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index b7e6b4cb374b..d14692e0920a 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -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
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 6891d86937d9..499b7e5317cf 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -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.
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 0d5ee57c9865..3865f088ffa2 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -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
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index a8cf6d8a509c..770fab37928e 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -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) {
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index e82ad78081b3..1861173bd4f6 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -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
diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S
index 29c802b19669..a1af9146cfdb 100644
--- a/arch/ia64/lib/flush.S
+++ b/arch/ia64/lib/flush.S
@@ -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
;;
diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
index 3c2cd2f04db9..6f308e62c137 100644
--- a/arch/ia64/lib/memcpy_mck.S
+++ b/arch/ia64/lib/memcpy_mck.S
@@ -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
diff --git a/arch/ia64/lib/memset.S b/arch/ia64/lib/memset.S
index bd8cf907fe22..f26c16aefb1c 100644
--- a/arch/ia64/lib/memset.S
+++ b/arch/ia64/lib/memset.S
@@ -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
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 547785e3cba2..4eb2f52b87a1 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -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();
}
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
index 4f381fb25049..4351c4ff9845 100644
--- a/arch/ia64/sn/kernel/Makefile
+++ b/arch/ia64/sn/kernel/Makefile
@@ -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
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 18160a06a8c9..9e07f5463f21 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -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);
}
}
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c
index 857774bb2c9a..6546db6abdba 100644
--- a/arch/ia64/sn/kernel/mca.c
+++ b/arch/ia64/sn/kernel/mca.c
@@ -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;
}
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index d35f2a6f9c94..44bfc7f318cb 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -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;
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index 66190d7e492d..ab9b5f35c2a7 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -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
index 000000000000..3be52a34c80f
--- /dev/null
+++ b/arch/ia64/sn/kernel/xp_main.c
@@ -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
index 000000000000..b772543053c9
--- /dev/null
+++ b/arch/ia64/sn/kernel/xp_nofault.S
@@ -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
index 000000000000..1a0aed8490d1
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpc.h
@@ -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
index 000000000000..0bf6fbcc46d2
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -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
index 000000000000..177ddb748ebe
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -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
index 000000000000..2c3c4a8af553
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpc_partition.c
@@ -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
index 000000000000..78c13d676fa6
--- /dev/null
+++ b/arch/ia64/sn/kernel/xpnet.c
@@ -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");
+
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index c90685985d81..64af2b2c1787 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -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;
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 54a0dd447e76..8dae9eb45456 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -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);
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index 7dbf997ff205..5649fbae430e 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -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
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index 505a2968e604..63024b0b7ac3 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -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
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 617aa73c3250..6433da2d2ce2 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -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
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index b501db51d9ec..da2a23a21463 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -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
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index 2bf6cef4f2b2..51251883adf8 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -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
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 7074f856820c..15b80abfe94a 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -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
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 61f09bc4846a..f0d5534f6830 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -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
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index 69c01004ec41..1d5c46ff3c81 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -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
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index 550ec26006c1..856238634d42 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -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
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index 5b5a619645aa..af903b5c5708 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -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
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index 704e42344cba..997143b7928a 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -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
diff --git a/arch/m68k/defconfig b/arch/m68k/defconfig
index 5b2296ecba82..7d935e48a9a8 100644
--- a/arch/m68k/defconfig
+++ b/arch/m68k/defconfig
@@ -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
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index fc4615b6d3a9..e729bd280623 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -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
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 2b6c9d32b7a6..c4a33f265dc0 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -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)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5e666aad8815..ab9944693f1f 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1656,3 +1656,7 @@ config GENERIC_HARDIRQS
config GENERIC_IRQ_PROBE
bool
default y
+
+config ISA_DMA_API
+ bool
+ default y
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index a2f899c2f4d4..92e70ca3bff9 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -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]);
}
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c
index c5f1043de938..53166f3598b2 100644
--- a/arch/mips/vr41xx/common/pmu.c
+++ b/arch/mips/vr41xx/common/pmu.c
@@ -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>
@@ -27,20 +29,31 @@
#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);
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 5b5cd00d98ca..e7e7c56fc212 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -45,6 +45,10 @@ config GENERIC_IRQ_PROBE
config PM
bool
+config ISA_DMA_API
+ bool
+ default y
+
source "init/Kconfig"
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index c3d941345e3d..6e6377a69d5b 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -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
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile
index f850fb0fb511..c9ac5f5fa9e4 100644
--- a/arch/ppc/boot/images/Makefile
+++ b/arch/ppc/boot/images/Makefile
@@ -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
diff --git a/arch/ppc/configs/mpc8555_cds_defconfig b/arch/ppc/configs/mpc8555_cds_defconfig
index 728bd9e1a8fa..15abebf46b96 100644
--- a/arch/ppc/configs/mpc8555_cds_defconfig
+++ b/arch/ppc/configs/mpc8555_cds_defconfig
@@ -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
@@ -105,10 +114,6 @@ CONFIG_PCI_NAMES=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# Advanced setup
#
# CONFIG_ADVANCED_OPTIONS is not set
@@ -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
@@ -370,14 +426,6 @@ CONFIG_INPUT=y
# 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
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -387,6 +435,13 @@ CONFIG_SOUND_GAMEPORT=y
# 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
#
# CONFIG_VT is not set
@@ -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
@@ -434,6 +490,11 @@ CONFIG_GEN_RTC=y
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
CONFIG_I2C=y
@@ -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
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
index 8aa5e8c69009..d44b7dc5390a 100644
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/ppc/kernel/cputable.c
@@ -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
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 9b6a8e513657..6c7ae6052464 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -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
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index f22ddce36135..ce36e88ba627 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -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.
*/
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index e4f1615ec13f..7329ef177a18 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -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
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index e97ce635b99e..5c20266e3b1f 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -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);
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index f8e7e324a173..c65731e8bc65 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -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];
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 0c0e714b84de..9353584fb710 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -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 :
diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S
index 8d08a2eb225e..36c9b97fd92a 100644
--- a/arch/ppc/lib/string.S
+++ b/arch/ppc/lib/string.S
@@ -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
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index be02a7fec2b7..363c157e3617 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -179,6 +179,7 @@ void free_initmem(void)
if (!have_of)
FREESEC(openfirmware);
printk("\n");
+ ppc_md.progress = NULL;
#undef FREESEC
}
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index b3b0f51979d2..e6348b5a1ddc 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -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
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
index f4d055ae19c1..a2f6e49d7151 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -26,9 +26,14 @@
#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
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index 4d857d6d633d..583838ab02d8 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -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);
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 6c020d67ad70..e7cfa498568c 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -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);
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
index 7627d77504bd..12b292c6ae32 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
@@ -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__ */
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
index 9ab05e590c3e..7b9e1543e175 100644
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -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);
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index f7fb2786cd50..5fdd4f607a40 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -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)
diff --git a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h
index cf5e5dd06d63..067d9a5aebc1 100644
--- a/arch/ppc/platforms/pq2ads.h
+++ b/arch/ppc/platforms/pq2ads.h
@@ -49,10 +49,10 @@
/* 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.
@@ -68,28 +68,23 @@
* 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 */
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index dd418ea3426c..96acf85800d4 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -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
diff --git a/arch/ppc/syslib/ipic.c b/arch/ppc/syslib/ipic.c
index acb2cde3171f..580ed658e872 100644
--- a/arch/ppc/syslib/ipic.c
+++ b/arch/ppc/syslib/ipic.c
@@ -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
index 057cc3f8ff37..000000000000
--- a/arch/ppc/syslib/m8260_pci.c
+++ /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
index d1352120acd7..000000000000
--- a/arch/ppc/syslib/m8260_pci.h
+++ /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 */
diff --git a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c
index 9c0582d639e0..1dc7e4e1d491 100644
--- a/arch/ppc/syslib/m8260_pci_erratum9.c
+++ b/arch/ppc/syslib/m8260_pci_erratum9.c
@@ -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;
}
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index 23ea3f694de2..fda75d79050c 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -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
index 000000000000..5e7a7edcea74
--- /dev/null
+++ b/arch/ppc/syslib/m82xx_pci.c
@@ -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
index 000000000000..924f73f8e595
--- /dev/null
+++ b/arch/ppc/syslib/m82xx_pci.h
@@ -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 */
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index 5c1a919eaabf..75c8e9834ae7 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -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[] = {
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index a231795ee26f..1e658ef57e75 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -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[] = {
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
index 7619e16fccae..000ba47c67cb 100644
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -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);
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
index c28f9d679484..843cf8873e60 100644
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -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(;;);
}
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
index 152c3ef1312a..f3277f469e78 100644
--- a/arch/ppc/syslib/ppc85xx_setup.c
+++ b/arch/ppc/syslib/ppc85xx_setup.c
@@ -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();
diff --git a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c
index 2cee87137f2e..7f15136830f4 100644
--- a/arch/ppc/syslib/prom_init.c
+++ b/arch/ppc/syslib/prom_init.c
@@ -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);
}
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index ef1f05e437c4..5cb343883e4d 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -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"
diff --git a/arch/ppc64/Kconfig.debug b/arch/ppc64/Kconfig.debug
index e341a129da80..46b1ce58da3b 100644
--- a/arch/ppc64/Kconfig.debug
+++ b/arch/ppc64/Kconfig.debug
@@ -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"
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index b0fa86ad8b1b..da12ea2ca464 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -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);
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c
index 7b607d1862cb..d5218b15824e 100644
--- a/arch/ppc64/boot/prom.c
+++ b/arch/ppc64/boot/prom.c
@@ -11,6 +11,23 @@
#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
index ea247e79b55e..000000000000
--- a/arch/ppc64/boot/start.c
+++ /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;
-}
diff --git a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig
index 0f90df0b3f9c..1eb33398648e 100644
--- a/arch/ppc64/configs/g5_defconfig
+++ b/arch/ppc64/configs/g5_defconfig
@@ -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
#
@@ -105,10 +110,6 @@ CONFIG_PCI_NAMES=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -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)
@@ -631,18 +633,6 @@ 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
#
CONFIG_INPUT_KEYBOARD=y
@@ -660,6 +650,16 @@ CONFIG_INPUT_MOUSE=y
# 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
#
CONFIG_VT=y
@@ -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
diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig
index a39e9d2e25da..f6a2b99afd63 100644
--- a/arch/ppc64/configs/iSeries_defconfig
+++ b/arch/ppc64/configs/iSeries_defconfig
@@ -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,6 +97,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
#
# PCCARD (PCMCIA/CardBus) support
@@ -96,10 +105,6 @@ CONFIG_PCI_NAMES=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -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)
@@ -539,14 +543,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# 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
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -556,6 +552,12 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_SERIAL_NONSTANDARD is not set
@@ -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
diff --git a/arch/ppc64/configs/maple_defconfig b/arch/ppc64/configs/maple_defconfig
index cf527501915c..8051b0f47b6f 100644
--- a/arch/ppc64/configs/maple_defconfig
+++ b/arch/ppc64/configs/maple_defconfig
@@ -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,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
#
# PCCARD (PCMCIA/CardBus) support
@@ -101,10 +109,6 @@ CONFIG_PCI_NAMES=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -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)
@@ -432,14 +437,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
# 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
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -449,6 +446,12 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -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
diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig
index 4fecf237d5c9..3eb5ef25d3a3 100644
--- a/arch/ppc64/configs/pSeries_defconfig
+++ b/arch/ppc64/configs/pSeries_defconfig
@@ -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
#
@@ -110,10 +120,6 @@ CONFIG_HOTPLUG_CPU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
CONFIG_HOTPLUG_PCI=m
@@ -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)
@@ -636,20 +642,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# 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
#
CONFIG_INPUT_KEYBOARD=y
@@ -669,6 +661,18 @@ 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
#
CONFIG_VT=y
@@ -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
diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig
index 537b1cc82eab..2f31bf3046f9 100644
--- a/arch/ppc64/defconfig
+++ b/arch/ppc64/defconfig
@@ -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
#
@@ -112,10 +121,6 @@ CONFIG_HOTPLUG_CPU=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
CONFIG_HOTPLUG_PCI=m
@@ -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)
@@ -683,20 +690,6 @@ 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
#
CONFIG_INPUT_KEYBOARD=y
@@ -716,6 +709,18 @@ 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
#
CONFIG_VT=y
@@ -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
diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
index d3604056e1a9..b61572eb2a71 100644
--- a/arch/ppc64/kernel/entry.S
+++ b/arch/ppc64/kernel/entry.S
@@ -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 */
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index 92a744c31ab1..346dbf606b5d 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -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
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index da20120f2261..6d06eb550a3f 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -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();
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index 6abc621d3ba0..f24ce2b87200 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -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;
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index 103daaf73573..e950a2058a19 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -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;
diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c
index 1bd52ece497c..5aca7e8005a8 100644
--- a/arch/ppc64/kernel/mf.c
+++ b/arch/ppc64/kernel/mf.c
@@ -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
@@ -36,10 +36,12 @@
#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];
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index 90b41f48d21c..e3c73b3425dc 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -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 */
diff --git a/arch/ppc64/kernel/pSeries_reconfig.c b/arch/ppc64/kernel/pSeries_reconfig.c
index cb5443f2e49b..dc2a69d412a2 100644
--- a/arch/ppc64/kernel/pSeries_reconfig.c
+++ b/arch/ppc64/kernel/pSeries_reconfig.c
@@ -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);
}
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
index c60d8cb2b84d..fbad349ec58c 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/ppc64/kernel/pSeries_smp.c
@@ -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);
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index be3cc387c1ec..d786d4b6af0b 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -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;
diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c
index c27588ede2fe..a23de37227bf 100644
--- a/arch/ppc64/kernel/pmac_smp.c
+++ b/arch/ppc64/kernel/pmac_smp.c
@@ -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;
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
index 8b0686122738..cdfecbeb331f 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -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;
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index fe2946c58314..eb6538b58008 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -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");
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index 35ec42de962e..b7683abfbe6a 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -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)
{
@@ -1844,6 +1909,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
&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
*/
if (RELOC(of_platform) & PLATFORM_PSERIES)
@@ -1920,6 +1991,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
}
/*
+ * Fixup any known bugs in the device-tree
+ */
+ fixup_device_tree();
+
+ /*
* Now finally create the flattened device-tree
*/
prom_printf("copying OF device tree ...\n");
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 5a846324ca8c..9f8c6087ae56 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -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))
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
index 3e70b91375fc..67989055a9fe 100644
--- a/arch/ppc64/kernel/rtc.c
+++ b/arch/ppc64/kernel/rtc.c
@@ -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
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index 21c57f539c29..dce198d39328 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -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.
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
index a95a2b49a1d5..bf782276984c 100644
--- a/arch/ppc64/kernel/signal.c
+++ b/arch/ppc64/kernel/signal.c
@@ -42,11 +42,7 @@
#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
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index 3b906cd94037..9ef5d36d6b25 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -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;
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 7cf7a9600025..9c8e317c598d 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -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;
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
index f2865ff8d2f9..a8cbb202b8cd 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/ppc64/kernel/syscalls.c
@@ -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;
}
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
index 0925694c3ce5..c8fa6569b2fd 100644
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/ppc64/kernel/sysfs.c
@@ -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 */
}
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index 772a465b49f9..33364a7d2cd2 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -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;
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
index eedd1d3c2a10..879f39b90a33 100644
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/ppc64/kernel/xics.c
@@ -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");
}
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c
index 144657e0c3d5..52b6b9305341 100644
--- a/arch/ppc64/mm/hash_native.c
+++ b/arch/ppc64/mm/hash_native.c
@@ -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]);
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c
index e48be12f518c..0a0f97008d02 100644
--- a/arch/ppc64/mm/hash_utils.c
+++ b/arch/ppc64/mm/hash_utils.c
@@ -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);
diff --git a/arch/ppc64/mm/imalloc.c b/arch/ppc64/mm/imalloc.c
index 9d92b0d9cde5..cb8727f3267a 100644
--- a/arch/ppc64/mm/imalloc.c
+++ b/arch/ppc64/mm/imalloc.c
@@ -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;
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index cf33d7ec2e29..4b42aff74d73 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -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 */
diff --git a/arch/ppc64/mm/stab.c b/arch/ppc64/mm/stab.c
index 31491131d5e4..df4bbe14153c 100644
--- a/arch/ppc64/mm/stab.c
+++ b/arch/ppc64/mm/stab.c
@@ -19,6 +19,11 @@
#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);
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index 01ae1964c938..c067435bae45 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -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> ******************************/
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index 462ee9a84e76..f0e2fbed3d4c 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -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)
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c
index dd61638d3027..2a4c7432db4a 100644
--- a/arch/s390/appldata/appldata_net_sum.c
+++ b/arch/s390/appldata/appldata_net_sum.c
@@ -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)
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index b83f07484551..e0a476bf4fd6 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -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;
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 9f0d73e3f5f7..06afa3103ace 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -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,22 +750,24 @@ 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
* stopping signal is not SIGTRAP. -brl
@@ -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]);
}
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 80306bc8c799..75fde949d125 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -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;
/*
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 722ea1d63c94..3468d5127223 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -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)"
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 066e253f9c12..2c216ffeea90 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -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
diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c
index 46aa51afec14..c20e5309f8aa 100644
--- a/arch/sparc/prom/memory.c
+++ b/arch/sparc/prom/memory.c
@@ -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;
diff --git a/arch/sparc/prom/sun4prom.c b/arch/sparc/prom/sun4prom.c
index 69ca735f0d4e..00390a2652aa 100644
--- a/arch/sparc/prom/sun4prom.c
+++ b/arch/sparc/prom/sun4prom.c
@@ -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,
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index a38cb5036df0..4dcb8af94090 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -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;
}
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 292983413ae2..2803bc7c2c79 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -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);
}
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 3567fa879e1f..534320ef0db2 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -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;
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 5525d1ec4af8..53d333b4a4e8 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -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;
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index e93fcadc3722..5753175b94e6 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -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;
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 26d3ec41da1c..a0cd2b2494d6 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -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
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 14d9c3a21b9a..89f5e019f24c 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -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);
}
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 12c3d84b7460..b7e6a91952b2 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -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;
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 6dff06a44e76..e5b9c7a27789 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -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();
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index cad5a1122800..e78cc53594fa 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -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
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 56b203a2af69..a9f4596d7c2b 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -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;
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index db6fa77b4dab..9c5222075da9 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -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;
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug
index b89989de364d..bd41e4286d0d 100644
--- a/arch/um/Kconfig.debug
+++ b/arch/um/Kconfig.debug
@@ -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
diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char
index 3e50fdb67626..62d87b71179b 100644
--- a/arch/um/Kconfig_char
+++ b/arch/um/Kconfig_char
@@ -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
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
index fd8d7e8982b1..f162f50f0b17 100644
--- a/arch/um/Kconfig_x86_64
+++ b/arch/um/Kconfig_x86_64
@@ -6,6 +6,10 @@ config 64BIT
bool
default y
+config TOP_ADDR
+ hex
+ default 0x80000000
+
config 3_LEVEL_PGTABLES
bool
default y
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 97bca6b5ca95..f2a0c40a9204 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -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
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index f9e3c0f06541..29e182d5a83a 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -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
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index a77971133e91..32144562c279 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -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)
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 323f72c64cd2..b2de9916c32c 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -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
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 0150038af795..14a12d6b3df6 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -20,9 +20,17 @@
#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);
}
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 583b8e137c33..5d3768156c92 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -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));
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index d0f97127adf6..025d3be8aca4 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -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;
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index faf714e87b5b..217438cdef33 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -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){
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 0fe1d9fa9139..7a0d115b29d0 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -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:
- */
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index a63231dffe05..a37a5ac13c22 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -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);
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 47229fe4a813..3730d4f12713 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -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];
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index d43e9fab05a7..f9e22198e011 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -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");
diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h
index 495f2f1b1420..bb0dab41c2e4 100644
--- a/arch/um/drivers/slip.h
+++ b/arch/um/drivers/slip.h
@@ -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
index 000000000000..e89cfc68fc3e
--- /dev/null
+++ b/arch/um/drivers/slip_common.c
@@ -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_proto.h b/arch/um/drivers/slip_common.h
index 7206361ace45..2ae76d8f1be1 100644
--- a/arch/um/drivers/slip_proto.h
+++ b/arch/um/drivers/slip_common.h
@@ -1,10 +1,10 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
+#ifndef __UM_SLIP_COMMON_H
+#define __UM_SLIP_COMMON_H
-#ifndef __UM_SLIP_PROTO_H__
-#define __UM_SLIP_PROTO_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 */
@@ -12,7 +12,8 @@
#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)
+static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos,
+ int *esc)
{
int ret;
@@ -79,15 +80,25 @@ static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
return (ptr - d);
}
-#endif
+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 \
+}
-/*
- * 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:
- */
+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
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 0886eedba213..9a6f5c85f902 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -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_user.c b/arch/um/drivers/slip_user.c
index d94846b1b4cf..71af444e591f 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -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:
- */
diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h
index 04e407d1e44a..6cf88ab580c9 100644
--- a/arch/um/drivers/slirp.h
+++ b/arch/um/drivers/slirp.h
@@ -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:
- */
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index c9d6b52a831d..9864d27afdbe 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -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;
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index c322515c71cc..8d91f663d82c 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -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:
- */
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index a2bac429f3d4..b32a77010fbe 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -22,7 +22,6 @@
#include "init.h"
#include "irq_user.h"
#include "mconsole_kern.h"
-#include "2_5compat.h"
static int ssl_version = 1;
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 98565b53d170..429ae8e6c7e5 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -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)
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 361d0be342b3..afbe1e71ed83 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -28,7 +28,6 @@
#include "irq_user.h"
#include "mconsole_kern.h"
#include "init.h"
-#include "2_5compat.h"
#define MAX_TTYS (16)
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 9a56ff94308d..2a7f6892c55c 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -49,13 +49,12 @@
#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 {
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index 7917b9d1cec8..a4fdf3584ad2 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -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
index abdb015a4d71..000000000000
--- a/arch/um/include/2_5compat.h
+++ /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
index 000000000000..d705daa2d854
--- /dev/null
+++ b/arch/um/include/common-offsets.h
@@ -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);
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 15389c886b41..e5fec5570199 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -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);
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 9fbe3083fdd8..cfa368e045a5 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -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;
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 36807b796e9f..89885a77a771 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -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);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 07340c8cf203..881d2988d2d8 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -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);
diff --git a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h
index cfb5fb4f5b91..cd2327d09c8d 100644
--- a/arch/um/include/skas_ptrace.h
+++ b/arch/um/include/skas_ptrace.h
@@ -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
/*
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h
index 3a2a45811aa3..764ba4db4788 100644
--- a/arch/um/include/sysdep-i386/checksum.h
+++ b/arch/um/include/sysdep-i386/checksum.h
@@ -24,19 +24,6 @@ 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
index 000000000000..db437cc373bc
--- /dev/null
+++ b/arch/um/include/sysdep-i386/faultinfo.h
@@ -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
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index 661d495e2044..c8ee9559f3ab 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -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
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index dfee589de360..1fe729265167 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -13,15 +13,12 @@
#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);
diff --git a/arch/um/include/sysdep-i386/signal.h b/arch/um/include/sysdep-i386/signal.h
index b1e1f7a77499..07518b162136 100644
--- a/arch/um/include/sysdep-i386/signal.h
+++ b/arch/um/include/sysdep-i386/signal.h
@@ -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
index 000000000000..e27b8a791773
--- /dev/null
+++ b/arch/um/include/sysdep-i386/skas_ptrace.h
@@ -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
index 000000000000..25a38e715702
--- /dev/null
+++ b/arch/um/include/sysdep-ia64/skas_ptrace.h
@@ -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
index 000000000000..d9fbbac10de0
--- /dev/null
+++ b/arch/um/include/sysdep-ppc/skas_ptrace.h
@@ -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
diff --git a/arch/um/include/sysdep-x86_64/checksum.h b/arch/um/include/sysdep-x86_64/checksum.h
index 572c6c19be33..ea97005af694 100644
--- a/arch/um/include/sysdep-x86_64/checksum.h
+++ b/arch/um/include/sysdep-x86_64/checksum.h
@@ -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
index 000000000000..cb917b0d5660
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/faultinfo.h
@@ -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
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 915c82daffbd..be8acd5efd97 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -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:
- */
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
index 1e38a54ff4cf..2a78260d15a0 100644
--- a/arch/um/include/sysdep-x86_64/sigcontext.h
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h
@@ -17,11 +17,12 @@
#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);
diff --git a/arch/um/include/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h
index e5e52756fab4..6142897af3d1 100644
--- a/arch/um/include/sysdep-x86_64/signal.h
+++ b/arch/um/include/sysdep-x86_64/signal.h
@@ -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
index 000000000000..95db4be786e4
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/skas_ptrace.h
@@ -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
diff --git a/arch/um/include/sysrq.h b/arch/um/include/sysrq.h
index 2ce9423460b3..c8d332b56b98 100644
--- a/arch/um/include/sysrq.h
+++ b/arch/um/include/sysrq.h
@@ -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
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index 103cd320386c..7b6a24dfd302 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -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);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 246f0e7fb4cc..a8918e80df96 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -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
index e69b2be951d1..000000000000
--- a/arch/um/kernel/checksum.c
+++ /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);
-}
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
index 49ddabe69be7..efd222ffe20e 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec_kern.c
@@ -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_kern.c b/arch/um/kernel/initrd.c
index fc568af468b9..82ecf904b09c 100644
--- a/arch/um/kernel/initrd_kern.c
+++ b/arch/um/kernel/initrd.c
@@ -41,12 +41,31 @@ static int __init uml_initrd_setup(char *line, int *add)
return 0;
}
-__uml_setup("initrd=", uml_initrd_setup,
+__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
diff --git a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c
deleted file mode 100644
index cb90681e151c..000000000000
--- a/arch/um/kernel/initrd_user.c
+++ /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:
- */
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index d71e8f00810f..d44fb5282547 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -163,7 +163,6 @@ void __init init_IRQ(void)
irq_desc[i].handler = &SIGIO_irq_type;
enable_irq(i);
}
- init_irq_signals(0);
}
/*
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
index 6d6f9484b884..b3074cbaa479 100644
--- a/arch/um/kernel/irq_user.c
+++ b/arch/um/kernel/irq_user.c
@@ -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;
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index b41d3397d07b..99439fa15ef4 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -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);
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c
index a17c49703f9b..e59f58152678 100644
--- a/arch/um/kernel/main.c
+++ b/arch/um/kernel/main.c
@@ -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;
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index f156661781cb..c22825f13e40 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -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;
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index f76a2692adca..1b5ef3e96c71 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -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);
}
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 7a943696f950..804c6bbdf67c 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -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"
@@ -55,18 +54,6 @@
*/
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
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index e50e60ff5d27..71af4d503899 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -19,15 +19,30 @@
#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:
- */
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 668df13d8c9d..e89218958f38 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -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);
diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h
index 94c564962378..e48490028111 100644
--- a/arch/um/kernel/skas/include/mode_kern-skas.h
+++ b/arch/um/kernel/skas/include/mode_kern-skas.h
@@ -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,
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index f0702c2c7204..96b51dba3471 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -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
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index c35620385da0..cd6c280482cb 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -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);
}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index b4ffaaa81241..773cd2b525fc 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -4,6 +4,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
@@ -27,27 +28,37 @@
#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)
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 5d096ea63b97..fc71ef295782 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -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);
}
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
index 8e9b46d4702e..0dee1d95c806 100644
--- a/arch/um/kernel/skas/trap_user.c
+++ b/arch/um/kernel/skas/trap_user.c
@@ -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);
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index f7da9d027672..75195281081e 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -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);
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
index 17f5909d60f7..f7b7eba83340 100644
--- a/arch/um/kernel/skas/util/Makefile
+++ b/arch/um/kernel/skas/util/Makefile
@@ -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
diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c
index 0788dd05bcac..1f96e1eeb8a7 100644
--- a/arch/um/kernel/skas/util/mk_ptregs-i386.c
+++ b/arch/um/kernel/skas/util/mk_ptregs-i386.c
@@ -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);
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
index 67aee92a70ef..5fccbfe35f78 100644
--- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
+++ b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
@@ -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");
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
index 42731e04f50f..b7a55251e897 100644
--- a/arch/um/kernel/syscall_kern.c
+++ b/arch/um/kernel/syscall_kern.c
@@ -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"
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index e630438f9e73..f80850091e79 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -3,6 +3,7 @@
* Licensed under the GPL
*/
+#include "linux/config.h"
#include "linux/sched.h"
#include "linux/kernel.h"
#include "linux/module.h"
@@ -12,14 +13,14 @@
#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);
}
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 2461cd73ca87..6516fc52afe0 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -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();
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 47e766e6ba10..c20aef120598 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -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);
}
diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
index 50a4042a509f..f825a6eda3f5 100644
--- a/arch/um/kernel/trap_user.c
+++ b/arch/um/kernel/trap_user.c
@@ -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)
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
index 3d5177df3504..c3faea21a996 100644
--- a/arch/um/kernel/tt/Makefile
+++ b/arch/um/kernel/tt/Makefile
@@ -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 \
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h
index 28aaab3448fa..e0ca0e0b2516 100644
--- a/arch/um/kernel/tt/include/mode_kern-tt.h
+++ b/arch/um/kernel/tt/include/mode_kern-tt.h
@@ -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);
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index bb69d6b7d022..3fbb5fe26f49 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/kernel/tt/include/uaccess-tt.h
@@ -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);
}
diff --git a/arch/um/kernel/tt/ksyms.c b/arch/um/kernel/tt/ksyms.c
index 92ec85d67c7c..84a9385a8fef 100644
--- a/arch/um/kernel/tt/ksyms.c
+++ b/arch/um/kernel/tt/ksyms.c
@@ -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);
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
index 74346a04a2b2..bcb8796c3cb1 100644
--- a/arch/um/kernel/tt/mem.c
+++ b/arch/um/kernel/tt/mem.c
@@ -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)
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index f19f7c18febe..776310fd5b8b 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -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)
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
index e4e7e9c2224c..b218316cfdb2 100644
--- a/arch/um/kernel/tt/syscall_user.c
+++ b/arch/um/kernel/tt/syscall_user.c
@@ -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");
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index 7b5d937e5955..d11e7399d7a1 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -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));
}
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index 92a3820ca543..fc108615beaf 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -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;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 5c49d88eed3d..8736d098f0ee 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -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();
}
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 76eadb309189..dd5355500bdc 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -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
index 000000000000..1660a769674b
--- /dev/null
+++ b/arch/um/kernel/vmlinux.lds.S
@@ -0,0 +1,6 @@
+#include <linux/config.h>
+#ifdef CONFIG_LD_SCRIPT_STATIC
+#include "uml.lds.S"
+#else
+#include "dyn.lds.S"
+#endif
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index 9aee0b62ebca..f0d6060e3e57 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -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;
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 77d4066d1af8..fd45bb260907 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -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;
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index ba9ca1cc790a..1e126bfd31a7 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -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)
{
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 7eac1baf5975..c7bfd5ee3925 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -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;
diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile
index fb00ddf969bd..9778aed0c314 100644
--- a/arch/um/os-Linux/util/Makefile
+++ b/arch/um/os-Linux/util/Makefile
@@ -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
diff --git a/arch/um/os-Linux/util/mk_user_constants.c b/arch/um/os-Linux/util/mk_user_constants.c
index 0933518aa8bd..4838f30eecf0 100644
--- a/arch/um/os-Linux/util/mk_user_constants.c
+++ b/arch/um/os-Linux/util/mk_user_constants.c
@@ -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");
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 143f6fea0763..98346c711493 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -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)
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 950781e354de..4351e5605506 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -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
diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S
index a11171fb6223..d98b2fff3d08 100644
--- a/arch/um/sys-i386/checksum.S
+++ b/arch/um/sys-i386/checksum.S
@@ -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
diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c
index 20d37dbbaf08..2c11b9770e8b 100644
--- a/arch/um/sys-i386/delay.c
+++ b/arch/um/sys-i386/delay.c
@@ -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
index 000000000000..9f8ecd1fdd96
--- /dev/null
+++ b/arch/um/sys-i386/kernel-offsets.c
@@ -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>
+}
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c
index 74f70a120458..db524ab3f743 100644
--- a/arch/um/sys-i386/ksyms.c
+++ b/arch/um/sys-i386/ksyms.c
@@ -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);
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 31bcb2f997d4..dc755b0b9db8 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -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;
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index e470d28cdf84..e839ce65ad28 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -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;
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 76ba87254b25..03913ca5d256 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -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,
diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c
index 281fc7b8ca00..e3706d15c4f5 100644
--- a/arch/um/sys-i386/sysrq.c
+++ b/arch/um/sys-i386/sysrq.c
@@ -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
index 000000000000..3ceaabceb3d7
--- /dev/null
+++ b/arch/um/sys-i386/user-offsets.c
@@ -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));
+}
diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
index 34860f9ca7b0..bf61afd0b045 100644
--- a/arch/um/sys-i386/util/Makefile
+++ b/arch/um/sys-i386/util/Makefile
@@ -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
diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
index 85cbd30396f7..04c0d73433aa 100644
--- a/arch/um/sys-i386/util/mk_sc.c
+++ b/arch/um/sys-i386/util/mk_sc.c
@@ -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
index 000000000000..7470d0dda67e
--- /dev/null
+++ b/arch/um/sys-i386/util/mk_thread.c
@@ -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
index 948b1ce85230..000000000000
--- a/arch/um/sys-i386/util/mk_thread_kern.c
+++ /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
index 2620cd6aa1f1..000000000000
--- a/arch/um/sys-i386/util/mk_thread_user.c
+++ /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");
-}
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c
index a971366d3277..8e71b47f2b8e 100644
--- a/arch/um/sys-ppc/ptrace.c
+++ b/arch/um/sys-ppc/ptrace.c
@@ -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
diff --git a/arch/um/sys-ppc/sysrq.c b/arch/um/sys-ppc/sysrq.c
index 82d6e9335bb6..2f816f1a0ff4 100644
--- a/arch/um/sys-ppc/sysrq.c
+++ b/arch/um/sys-ppc/sysrq.c
@@ -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:
- */
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index d7ed2f7908df..608466ad6b22 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -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
diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
index f3b5187942b4..137f4446b439 100644
--- a/arch/um/sys-x86_64/delay.c
+++ b/arch/um/sys-x86_64/delay.c
@@ -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
index 000000000000..220e875cbe29
--- /dev/null
+++ b/arch/um/sys-x86_64/kernel-offsets.c
@@ -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
index 000000000000..859273808203
--- /dev/null
+++ b/arch/um/sys-x86_64/ksyms.c
@@ -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);
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 8c146b2a1e00..74eee5c7c6dd 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -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
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index 5bc5a0d796e5..73a7926f7370 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -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;
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index ab4b0abf8af3..6f44f40204ed 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -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;
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c
index ddf74691a610..d0a25af19a5b 100644
--- a/arch/um/sys-x86_64/sysrq.c
+++ b/arch/um/sys-x86_64/sysrq.c
@@ -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
index 000000000000..8b8eff1bd977
--- /dev/null
+++ b/arch/um/sys-x86_64/um_module.c
@@ -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
index 000000000000..513d17ceafd4
--- /dev/null
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -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));
+}
diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile
index 002607980864..75b052cfc206 100644
--- a/arch/um/sys-x86_64/util/Makefile
+++ b/arch/um/sys-x86_64/util/Makefile
@@ -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
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c
index c236e213918d..7619bc377c1f 100644
--- a/arch/um/sys-x86_64/util/mk_sc.c
+++ b/arch/um/sys-x86_64/util/mk_sc.c
@@ -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
index 000000000000..15517396e9cf
--- /dev/null
+++ b/arch/um/sys-x86_64/util/mk_thread.c
@@ -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
index a281673f02b2..000000000000
--- a/arch/um/sys-x86_64/util/mk_thread_kern.c
+++ /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
index 7989725568b8..000000000000
--- a/arch/um/sys-x86_64/util/mk_thread_user.c
+++ /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");
-}
diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile
index e2ab71209f3f..4c7551c28033 100644
--- a/arch/um/util/Makefile
+++ b/arch/um/util/Makefile
@@ -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
index 000000000000..ab217becc36a
--- /dev/null
+++ b/arch/um/util/mk_constants.c
@@ -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
index cdcb1232a1ea..000000000000
--- a/arch/um/util/mk_constants_kern.c
+++ /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
index 8f4d7e50be7c..000000000000
--- a/arch/um/util/mk_constants_user.c
+++ /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_user.c b/arch/um/util/mk_task.c
index 9db849f3f3ac..36c9606505e2 100644
--- a/arch/um/util/mk_task_user.c
+++ b/arch/um/util/mk_task.c
@@ -1,18 +1,19 @@
#include <stdio.h>
+#include <kernel-offsets.h>
-void print(char *name, char *type, int offset)
+void print_ptr(char *name, char *type, int offset)
{
- printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
+ printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
offset);
}
-void print_ptr(char *name, char *type, int offset)
+void print(char *name, char *type, int offset)
{
- printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
+ printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
offset);
}
-void print_head(void)
+int main(int argc, char **argv)
{
printf("/*\n");
printf(" * Generated by mk_task\n");
@@ -21,10 +22,9 @@ void print_head(void)
printf("#ifndef __TASK_H\n");
printf("#define __TASK_H\n");
printf("\n");
-}
-
-void print_tail(void)
-{
+ 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
index c218103315ed..000000000000
--- a/arch/um/util/mk_task_kern.c
+++ /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/x86_64/Kconfig b/arch/x86_64/Kconfig
index 80c38c5d71fe..289f448ac89c 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -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
diff --git a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S
index bb15d406ee95..011b7a4993d4 100644
--- a/arch/x86_64/boot/bootsect.S
+++ b/arch/x86_64/boot/bootsect.S
@@ -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
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 9ce51dee30b3..569595b74c7c 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -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,9 +176,11 @@ 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
@@ -182,10 +188,6 @@ CONFIG_PCI_MSI=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
@@ -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
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index 0a3318e08ab6..5ca4a4598fda 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -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
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index a491f72cc966..504e63474993 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -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();
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 7e13545748e0..f8e6cc4fecd4 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -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;
}
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 1086b5fcac21..28817490fdc6 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -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
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 60be58617eb9..afd87e64d0a8 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -37,11 +37,14 @@
#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;
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 4f2a852299b6..f77f8a0ff187 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -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;
diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c
index c2ffea8845ed..bac195c74bcc 100644
--- a/arch/x86_64/kernel/module.c
+++ b/arch/x86_64/kernel/module.c
@@ -30,9 +30,12 @@
#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,
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 7ec031c6ca10..61a63be6b294 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -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);
/*
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 61de0b34a01e..31c0f2e6ac91 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -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
index 000000000000..feb5f108dd26
--- /dev/null
+++ b/arch/x86_64/kernel/pmtimer.c
@@ -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);
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index c64b9c97c745..525f6a128a27 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -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))
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 2129cf9ba6b2..99f038ede23c 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -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,
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index d439ced150c6..429c0269dc4e 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -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;
}
}
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 73f7e8b9543a..f1ec0f345941 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -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();
}
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 0e3b60e1ac5b..fb8c809b4cd9 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -26,6 +26,10 @@
#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();
@@ -923,35 +938,50 @@ void __init time_init(void)
}
/*
+ * 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.
*/
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;
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 65a37f52c56e..3dfec8fdabcd 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -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;
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index b4b8dc59663a..2e5734425949 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -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;
}
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index 88626e626886..68ec03070e5a 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -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);
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index e03309216764..5d6b2114cc9a 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -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;
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index 74ec8554b195..58aac23760ef 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -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);
}
diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c
index f691d31fa9ee..3fcf6e887e87 100644
--- a/crypto/crypto_null.c
+++ b/crypto/crypto_null.c
@@ -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
@@ -28,11 +29,13 @@
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");
diff --git a/crypto/internal.h b/crypto/internal.h
index e68e43886d3c..964b9a60ca24 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -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();
}
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 0400a52d5085..670fdb5142d1 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -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
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 12b0eea63407..8093f2e00321 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -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] -> ",
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile
index d1dcd8eae3c9..5b77188527a9 100644
--- a/drivers/atm/Makefile
+++ b/drivers/atm/Makefile
@@ -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
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 9e65bfb85ba3..5f702199543a 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -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,
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 3022c548a132..df2c83fd5496 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -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
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 85bf5c8442b0..b2a7b754fd14 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -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;
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 47a800519ad0..8d5e65cb9755 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -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;
}
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 6662b545e0a9..a47928a2e575 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -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
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index f4fa27315fb4..3cb04bb04c2b 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -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);
}
}
diff --git a/drivers/base/core.c b/drivers/base/core.c
index a7cedd8cefe5..fbc223486f81 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -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
index bd515843a0cb..000000000000
--- a/drivers/base/interface.c
+++ /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,
-};
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index e5eda746f2a6..2e700d795cf1 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -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);
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index f8f5055754d6..26468971ef5a 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -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;
}
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c
index d1e023fbe169..f50a08be424b 100644
--- a/drivers/base/power/shutdown.c
+++ b/drivers/base/power/shutdown.c
@@ -19,20 +19,6 @@
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);
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index a0b5cf689e63..0ec44ef840be 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -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;
}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 423bbf2000d2..3760edfdc65c 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -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,
@@ -7007,6 +7132,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,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index d5e8e7190c90..a82f37f749a5 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -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;
@@ -2541,6 +2542,320 @@ void dma_addr_writeql(dma_addr_t addr, void __iomem *write_address)
}
/*
+ 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.
*/
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index e43e02328968..b594768b0241 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -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.
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index aa8b547ffafa..721ba8086043 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -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"
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 4780f7926d42..0e97fcb9f3a1 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -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
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index ec16c64dd114..6e231c5a1199 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -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);
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index bc92aacb6dad..9e6f51c528b0 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -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;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 42dfa281a880..f0c1084b840f 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -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 {
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index ab4db71375e0..8bbe01d4b487 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -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;
diff --git a/drivers/block/ioctl.c b/drivers/block/ioctl.c
index 5e03f5157ef9..6d7bcc9da9e7 100644
--- a/drivers/block/ioctl.c
+++ b/drivers/block/ioctl.c
@@ -237,3 +237,5 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
}
return ret;
}
+
+EXPORT_SYMBOL_GPL(blkdev_ioctl);
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 1a1fa3ccb913..bc56770bcc90 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -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);
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index ce42889f98fb..19c5e59bcfa8 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -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
@@ -49,7 +48,14 @@
#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;
@@ -1812,6 +1815,90 @@ static void ub_probe_timeout(unsigned long arg)
}
/*
+ * 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.
*/
static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe)
@@ -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;
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
index 647a71b12a2a..ac96de15d833 100644
--- a/drivers/cdrom/cdu31a.c
+++ b/drivers/cdrom/cdu31a.c
@@ -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);
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
index ccde7ab491d4..07bbd24e3c18 100644
--- a/drivers/cdrom/mcdx.c
+++ b/drivers/cdrom/mcdx.c
@@ -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");
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index fc2c433f6a29..452d34675159 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -5895,7 +5895,7 @@ int __init sbpcd_init(void)
}
/*==========================================================================*/
#ifdef MODULE
-void sbpcd_exit(void)
+static void sbpcd_exit(void)
{
int j;
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index fcca26c89bbc..38dd9ffbe8bc 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -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 */
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index e162dab64ffd..5ed6515ae01f 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -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.
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index ad9c11391d81..c1fe013c64f3 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -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;
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 0212febda654..9c9c9c2247ce 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -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);
}
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index e62a3c2c44a9..3a41672e4d66 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -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. */
}
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 399c042f68f0..1407945a5892 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -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);
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index a65f8827c283..e572ced9100a 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -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. */
}
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 2f3dfb63bdc6..4d4e602fdc7e 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -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
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 1383c3165ea1..ac19fdcd21c1 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -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);
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index c321a924e38a..f0079e991bdc 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -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;
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 6052bfa04c72..99762b6c19ae 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -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);
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index adbea896c0d2..94943298c03e 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -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);
}
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 8c7d727432bb..51266d6b4d78 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -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),
{ }
};
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 4b3eda267976..d3aa159c9dec 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -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);
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 10c23302dd84..a9fb12c20eb7 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -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;
}
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index a673971f2a90..c8255312b8c1 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -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;
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 54a2914e3a32..11c6950158b3 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -220,5 +220,6 @@
{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}
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index 5b18bee6492e..cd25f28e26a3 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -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 );
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 49d67f5384a2..6dc765dc5413 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -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);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 5419440087fd..298574e16061 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -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++;
diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h
index a0212b004016..62791dd42985 100644
--- a/drivers/char/ipmi/ipmi_si_sm.h
+++ b/drivers/char/ipmi/ipmi_si_sm.h
@@ -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;
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 3ce51c6a1b18..7b19e02f112f 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -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;
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index ec7100556c50..ac9cfa9701ea 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -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;
diff --git a/drivers/char/mbcs.h b/drivers/char/mbcs.h
index 844644d201c5..e7fd47e43257 100644
--- a/drivers/char/mbcs.h
+++ b/drivers/char/mbcs.h
@@ -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);
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 7a245068e3e5..f022f0944434 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -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);
}
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index a2e33ec79615..ca5f42bcaad9 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -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)
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index c812191417c3..fd042060809a 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -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:
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 06e5a3f1836d..26e5e19ed854 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -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
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
index c337978dc966..b14d642439ed 100644
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -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);
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 95882bb1950e..60c9be99c6d9 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -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
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 67b16e5a41a7..71fc3b4173f1 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -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
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 8e561313d094..03b5fb2ddcf4 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -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
index 000000000000..e1df376e709e
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -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);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 8d83a21c6477..c1fc9c62bb51 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -34,13 +34,9 @@
*/
#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)
{
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 2084593937c6..741b6b191e6a 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -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);
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
index 6d5df6c2efa2..df1b721154d2 100644
--- a/drivers/firmware/pcdp.c
+++ b/drivers/firmware/pcdp.c
@@ -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>
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index 35710818fe47..fdd881aee618 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -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
@@ -57,10 +58,11 @@
#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))
diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
index dd0d4c463146..867d443e7133 100644
--- a/drivers/i2c/busses/i2c-keywest.c
+++ b/drivers/i2c/busses/i2c-keywest.c
@@ -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;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 33a020faeabd..39f3e9101ed4 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -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);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 5d54f7756100..3302cd8eab4c 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -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);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 36c0b74a4e45..c949e98df4b6 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -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);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 554473a95cf7..5d876f53c697 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -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;
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index bdff5ac58053..4063d2c34e3d 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -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);
}
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 482544854985..5a3dc46008e6 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -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);
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 973dec799b5c..dae1bd5b8c3e 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -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
*/
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 47225e324356..4e0f13d1d060 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -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);
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 9d70ba5ea59b..16b3e2d8bfb1 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -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;
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index 78b201fb5e8a..7d58af1ae306 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -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
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 1c5845f7e4ab..a294e45c77cd 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -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 **/
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
index 09908b9564d8..0aa876360f9b 100644
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ b/drivers/ieee1394/ieee1394_transactions.c
@@ -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 */
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h
index 526a43ceb496..45ba784fe6da 100644
--- a/drivers/ieee1394/ieee1394_transactions.h
+++ b/drivers/ieee1394/ieee1394_transactions.h
@@ -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 */
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index a1e30a66297b..83e66ed97ab5 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -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;
}
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 6cb0b586c297..36e25ac823dc 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -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;
diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h
index d1758d409610..cc66c1cae250 100644
--- a/drivers/ieee1394/ohci1394.h
+++ b/drivers/ieee1394/ohci1394.h
@@ -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;
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index a261d2b0e5ac..bdb3a85cafa6 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -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
}
diff --git a/drivers/ieee1394/pcilynx.h b/drivers/ieee1394/pcilynx.h
index 644ec55d3d46..d631aa8383ad 100644
--- a/drivers/ieee1394/pcilynx.h
+++ b/drivers/ieee1394/pcilynx.h
@@ -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,
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 4bedf7113f40..d68c4658f2fc 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -35,6 +35,11 @@
*
*/
+/* 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;
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index d4233ee61c35..276e1a53010d 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -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 ?
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 56b9c2fa2ecc..9d912d6877ff 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -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;
diff --git a/drivers/infiniband/include/ib_sa.h b/drivers/infiniband/include/ib_sa.h
index f4f747707b30..00222285eb9a 100644
--- a/drivers/infiniband/include/ib_sa.h
+++ b/drivers/infiniband/include/ib_sa.h
@@ -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;
diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig
index 6282f460aba0..1d93f5092904 100644
--- a/drivers/input/gameport/Kconfig
+++ b/drivers/input/gameport/Kconfig
@@ -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
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 7d7527f8b02d..627d343dfba1 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -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;
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index ff66ed4ee2cd..48fdf1e517cf 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -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);
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 1f85a9718c89..42a9f7f6f8cb 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -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");
}
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index cd8509549eac..019034b21a0b 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -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;
}
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 69832f8fb720..36c721227b68 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -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;
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 564974ce5793..96fb9870834a 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -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;
}
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index f64867808fea..0487ecbb8a49 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -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[] = {
{
@@ -115,12 +117,26 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
},
},
{
+ .ident = "Fujitsu Lifebook S6230",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
+ },
+ },
+ {
.ident = "Fujitsu T70H",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
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;
}
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 8e63e464d361..5900de3c3f4f 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -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;
}
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 3313e2daeab0..0beacb77ee18 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -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.
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 22f73683952b..f6b85222ba3d 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -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);
}
/*
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
index c9d0a153671c..53a27e43dd23 100644
--- a/drivers/input/touchscreen/gunze.c
+++ b/drivers/input/touchscreen/gunze.c
@@ -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;
}
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index e0ac63effa55..d09308f30960 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -39,15 +39,16 @@
#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);
}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index e654aa5eecd4..b941ee220997 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -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();
diff --git a/drivers/md/dm-emc.c b/drivers/md/dm-emc.c
index 700658664594..c7067674dcb7 100644
--- a/drivers/md/dm-emc.c
+++ b/drivers/md/dm-emc.c
@@ -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))
diff --git a/drivers/md/dm-hw-handler.c b/drivers/md/dm-hw-handler.c
index ae63772e44c9..4cc0010e0156 100644
--- a/drivers/md/dm-hw-handler.c
+++ b/drivers/md/dm-hw-handler.c
@@ -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;
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 43763a0bd096..0c1b8520ef86 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -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",
diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c
index ac5c4bbec6c1..a28c1c2b4ef5 100644
--- a/drivers/md/dm-path-selector.c
+++ b/drivers/md/dm-path-selector.c
@@ -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;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index ee175d4906c4..18e9b9953fcd 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -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;
diff --git a/drivers/md/dm-zero.c b/drivers/md/dm-zero.c
index 7febc2cac73d..51c0639b2487 100644
--- a/drivers/md/dm-zero.c
+++ b/drivers/md/dm-zero.c
@@ -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);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 243ff6884e83..f6b03957efc7 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -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)
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 161e9aa87291..b1941b887f46 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -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))
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 97af857d8a88..d899204d3743 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -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;
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 1891e4930dcc..2ae2d709cb15 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -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:
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 83380b5d6593..1db5de52d376 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -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:
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index e9dc2876a626..3c37be6423d7 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -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...
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index e96e2a10a9c9..3cb11ac232fa 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -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:
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 8a33f351e092..908edd78a792 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -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) {
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 9f6c19ac1285..50e8b8654018 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -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)");
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 883ec08490f4..4983e1b1bb1d 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -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"
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 52596907a0be..99bd675df955 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -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.
-
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index 9fb1247bfab8..7703812af34f 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -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
index 000d60c405e3..000000000000
--- a/drivers/media/dvb/b2c2/b2c2-common.c
+++ /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
index 9306da046c91..000000000000
--- a/drivers/media/dvb/b2c2/b2c2-usb-core.c
+++ /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
index 000000000000..773d158032df
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -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
index 000000000000..8d2706075360
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -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
index 000000000000..bbcf070a178d
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-eeprom.c
@@ -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
index 000000000000..71be400e9aeb
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -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
index 000000000000..2baf43d3ce8f
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -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
index 000000000000..be4266d4ae91
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -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
index 000000000000..19e06da46774
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -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
index 000000000000..ed717c0073d5
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -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
index 000000000000..5e131be55cb3
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -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
index 000000000000..01570ec80962
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-sram.c
@@ -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
index 000000000000..0113449abd15
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -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
index 000000000000..630e647a2caa
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop-usb.h
@@ -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
index 000000000000..8b5d14dd36e3
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -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
index 000000000000..caa343a97bdc
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop.h
@@ -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
diff --git a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c
index 336c178fcd5f..acbc4c34f72a 100644
--- a/drivers/media/dvb/b2c2/skystar2.c
+++ b/drivers/media/dvb/b2c2/skystar2.c
@@ -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);
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index e7d11e0667a8..b12545f093f8 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -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.
-
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile
index 9da8604b9e18..d188e4c670b5 100644
--- a/drivers/media/dvb/bt8xx/Makefile
+++ b/drivers/media/dvb/bt8xx/Makefile
@@ -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
-
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 213ff7902024..3c5a8e273c4a 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -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 */
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
index e1b9809d1b08..837623f7fcdf 100644
--- a/drivers/media/dvb/bt8xx/bt878.h
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -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)
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index eac83768dfd0..1339912c308b 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -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>
@@ -31,59 +31,22 @@
#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
index bcb418c5c121..000000000000
--- a/drivers/media/dvb/bt8xx/dst.h
+++ /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
index 000000000000..d781504cc2fa
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -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
index 000000000000..59cd0ddd6d8e
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_ca.h
@@ -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
index 000000000000..0b3da29245fb
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -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
diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/dvb/bt8xx/dst_priv.h
index 80488aa628b4..3974a4c6ebe7 100644
--- a/drivers/media/dvb/bt8xx/dst_priv.h
+++ b/drivers/media/dvb/bt8xx/dst_priv.h
@@ -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);
-
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index b735397f59aa..6f857c6091f3 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -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);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 80ef189f930f..2923b3b0dd3c 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -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;
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 28d4d926de3e..96c57fde95a0 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -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);
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
index 04e54ec093f0..400b439e804e 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
@@ -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;
}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
index 2ed89488c7c4..5a71b88797d9 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
@@ -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
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb.h b/drivers/media/dvb/dibusb/dvb-dibusb.h
index 52cd35dd9d83..c965b64fb1ab 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb.h
+++ b/drivers/media/dvb/dibusb/dvb-dibusb.h
@@ -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;
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 1863f1dfb00c..c225de7ffd82 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -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__);
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index c1ea89f2880c..0eb9aa711fb0 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -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__);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 59a9adfae1eb..d19301d90a09 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -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);
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 44892e7abd3d..6a968c346a36 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -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;
}
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index cf4ffe38fda3..9d9662f4b8e6 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -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);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 184edba3caa7..a251867f30f1 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -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,
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 0bfd4df17d08..75fb556ec01f 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -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
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c
index ce2eaa1640e8..72a2b5455b0b 100644
--- a/drivers/media/dvb/frontends/at76c651.c
+++ b/drivers/media/dvb/frontends/at76c651.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
index a212279042b8..0c2ed4438618 100644
--- a/drivers/media/dvb/frontends/cx22700.c
+++ b/drivers/media/dvb/frontends/cx22700.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index 011860ce36cc..f4aa44136c7c 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index ae16112a0653..8222b88cb486 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index a853d12a26f1..6f52d649e97e 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -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));
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 4a31c05eaecd..888f10a5e96b 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -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));
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 016c794a5677..c4c3c56c4a81 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -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
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
index c05a9b05600c..cff93b9d8ab2 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index 9ac95de9834d..031a1ddc7d11 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index 176a22e3441b..e455aecd76b2 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -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;
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index 50326c7248fa..d32dc4de9e7f 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -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:
- */
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
index f5d8a5aed8a9..03040cd595bb 100644
--- a/drivers/media/dvb/frontends/mt352.h
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -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:
- */
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
index 4743aa17406e..35a1d60f1927 100644
--- a/drivers/media/dvb/frontends/nxt2002.c
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
index a41f7da8b842..966de9853d18 100644
--- a/drivers/media/dvb/frontends/nxt6000.c
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -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);
diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb/frontends/nxt6000_priv.h
index 64b1a89b2a22..0422e580038a 100644
--- a/drivers/media/dvb/frontends/nxt6000_priv.h
+++ b/drivers/media/dvb/frontends/nxt6000_priv.h
@@ -65,12 +65,27 @@
#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)
@@ -117,6 +132,12 @@
#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)
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index df5dee7760a3..cc0a77c790f1 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -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);
}
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
index 58ad34ef0a00..764a95a2e212 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index 7eae833ece49..d868a6927a16 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index 502c6403dfc6..e681263bf079 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -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;
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 15b40541b62d..cfa3928bb487 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -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).");
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 4e40d95ee95d..87d5f4d8790f 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 687ad9cf3384..0beb370792ae 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -35,9 +35,10 @@
#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).");
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index e452fc0bad11..c8e1d54ff262 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -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);
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
index da82e90d6d13..168e013d23bd 100644
--- a/drivers/media/dvb/frontends/tda8083.c
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
index c99632114283..032d348dafb7 100644
--- a/drivers/media/dvb/frontends/tda80xx.c
+++ b/drivers/media/dvb/frontends/tda80xx.c
@@ -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 */
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
index 9c0d23e1d9e5..70fb44b391a7 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -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;
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c
index edcad283aa86..821df8e839d0 100644
--- a/drivers/media/dvb/frontends/ves1x93.c
+++ b/drivers/media/dvb/frontends/ves1x93.c
@@ -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 */
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 922c205a2652..8e33a850e13e 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -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
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index 5070e0523da7..4f69b4d01479 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -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);
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index d77e8a00688f..ccf946125d02 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -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;
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index 21f7aacf7726..c3801e328fe9 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -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);
}
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index bd6e5ea4aefe..7fa4a0ebe133 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -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;
}
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index bf901c624682..52061e17c6dd 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -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 */
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 6d2256f1e354..665cdb8a3f71 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -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;
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index eb84fb08d95c..e65fc36e2ce8 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -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);
}
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 14e963206b89..6e0f5d307c52 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -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).");
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 521111be3558..dce116111376 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -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;
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index 93a9b40917e4..0498a055a4cd 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -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);
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 5d524a4f213f..8142e26b47f5 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -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;
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 5e6a10f4ad95..083fd44e5f90 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -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;
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h
index 10bd41f0363b..c6ef496ba70a 100644
--- a/drivers/media/dvb/ttpci/budget.h
+++ b/drivers/media/dvb/ttpci/budget.h
@@ -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
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 4c046ece883a..afa0e7a0e506 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -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);
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 64e771bd8907..505bdaff5a7e 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -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);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index d3dd4228b72d..6c05fddb69ab 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -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.
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 85224b90e394..6334122704ae 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -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",
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index e42f1ec13f3e..c2368bc832ed 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -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);
}
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index cee13584c9cf..1db022682980 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -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;
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 2021e099e35a..fa1357336907 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -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;
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 881a0539fc17..6212388edb75 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -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:
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
index 31cc4ed9b747..5f870075b55e 100644
--- a/drivers/media/video/video-buf-dvb.c
+++ b/drivers/media/video/video-buf-dvb.c
@@ -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);
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 7b74c87b569e..4830b7759061 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -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);
};
/*
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 72f2b466b816..4991bbd054f3 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -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.
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index b5b4a7b11903..d4eee99c2bf6 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -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) {
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 39747526c719..b7fbd30b49a0 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -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...) \
@@ -52,10 +54,6 @@
#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)
{
@@ -79,28 +77,61 @@ void DBG_REG(int reg, u8 value)
#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);
}
@@ -133,6 +164,13 @@ static void wbsd_init_device(struct wbsd_host* host)
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.
*/
host->clk = wbsd_read_index(host, WBSD_IDX_CLK);
@@ -148,6 +186,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.
*/
ier = 0;
@@ -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)");
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h
index fdc03b56a81f..864f30828d01 100644
--- a/drivers/mmc/wbsd.h
+++ b/drivers/mmc/wbsd.h
@@ -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 */
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 43e2ac532f82..b5e076043431 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -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);
}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 68242bda4b9c..f08e01b2fd19 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -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
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 6202b10dbb4d..30c7567001fe 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -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/
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index fc519377b5aa..fb433325aa27 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -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>
*
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index f2e937abf7b4..b7dd7260cafb 100755
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -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);
}
diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig
index 60b19679ca5c..69c488d933a2 100644
--- a/drivers/net/appletalk/Kconfig
+++ b/drivers/net/appletalk/Kconfig
@@ -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.
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 2161c2d585f0..9edaa183227a 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -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);
diff --git a/drivers/net/appletalk/cops_ffdrv.h b/drivers/net/appletalk/cops_ffdrv.h
index 4131b4a7a65b..31cf8c9c947f 100644
--- a/drivers/net/appletalk/cops_ffdrv.h
+++ b/drivers/net/appletalk/cops_ffdrv.h
@@ -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,
diff --git a/drivers/net/appletalk/cops_ltdrv.h b/drivers/net/appletalk/cops_ltdrv.h
index 05de66dd9206..4afb8e18ba65 100644
--- a/drivers/net/appletalk/cops_ltdrv.h
+++ b/drivers/net/appletalk/cops_ltdrv.h
@@ -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,
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index ad8e943231a1..db4f369637b6 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -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;
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
index 16e155b04129..66485585ab39 100644
--- a/drivers/net/arcnet/capmode.c
+++ b/drivers/net/arcnet/capmode.c
@@ -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
index 000000000000..8acc655ec1e8
--- /dev/null
+++ b/drivers/net/bnx2.c
@@ -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
index 000000000000..8214a2853d0d
--- /dev/null
+++ b/drivers/net/bnx2.h
@@ -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
index 000000000000..35f3a2ae5ef1
--- /dev/null
+++ b/drivers/net/bnx2_fw.h
@@ -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 };
+
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 770e28f98fd5..269a5e407349 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -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);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 1b68dd5a49b6..4a47df5a9ff9 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -155,9 +155,9 @@
#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)
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 148930d4e9bd..af1e82c5b808 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -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_ */
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 0a2ca7c73a41..237247f74df4 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -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;
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 786a9b935659..723589b28be5 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -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,274 +1047,398 @@ 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) {
+ return E1000_SUCCESS;
+}
- 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);
+/********************************************************************
+* 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 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);
+ DEBUGFUNC("e1000_copper_link_igp_setup");
- /* 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->phy_reset_disable)
+ return E1000_SUCCESS;
+
+ ret_val = e1000_phy_reset(hw);
+ if (ret_val) {
+ DEBUGOUT("Error Resetting the PHY\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;
+ /* Wait 10ms for MAC to configure PHY from eeprom settings */
+ msec_delay(15);
- 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;
+ /* 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);
- } 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;
+ /* 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;
+ }
- /* set auto-master slave resolution settings */
- if(hw->autoneg) {
- e1000_ms_type phy_ms_setting = hw->master_slave;
+ /* 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;
- if(hw->ffe_config_state == e1000_ffe_config_active)
- hw->ffe_config_state = e1000_ffe_config_enabled;
+ 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->dsp_config_state == e1000_dsp_config_activated)
- hw->dsp_config_state = e1000_dsp_config_enabled;
+ } else {
+ hw->dsp_config_state = e1000_dsp_config_enabled;
+ phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
- /* 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;
- }
+ 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;
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
- if(ret_val)
- return ret_val;
+ /* set auto-master slave resolution settings */
+ if(hw->autoneg) {
+ e1000_ms_type phy_ms_setting = hw->master_slave;
- /* 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(hw->ffe_config_state == e1000_ffe_config_active)
+ hw->ffe_config_state = e1000_ffe_config_enabled;
+
+ if(hw->dsp_config_state == e1000_dsp_config_activated)
+ hw->dsp_config_state = e1000_dsp_config_enabled;
+
+ /* 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;
+ }
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+ ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
+ if(ret_val)
+ return ret_val;
- /* 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;
+ /* 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 (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:
+ 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:
- phy_data |= M88E1000_PSCR_AUTO_X_MODE;
- break;
- }
+ break;
+ }
+ ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
+ if(ret_val)
+ return ret_val;
+ }
- /* 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);
- if(ret_val)
- return ret_val;
+ return E1000_SUCCESS;
+}
- /* 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;
+/********************************************************************
+* 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;
+
+ DEBUGFUNC("e1000_copper_link_mgp_setup");
+
+ 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 |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+ /* 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;
+
+ 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
+ */
+ 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;
- if (hw->phy_revision < M88E1011_I_REV_4) {
- /* Configure Master and Slave downshift values */
- phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
+ /* 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 |
+ 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;
- }
+ ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
+ if(ret_val)
+ return ret_val;
+ }
- /* 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;
- }
+ /* 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;
+ }
+
+ return E1000_SUCCESS;
+}
+
+/********************************************************************
+* Setup auto-negotiation and flow control advertisements,
+* and then perform auto-negotiation.
+*
+* hw - Struct containing variables accessed by shared code
+*********************************************************************/
+static int32_t
+e1000_copper_link_autoneg(struct e1000_hw *hw)
+{
+ int32_t ret_val;
+ uint16_t phy_data;
+
+ DEBUGFUNC("e1000_copper_link_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;
+
+ 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;
+
+ 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;
+
+ /* 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;
}
+ }
- /* 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.
- */
+ hw->get_link_status = TRUE;
- /* 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;
+ return E1000_SUCCESS;
+}
- /* 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");
+/******************************************************************************
+* 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;
+ }
- /* 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;
+ /* 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;
+}
- 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;
+/******************************************************************************
+* 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;
- /* 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;
- }
+ 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;
}
- } /* !hw->phy_reset_disable */
+ }
/* Check link status. Wait up to 100 microseconds for link to become
* valid.
@@ -1242,37 +1452,11 @@ e1000_setup_copper_link(struct e1000_hw *hw)
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");
+ /* 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");
-
- 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;
}
@@ -1302,10 +1486,10 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
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;
+ /* 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
@@ -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,6 +3814,132 @@ e1000_read_eeprom(struct e1000_hw *hw,
}
/******************************************************************************
+ * Reads a 16 bit word from the EEPROM using the EERD register.
+ *
+ * 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_read_eeprom_eerd(struct e1000_hw *hw,
+ uint16_t offset,
+ uint16_t words,
+ uint16_t *data)
+{
+ uint32_t i, eerd = 0;
+ int32_t error = 0;
+
+ for (i = 0; i < words; i++) {
+ eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) +
+ E1000_EEPROM_RW_REG_START;
+
+ E1000_WRITE_REG(hw, EERD, eerd);
+ error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);
+
+ if(error) {
+ break;
+ }
+ data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA);
+
+ }
+
+ return error;
+}
+
+/******************************************************************************
+ * Writes a 16 bit word from the EEPROM using the EEWR register.
+ *
+ * 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_write_eeprom_eewr(struct e1000_hw *hw,
+ uint16_t offset,
+ uint16_t words,
+ uint16_t *data)
+{
+ uint32_t register_value = 0;
+ uint32_t i = 0;
+ int32_t error = 0;
+
+ 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;
+
+ 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
@@ -3585,6 +3956,25 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw)
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");
@@ -3628,6 +4018,8 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
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;
@@ -3833,6 +4229,65 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw,
}
/******************************************************************************
+ * 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
*
* hw - Struct containing variables accessed by shared code
@@ -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,6 +5931,338 @@ e1000_set_vco_speed(struct e1000_hw *hw)
return E1000_SUCCESS;
}
+
+/*****************************************************************************
+ * 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)
+{
+ uint8_t i;
+ uint32_t offset = E1000_MNG_DHCP_COOKIE_OFFSET;
+ uint8_t length = E1000_MNG_DHCP_COOKIE_LENGTH;
+
+ length = (length >> 2);
+ offset = (offset >> 2);
+
+ for (i = 0; i < length; i++) {
+ *((uint32_t *) buffer + i) =
+ E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i);
+ }
+ return E1000_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * 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)
{
@@ -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;
+}
+
+
+
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index f397e637a3c5..a0263ee96c6b 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -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
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 82549a6fcfb3..325495b8b60c 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -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
@@ -29,33 +29,9 @@
#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 a 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);
}
@@ -2684,6 +3197,95 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
}
/**
+ * 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);
diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
index 970c656a517c..aac64de61437 100644
--- a/drivers/net/e1000/e1000_osdep.h
+++ b/drivers/net/e1000/e1000_osdep.h
@@ -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
@@ -42,7 +42,12 @@
#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_ */
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index e914d09fe6f9..676247f9f1cc 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -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);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index cda48c5d72a9..4ebcd052e150 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -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>
@@ -109,6 +110,7 @@
#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;
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index 34068f81d45e..7cdebe1a0b61 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -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
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 1c563f905a59..a7f15d9f13e5 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -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;
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
index ab44358ddbfc..6482d994d489 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ b/drivers/net/ibm_emac/ibm_emac_core.c
@@ -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:
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index 6bf76a444d48..ca5914091d3a 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -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.
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 855f8b2cf13b..55af32e9bf08 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -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);
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index 26c4f15f7fc0..f8d3385c7842 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -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 4 /* 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)))
diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c
index 653e99f919ce..3aae110c5560 100644
--- a/drivers/net/ixgb/ixgb_ee.c
+++ b/drivers/net/ixgb/ixgb_ee.c
@@ -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);
}
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index aea10e8aaa72..3fa113854eeb 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -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 */
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 7d26623d8592..35f6a7c271a2 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -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);
diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
index 9eba92891901..dba20481ee80 100644
--- a/drivers/net/ixgb/ixgb_osdep.h
+++ b/drivers/net/ixgb/ixgb_osdep.h
@@ -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
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 2ffc31708d5f..b33111e21313 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -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>
*
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 223bdadd4c0d..babb59e146ea 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -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);
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 2fcc181a8624..c336b46bd332 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -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.
@@ -63,9 +63,11 @@
* - 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;
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 41e517114807..c6e8b25f9685 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -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--;
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 17947e6c8793..13f114876965 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -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 */
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index c59507f8a76b..d6d0e43dab65 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -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--;
}
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
index e68cf5fb4920..20edeb345792 100644
--- a/drivers/net/shaper.c
+++ b/drivers/net/shaper.c
@@ -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);
}
/*
@@ -311,19 +288,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);
}
/*
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 3e9d9aab0588..3107aed0fb51 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -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,
};
/**
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 058c70c6f1ac..a0b8848049c9 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -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
@@ -133,6 +138,8 @@
/* 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);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 8de6f21037ba..993f84c93dc4 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -876,10 +876,12 @@
#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
@@ -892,8 +894,10 @@
#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) */
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index a7ffa64502dd..9680a308c62b 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -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 */
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
index edae09a4b021..919c40cd635c 100644
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -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. */
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index d098b3ba3538..e0ae3ed6e578 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -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 =
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 35791934a602..66b94668ddd8 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -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.
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 0aaa12c0c098..1d3231cc471a 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -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
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 463c789cdc77..fb10a2db63ad 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -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
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index a91b507e0a7a..a4ed28d9c783 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -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" },
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index 731010e0e6f6..16a2e6ae37f4 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -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
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index c5774e7855d0..e7f3bcb79000 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -67,6 +67,10 @@
#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 */
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index 021d0f76bc4c..3903f8c559b6 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -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);
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
index 3ddd75937a40..d9769b30be9a 100644
--- a/drivers/pci/hotplug/cpci_hotplug.h
+++ b/drivers/pci/hotplug/cpci_hotplug.h
@@ -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
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index ed243605dc7b..30af105271a2 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -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.
*
@@ -33,11 +33,11 @@
#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"
@@ -45,18 +45,19 @@
#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);
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index 2e969616f298..225b5e551dd6 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -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.
*
@@ -32,20 +32,16 @@
#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;
}
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
index 5bc039da647f..c22e0284d7b1 100644
--- a/drivers/pci/hotplug/ibmphp.h
+++ b/drivers/pci/hotplug/ibmphp.h
@@ -196,7 +196,7 @@ struct ebda_hpc_bus {
/********************************************************************
-* THREE TYPE OF HOT PLUG CONTROLER *
+* THREE TYPE OF HOT PLUG CONTROLLER *
********************************************************************/
struct isa_ctlr_access {
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
index 6894b548c8ca..1a3eb8d3d4cb 100644
--- a/drivers/pci/hotplug/ibmphp_hpc.c
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -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);
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
index 2335fac65fb4..8122fe734aa7 100644
--- a/drivers/pci/hotplug/ibmphp_pci.c
+++ b/drivers/pci/hotplug/ibmphp_pci.c
@@ -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;
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h
index 57ace325168d..88d44f7fef29 100644
--- a/drivers/pci/hotplug/pci_hotplug.h
+++ b/drivers/pci/hotplug/pci_hotplug.h
@@ -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.
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index f313121d5141..46b294a12418 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -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 {
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 72baf749e65e..df4915dbc321 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -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 */ }
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 9e70c4681f77..1cda30bd6e47 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -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);
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
index 6605d6bda529..3194d51c6ec9 100644
--- a/drivers/pci/hotplug/pcihp_skeleton.c
+++ b/drivers/pci/hotplug/pcihp_skeleton.c
@@ -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);
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index f0c53f850aed..a70a5c5705f2 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -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);
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 9f90eb8e6ecd..490a9553a062 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -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;
}
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
index 243a51d88b86..7957cdc72cd0 100644
--- a/drivers/pci/hotplug/shpchprm_acpi.c
+++ b/drivers/pci/hotplug/shpchprm_acpi.c
@@ -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) {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 22ecd3b058be..30206ac43c44 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -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.
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 968eb32f292d..bc01d34e2634 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -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 (
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 37b7961efc44..fe98553c978f 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -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);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index d57ae71d32b1..6ca0061137a6 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -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;
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index bfbff8335268..f04b9ffe4153 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -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;
}
/**
@@ -749,17 +749,6 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask)
}
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)
{
if (!pci_dma_supported(dev, 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);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 79cdc16c52c8..744da0d4ae5f 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -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 */
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
index 93481b41b613..1d2ef1e2ffc6 100644
--- a/drivers/pci/pci.ids
+++ b/drivers/pci/pci.ids
@@ -7173,6 +7173,7 @@
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
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index 4037a3e568de..3e84b501e6a4 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -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;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6f0edadd132c..fd48b201eb53 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -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)
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 84cc4f620d8d..e68bbfb1e7c3 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -15,6 +15,7 @@
#include <asm/uaccess.h>
#include <asm/byteorder.h>
+#include "pci.h"
static int proc_initialized; /* = 0 */
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 15a398051682..968033fd29f0 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -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,24 +456,16 @@ 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
* support the PCI_INTERRUPT_LINE register at all. Therefore
@@ -493,6 +488,31 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vi
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
* external device.
@@ -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
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 66150d08b5c7..c4ade288c5da 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -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;
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 3f4364341d8d..20642f0e7bfe 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -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;
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 52c073a9d7e4..a8a1d104524a 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -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);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 02cfe244e069..ceeb3cf64a16 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -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
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 7cabb80a2e41..90d4d0ef3dd4 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -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
diff --git a/drivers/s390/net/ctcdbug.h b/drivers/s390/net/ctcdbug.h
index ef8883951720..7fe2ebd1792d 100644
--- a/drivers/s390/net/ctcdbug.h
+++ b/drivers/s390/net/ctcdbug.h
@@ -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
@@ -25,9 +25,11 @@
* 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
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 7266bf5ea659..ff3e95e07e89 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -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
*
@@ -37,12 +37,11 @@
* 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 $
*
*/
#undef DEBUG
-
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -74,288 +73,13 @@
#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
-
-
-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;
-}
-
-/**
- * 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;
-}
-
/**
* 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);
-}
-
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,
@@ -3005,6 +2717,21 @@ static struct attribute_group ctc_attr_group = {
};
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)
{
pr_debug("%s() called\n", __FUNCTION__);
@@ -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,10 +2787,70 @@ 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
index 000000000000..ba3605f16335
--- /dev/null
+++ b/drivers/s390/net/ctcmain.h
@@ -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
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
index 9257d60c7833..3080393e823d 100644
--- a/drivers/s390/net/ctctty.c
+++ b/drivers/s390/net/ctctty.c
@@ -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);
diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c
index 1b0a9f16024c..0075894c71db 100644
--- a/drivers/s390/net/cu3088.c
+++ b/drivers/s390/net/cu3088.c
@@ -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 */ }
};
diff --git a/drivers/s390/net/cu3088.h b/drivers/s390/net/cu3088.h
index 0ec49a8b3adc..1753661f702a 100644
--- a/drivers/s390/net/cu3088.h
+++ b/drivers/s390/net/cu3088.h
@@ -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,
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index 1ac6563ee3e0..e08e74e16124 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -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 $
*
*/
@@ -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
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 0f76e945b984..cccfed248e70 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -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:
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index a341041a6cf7..a755b57db46b 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -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 */
}
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index 7ee1c06ed68a..f94f1f25eec6 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -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,
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 607b92542df6..208127a5033a 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -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;
@@ -540,6 +543,12 @@ qeth_set_offline(struct ccwgroup_device *cgdev)
}
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);
@@ -2278,6 +2344,16 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
}
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 :
@@ -3894,67 +3981,29 @@ 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) {
@@ -4184,6 +4251,25 @@ out:
}
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)
{
int ipv = 0;
@@ -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
index c91976274e7b..000000000000
--- a/drivers/s390/net/qeth_tso.c
+++ /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;
-}
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
index 83504dee3f57..ad33e6f466f1 100644
--- a/drivers/s390/net/qeth_tso.h
+++ b/drivers/s390/net/qeth_tso.h
@@ -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.
*
@@ -7,52 +7,148 @@
*
* 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__ */
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 1f9aeb4accc6..68d151aaa474 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -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 \
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 0afa1c4696ca..c5daf372f853 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -61,7 +61,6 @@
#include <linux/mempool.h>
#include <linux/syscalls.h>
#include <linux/ioctl.h>
-#include <linux/ioctl32.h>
/************************ DEBUG FLAGS *****************************************/
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
index e5fa1703856b..650d5e924f47 100644
--- a/drivers/sbus/char/aurora.c
+++ b/drivers/sbus/char/aurora.c
@@ -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);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 750b11cefd93..27fec8a5eb5b 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -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
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index 3c86655a5f33..74b93564a258 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -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"));
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index c9b82687ba1a..242fa77513f5 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -450,7 +450,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
}
}
- return 0;
+ return err;
}
/**
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index da5bd33d982d..fc5263c6b102 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -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)
diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c
index c2b47f2bdffd..682ca0b32b44 100644
--- a/drivers/scsi/aic7xxx/aic7770_osm.c
+++ b/drivers/scsi/aic7xxx/aic7770_osm.c
@@ -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
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 550c9921691a..7c02b7dc7098 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -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();
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index e60f9338e44a..c13e56320010 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -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,52 +2198,15 @@ 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
* full error information available when making
@@ -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,
@@ -3013,22 +2362,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
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
* there, check the pending_scb list. 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);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index c401537067b6..30c200d5bcd5 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -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>
@@ -66,18 +67,21 @@
#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
@@ -106,7 +110,7 @@
/************************* 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
@@ -382,11 +371,6 @@ struct ahc_linux_device {
ahc_linux_dev_flags flags;
/*
- * Per device timer.
- */
- struct timer_list timer;
-
- /*
* The high limit for the tags variable.
*/
u_int maxtags;
@@ -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);
@@ -657,57 +593,6 @@ ahc_unlock(struct ahc_softc *ahc, unsigned long *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)
{
spin_lock_init(&ahc_list_spinlock);
@@ -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);
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index 6f6674aa31ef..2a0ebce83e7a 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -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);
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c
index 85e80eecc9d0..5fece859fbd9 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_proc.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c
@@ -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;
diff --git a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c
index 79bfd9efd8ed..7c5a6db0e672 100644
--- a/drivers/scsi/aic7xxx/aiclib.c
+++ b/drivers/scsi/aic7xxx/aiclib.c
@@ -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"
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 3867f91ef8c7..3be546439252 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -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);
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 2e2486b035dd..83f062ed9082 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -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);
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 0b5d3a5b7eda..9e58f134f68b 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -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);
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 4c96df060c3b..7a4adc4c8f09 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -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.
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 6518226b8f87..d90430bbb0de 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -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;
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 2240a0cde583..9bc1f153f7ea 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -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)
{
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index e4bfe4d5bbe4..2efec6c24d60 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -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 *);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 84db911318c6..3c97aa45772d 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -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;
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index 69009f853a49..b0403ccd8a25 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -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)
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 19a13e3590f4..b18c90582e67 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -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,
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index dfd362104717..1383e8a28d72 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -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)
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index f0489dc302a0..49ed557a4b66 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -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));
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 5105ddd08447..e418b89c6b9d 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -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 = {
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 8d1a5d25c053..edef1fa969fc 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -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);
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 70118650c461..140cea05de3f 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -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)
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 0bff4f475f26..a71fb54eebd3 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -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 = {
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 3a7830667277..f43183c19a12 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -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 = {
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index 2c28f0ad73c2..c5e09dc6f3de 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -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)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 05d2bd075fd4..184bcaeaf812 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -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;
}
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index cca772624ae7..8d0d302844a1 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -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)
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 303d7656f710..67c6cc40ce16 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -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"
@@ -34,13 +35,18 @@
#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);
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index 3471be05779a..82d68fdb1548 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -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 */
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index f26c3a29e631..ebfddd40ce67 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -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);
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 5ff83d214f12..5b07c6ec3ecc 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -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;
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 33fbda79f350..0b10169961eb 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -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);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0d9358608fdf..30e8beb71430 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -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));
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index f8d90d0ecfea..de54bdc5398b 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -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
*/
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index f2a5e2933c47..2884b310e54d 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -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);
}
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index d5cbef3fe8b6..7db88ee18f75 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -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);
}
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 6242f3090a96..e92522b33c48 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -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));
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 51d8a49f4477..9dc151d8fa61 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -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));
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 435750d40a47..2a9f7ade2c9d 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -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;
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 157218bc6c6f..98641c3f5ab9 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -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)) |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 6eeb48f6a482..0d7b65f93e8d 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -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;
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index 85cfa08d3bad..56f269b6bfb1 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -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;
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 37b2ef297cbe..3f1051a4a13f 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -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));
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 39b788d95e39..10e2990a40d4 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -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. */
@@ -450,6 +462,25 @@ static void sunsab_stop_tx(struct uart_port *port, unsigned int tty_stop)
}
/* 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)
{
struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
@@ -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;
diff --git a/drivers/serial/sunsab.h b/drivers/serial/sunsab.h
index 686086fcbbf5..b78e1f7b8050 100644
--- a/drivers/serial/sunsab.h
+++ b/drivers/serial/sunsab.h
@@ -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
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 307886199f2f..1f985327b0d4 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -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) {
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index 5538756f13ba..d5863b8b56ee 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -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;
}
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index 143818a56121..51e3f7f6597b 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -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>
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 233f9229badb..2a1697bfd695 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -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;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index e12c5be1e0a3..f50aaf25c98e 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -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.
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index ec9b3bde8ae5..4d0c9e65cd03 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -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 = {
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 16972159a57a..0faf18d511de 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -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.
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 3993156c2e82..3f783cbdc7c3 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -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
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 2cff67ccce45..1e5e6ddef787 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -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)
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index 0def9f70e889..df75ab65a5ec 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -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));
}
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index f1762ed6db63..4d591c764e38 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -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;
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3196c3265ff5..19e598c9641f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -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".
+
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a574ca06cf6b..5dbd3e7a27c7 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -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
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 84d2b93aca37..bc69bd7acebe 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -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;
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 2373537fabed..d7b4f7939ded 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -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);
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index e763a8399a75..4df498231752 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -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));
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index 376f8a034f65..d9883d774d3a 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -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;
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index d309e292198e..99d43f758ad0 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -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
index 000000000000..6e173265095c
--- /dev/null
+++ b/drivers/usb/host/sl811_cs.c
@@ -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);
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index 5791723e6083..a330a4b50e16 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -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
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index 2d76be62f4e0..94ce2a9ad50f 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -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
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 869ff73690ac..2d8bd9dcc6ed 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -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 },
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index 6b45a66d58c1..ab1a2a30ce7c 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -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
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
index d6051822416e..036c485d1d1e 100644
--- a/drivers/usb/media/ov511.c
+++ b/drivers/usb/media/ov511.c
@@ -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
index b2eb71a9afb5..000000000000
--- a/drivers/usb/media/pwc/ChangeLog
+++ /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.
diff --git a/drivers/usb/media/pwc/Makefile b/drivers/usb/media/pwc/Makefile
index e0b41ed4407f..2d93a775011a 100644
--- a/drivers/usb/media/pwc/Makefile
+++ b/drivers/usb/media/pwc/Makefile
@@ -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
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c
index 42352f531bc0..53099190952c 100644
--- a/drivers/usb/media/pwc/pwc-ctrl.c
+++ b/drivers/usb/media/pwc/pwc-ctrl.c
@@ -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
index 57d03d9178f6..000000000000
--- a/drivers/usb/media/pwc/pwc-dec1.c
+++ /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
index a7ffd9c45a2c..000000000000
--- a/drivers/usb/media/pwc/pwc-dec1.h
+++ /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
index 98fa3f7a9eff..000000000000
--- a/drivers/usb/media/pwc/pwc-dec23.c
+++ /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
index 5b2aacdefa6c..000000000000
--- a/drivers/usb/media/pwc/pwc-dec23.h
+++ /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
-
-
-
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index c53e2263b7fb..b77e65c03659 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -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.
diff --git a/drivers/usb/media/pwc/pwc-ioctl.h b/drivers/usb/media/pwc/pwc-ioctl.h
index 65805eaa9a1c..5f9cb08bc02e 100644
--- a/drivers/usb/media/pwc/pwc-ioctl.h
+++ b/drivers/usb/media/pwc/pwc-ioctl.h
@@ -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 */
diff --git a/drivers/usb/media/pwc/pwc-kiara.c b/drivers/usb/media/pwc/pwc-kiara.c
index 5485800efd83..c498c68bace1 100644
--- a/drivers/usb/media/pwc/pwc-kiara.c
+++ b/drivers/usb/media/pwc/pwc-kiara.c
@@ -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}
- }
- }
-};
-
diff --git a/drivers/usb/media/pwc/pwc-timon.c b/drivers/usb/media/pwc/pwc-timon.c
index f950a4e5ed96..dee967173d6c 100644
--- a/drivers/usb/media/pwc/pwc-timon.c
+++ b/drivers/usb/media/pwc/pwc-timon.c
@@ -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}
- }
- }
-};
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c
index c062e43b3ac5..bc3b1635eab0 100644
--- a/drivers/usb/media/pwc/pwc-uncompress.c
+++ b/drivers/usb/media/pwc/pwc-uncompress.c
@@ -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;
}
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index dd4580cb57e0..7d06105763d4 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -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);
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
index db64c908d4a7..b104430e2c6a 100644
--- a/drivers/usb/net/Kconfig
+++ b/drivers/usb/net/Kconfig
@@ -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)"
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index a45ea7c97356..4cbb408af727 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -1517,6 +1517,26 @@ static void cdc_unbind (struct usbnet *dev, struct usb_interface *intf)
}
}
+#endif /* NEED_GENERIC_CDC */
+
+
+#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 */
-
-
-#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.
*/
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
index f98cb2af024e..341ae5f732dd 100644
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -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
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 0c4aa00bb39d..9438909e87a5 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -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
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index b0aac47d1959..6c7cdcc99a9e 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -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
index 000000000000..a4ce0008d69b
--- /dev/null
+++ b/drivers/usb/serial/airprime.c
@@ -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");
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 7e9bb63eb466..4ace9964fc6b 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -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;
}
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index d165f42d560d..012e63e05806 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -16,6 +16,14 @@
* 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
@@ -32,12 +40,6 @@
* 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. */
@@ -72,11 +74,12 @@
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");
diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h
index 1012ee6b19ce..1fa119efe41a 100644
--- a/drivers/usb/serial/cypress_m8.h
+++ b/drivers/usb/serial/cypress_m8.h
@@ -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
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 4c788c767a97..3bfcc7b9f861 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -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.
*
@@ -264,7 +264,7 @@
/*
* 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)
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index be5d60bf90b9..8866376823a5 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -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 */
@@ -137,7 +136,7 @@
/*
* 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 */
@@ -145,6 +144,8 @@
/* 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
@@ -157,7 +158,8 @@
*/
#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 */
@@ -236,10 +238,10 @@
/*
* 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/)
@@ -247,6 +249,26 @@
#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 */
@@ -259,10 +281,6 @@
#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
diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h
index 8c1fa5e722b1..f1804fd5a3dd 100644
--- a/drivers/usb/serial/io_usbvend.h
+++ b/drivers/usb/serial/io_usbvend.h
@@ -289,7 +289,7 @@
//
//
-// 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
diff --git a/drivers/usb/serial/keyspan_usa90msg.h b/drivers/usb/serial/keyspan_usa90msg.h
index dd935b62c1a8..86708ecd8735 100644
--- a/drivers/usb/serial/keyspan_usa90msg.h
+++ b/drivers/usb/serial/keyspan_usa90msg.h
@@ -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
index 000000000000..b722175f108f
--- /dev/null
+++ b/drivers/usb/serial/option.c
@@ -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");
+
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 4536f63faaea..5da76dd8fb28 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -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:
diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c
index d76483706bc9..5a9321705a74 100644
--- a/drivers/usb/storage/debug.c
+++ b/drivers/usb/storage/debug.c
@@ -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"
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index 7eff03d9b041..f3b60288696c 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -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;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index bbda63c24c4d..9fcc7bd1fbe4 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -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 $
*
@@ -48,6 +48,14 @@
* 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",
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index ee25b9e8db60..47a6b12bc968 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -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;
}
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 208a68ceb63b..7705070191d9 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -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;
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 2bdda4010b81..277d733c6d00 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -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),
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index e04d3e8b2549..a9a618f2aa6a 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -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");
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 549e22939260..25f9a9a65c24 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -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");
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
index de5a0f383600..2fc71081f7e7 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/macmodes.c
@@ -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");
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c
index 1994054d45ff..ecfd72178dbb 100644
--- a/drivers/video/sis/init.c
+++ b/drivers/video/sis/init.c
@@ -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;
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index 35030d300431..7e36b7ac1470 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -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,
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index 2bc5b8097910..274dacd54bb8 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -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)
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index f05aebc994b4..f84eb54164a5 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -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);
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index b773c98f6513..698266036819 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -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();
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 672a31924f3c..e172180a1d8c 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -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,
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index ce9423bb2de3..c374be51b041 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -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));
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index f0cd67d9d31b..c8998dc66882 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -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)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index d19d07c49ad3..c0cbd1bc1a02 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -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)
diff --git a/fs/buffer.c b/fs/buffer.c
index 5f525b3c6d9f..7e9e409feaa7 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -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
diff --git a/fs/char_dev.c b/fs/char_dev.c
index a745b1d9e545..c1e3537909fc 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -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)) {
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 95483baab706..dab4774ee7bb 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -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
------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 7b4ac096cd11..34b0cf7111f3 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -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
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index d00b3bfe1a52..78af5850c558 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -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 */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 0010511083fc..ea239dea571e 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -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);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 741ff0c69f37..3c628bf667a5 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -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;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index e3137aa48cdd..3f3538d4a1fa 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -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 */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index dde2d251fc3d..30ab70ce5547 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -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;
}
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 670947288262..8d336a900255 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -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,
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index db14b503d89e..072b4ee8c53e 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -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);
diff --git a/fs/dcache.c b/fs/dcache.c
index 496a4e08369c..3aa8a7e980d8 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -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);
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 05b966cd6f76..9900e333655a 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -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;
diff --git a/fs/exec.c b/fs/exec.c
index a8394499926c..e56ee2437025 100644
--- 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;
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index ea5888688f94..0d5fa73b18dc 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -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,
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 545b440a2d2f..981ccb233ef5 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -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);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index e6c63d9cac7b..4bf43ea87c46 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -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:
diff --git a/fs/inode.c b/fs/inode.c
index af8fd78d2099..801fe7f36280 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -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 */
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 98d830401c56..5a97e346bd95 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -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
diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c
index 450d6624181f..09422388fb96 100644
--- a/fs/jffs2/compr_rubin.c
+++ b/fs/jffs2/compr_rubin.c
@@ -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;
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index 9f9932c22adb..078a30e406b5 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -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;
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index 2c1f311914a1..31b34db4519e 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -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:
diff --git a/fs/locks.c b/fs/locks.c
index 1792ce547af7..3fa6a7ce57a7 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -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;
diff --git a/fs/mbcache.c b/fs/mbcache.c
index f9e4d2700cd8..c7170b9221a3 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -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)");
diff --git a/fs/mpage.c b/fs/mpage.c
index 32c7c8fcfce7..bb9aebe93862 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -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)
@@ -627,15 +630,6 @@ 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;
sector_t last_block_in_bio = 0;
@@ -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)
diff --git a/fs/namei.c b/fs/namei.c
index 9e4aef2a1a21..a7f7f44119b3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -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;
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 73f96acd5d37..ff6155f5e8d9 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -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)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f06eee6dcff5..55c907592490 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -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.
*
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index b74c4e3a64e2..87f4f9aeac86 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -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;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 6345f26e87ee..f2317f3e29f9 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -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");
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index 897512796edb..a912debcd20b 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -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,
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index 17ee1b4ff087..584a27b2bbd5 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -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)) {
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 07cafdf74ef2..e31903aadd96 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -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;
diff --git a/fs/proc/mmu.c b/fs/proc/mmu.c
index a7041038ad56..25d2d9c6e329 100644
--- a/fs/proc/mmu.c
+++ b/fs/proc/mmu.c
@@ -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)
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 67423c696c0a..6fd57f154197 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -12,15 +12,8 @@
#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;
}
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 80e92d9b81cb..7d4dc5f5aa8b 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -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;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index da23ba75f3d5..c47f8fd31a2d 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -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
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 31e75125f48b..b35b87744983 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -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
diff --git a/fs/select.c b/fs/select.c
index 25b1ccac2f2c..b80e7eb0ac0d 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -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;
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index c2634bda6b50..85d8dbe843f1 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -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;
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 554e4a18c152..d3ff78354638 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -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
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 76a84758073a..93ce257cd149 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -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);
}
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 23e0eb67fc25..997963e53622 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -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);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 9f057a4a5b06..24fa3b101b93 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -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,
};
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 7a12c83184f5..0f8f1384eb36 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -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);
}
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.h b/fs/xfs/linux-2.6/xfs_ioctl32.h
index 779f69a48116..c874793a1dc9 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.h
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.h
@@ -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);
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index ff145fd0d1a4..aa9daaea6c34 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -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);
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 53dc658cafa6..455e2b2fb964 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -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>
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index 849c61c74f3c..a832d165f24f 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -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);
}
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index da76c1f1e11c..00466c3194ac 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -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 *);
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 08d551a17347..63abdc2ac7f4 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -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) {
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 3a0ba1dfd0e8..d3da00045f26 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -136,6 +136,40 @@ xfs_chash_free(xfs_mount_t *mp)
}
/*
+ * 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
* represented by the mount point parameter mp. Each bucket of
@@ -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);
/*
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 43c632ab86ad..bc8c8c7f9039 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -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,
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index a53b1ccf6070..37e1c316f3b6 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -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 *);
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 3826e8f0e28a..469e1a7939d4 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -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;
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 31c91087cb33..4daaa5212102 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -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__*/
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index b57423caef9b..2ec967d93e5a 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -301,6 +301,15 @@ xfs_mount_validate_sb(
}
/*
+ * 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.
*/
if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) {
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 5fc6201dd8e2..30dd08fb9f57 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -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
/*
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 04609d27ea51..e4bf711e48ff 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -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)
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 816b945fa0ea..d1f8146a06ea 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -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 */
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index e1ed6a588000..01d98b4b7af7 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -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 *);
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 00aae9c6a904..b53736650100 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -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);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 70092963ca9e..25a526629b12 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -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));
diff --git a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h
index c99dbbb5bcb5..ef855a3bc0f5 100644
--- a/include/asm-alpha/agp.h
+++ b/include/asm-alpha/agp.h
@@ -10,4 +10,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
diff --git a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h
index 4e0842b415aa..1a2c52a056fb 100644
--- a/include/asm-alpha/signal.h
+++ b/include/asm-alpha/signal.h
@@ -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 {
diff --git a/include/asm-arm/arch-imx/imx-regs.h b/include/asm-arm/arch-imx/imx-regs.h
index f32c203952cf..93b840e8fa60 100644
--- a/include/asm-arm/arch-imx/imx-regs.h
+++ b/include/asm-arm/arch-imx/imx-regs.h
@@ -228,6 +228,30 @@
#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
*/
#define DCR __REG(IMX_DMAC_BASE +0x00) /* DMA Control Register */
diff --git a/include/asm-arm/arch-imx/imxfb.h b/include/asm-arm/arch-imx/imxfb.h
new file mode 100644
index 000000000000..2346d454ab9c
--- /dev/null
+++ b/include/asm-arm/arch-imx/imxfb.h
@@ -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);
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
index a8e3c2daefd6..083462668e18 100644
--- a/include/asm-arm/arch-ixp2000/io.h
+++ b/include/asm-arm/arch-ixp2000/io.h
@@ -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;
}
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 39741d3c9a34..b5e54a9e9fa7 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1296,6 +1296,7 @@
#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 */
@@ -1428,6 +1429,7 @@
#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)
diff --git a/include/asm-arm/arch-s3c2410/regs-nand.h b/include/asm-arm/arch-s3c2410/regs-nand.h
index c443ac834698..7cff235e667a 100644
--- a/include/asm-arm/arch-s3c2410/regs-nand.h
+++ b/include/asm-arm/arch-s3c2410/regs-nand.h
@@ -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
@@ -26,6 +27,22 @@
#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)
@@ -37,7 +54,28 @@
#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 */
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index cbceacbe5afa..a1696ba238d3 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -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
diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h
index 4ca3a8e9348f..019c45d75730 100644
--- a/include/asm-arm/page.h
+++ b/include/asm-arm/page.h
@@ -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)
{
diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h
index 4a9845997a75..7d4118e09054 100644
--- a/include/asm-arm/processor.h
+++ b/include/asm-arm/processor.h
@@ -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.
diff --git a/include/asm-arm/signal.h b/include/asm-arm/signal.h
index b860dc3c5dc7..46e69ae395af 100644
--- a/include/asm-arm/signal.h
+++ b/include/asm-arm/signal.h
@@ -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 {
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index a61618fb433c..66c585c50cf9 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -14,6 +14,10 @@
#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
*/
diff --git a/include/asm-arm26/elf.h b/include/asm-arm26/elf.h
index 8b149474db24..5a47fdb3015d 100644
--- a/include/asm-arm26/elf.h
+++ b/include/asm-arm26/elf.h
@@ -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
diff --git a/include/asm-arm26/signal.h b/include/asm-arm26/signal.h
index a1aacefa6562..37ad25355591 100644
--- a/include/asm-arm26/signal.h
+++ b/include/asm-arm26/signal.h
@@ -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
diff --git a/include/asm-cris/signal.h b/include/asm-cris/signal.h
index 2330769ba55d..dfe039593a78 100644
--- a/include/asm-cris/signal.h
+++ b/include/asm-cris/signal.h
@@ -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 {
diff --git a/include/asm-frv/signal.h b/include/asm-frv/signal.h
index c930bb176875..d407bde57eca 100644
--- a/include/asm-frv/signal.h
+++ b/include/asm-frv/signal.h
@@ -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 {
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 976ac29598b7..195ccdc069e6 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -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
index 000000000000..9418d6e9b8cd
--- /dev/null
+++ b/include/asm-generic/signal.h
@@ -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
diff --git a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h
index 82431edeb2a1..1ec8a3427120 100644
--- a/include/asm-h8300/kmap_types.h
+++ b/include/asm-h8300/kmap_types.h
@@ -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
};
diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h
index abe08856c84f..63f727a59850 100644
--- a/include/asm-h8300/mman.h
+++ b/include/asm-h8300/mman.h
@@ -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 */
diff --git a/include/asm-h8300/signal.h b/include/asm-h8300/signal.h
index ac3e01bd6396..8eccdc176163 100644
--- a/include/asm-h8300/signal.h
+++ b/include/asm-h8300/signal.h
@@ -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 {
diff --git a/include/asm-i386/agp.h b/include/asm-i386/agp.h
index a917ff50354f..b82f5f3ab887 100644
--- a/include/asm-i386/agp.h
+++ b/include/asm-i386/agp.h
@@ -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
diff --git a/include/asm-i386/floppy.h b/include/asm-i386/floppy.h
index f4782284807a..79727afb94c9 100644
--- a/include/asm-i386/floppy.h
+++ b/include/asm-i386/floppy.h
@@ -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);
diff --git a/include/asm-i386/linkage.h b/include/asm-i386/linkage.h
index af3d8571c5c7..f4a6ebac0247 100644
--- a/include/asm-i386/linkage.h
+++ b/include/asm-i386/linkage.h
@@ -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
diff --git a/include/asm-i386/mach-numaq/mach_ipi.h b/include/asm-i386/mach-numaq/mach_ipi.h
index 1b46fd3f2ae3..c6044488e9e6 100644
--- a/include/asm-i386/mach-numaq/mach_ipi.h
+++ b/include/asm-i386/mach-numaq/mach_ipi.h
@@ -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)
{
diff --git a/include/asm-i386/module.h b/include/asm-i386/module.h
index 508865e26308..eb7f2b4234aa 100644
--- a/include/asm-i386/module.h
+++ b/include/asm-i386/module.h
@@ -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
diff --git a/include/asm-i386/signal.h b/include/asm-i386/signal.h
index 0f082bd1c455..cbb47d34aa31 100644
--- a/include/asm-i386/signal.h
+++ b/include/asm-i386/signal.h
@@ -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 {
diff --git a/include/asm-i386/timer.h b/include/asm-i386/timer.h
index 40c54f69780e..c34709849839 100644
--- a/include/asm-i386/timer.h
+++ b/include/asm-i386/timer.h
@@ -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);
diff --git a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h
index d1316f1e6ee1..4e517f0e6afa 100644
--- a/include/asm-ia64/agp.h
+++ b/include/asm-ia64/agp.h
@@ -18,4 +18,14 @@
#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
index d0d227f45e05..000000000000
--- a/include/asm-ia64/ioctl32.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <linux/ioctl32.h>
diff --git a/include/asm-ia64/perfmon.h b/include/asm-ia64/perfmon.h
index ed5416c5b1ac..7f3333dd00e4 100644
--- a/include/asm-ia64/perfmon.h
+++ b/include/asm-ia64/perfmon.h
@@ -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
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index ea121a002309..fcc9c3344ab4 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -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
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 9e1ba8b7fb68..91bbd1f22461 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -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(); \
diff --git a/include/asm-ia64/signal.h b/include/asm-ia64/signal.h
index 85a577ae9146..608168d713d3 100644
--- a/include/asm-ia64/signal.h
+++ b/include/asm-ia64/signal.h
@@ -118,13 +118,7 @@
#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__
@@ -133,9 +127,6 @@
/* 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;
diff --git a/include/asm-ia64/sn/addrs.h b/include/asm-ia64/sn/addrs.h
index 960d626ee589..1bfdfb4d7b01 100644
--- a/include/asm-ia64/sn/addrs.h
+++ b/include/asm-ia64/sn/addrs.h
@@ -136,6 +136,7 @@
*/
#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)
/*
@@ -161,6 +162,13 @@
/*
+ * 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
* of any given node.
diff --git a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h
index 7c349f07916a..635fdce854a8 100644
--- a/include/asm-ia64/sn/arch.h
+++ b/include/asm-ia64/sn/arch.h
@@ -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
index 5f4ad8f4b5d2..000000000000
--- a/include/asm-ia64/sn/fetchop.h
+++ /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 */
-
diff --git a/include/asm-ia64/sn/l1.h b/include/asm-ia64/sn/l1.h
index d5dbd55e44b5..08050d37b662 100644
--- a/include/asm-ia64/sn/l1.h
+++ b/include/asm-ia64/sn/l1.h
@@ -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 */
diff --git a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h
index 13cc1002b294..7138b1eafd6b 100644
--- a/include/asm-ia64/sn/nodepda.h
+++ b/include/asm-ia64/sn/nodepda.h
@@ -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 */
diff --git a/include/asm-ia64/sn/pda.h b/include/asm-ia64/sn/pda.h
index cd19f17bf91a..ea5590c76ca4 100644
--- a/include/asm-ia64/sn/pda.h
+++ b/include/asm-ia64/sn/pda.h
@@ -24,14 +24,6 @@
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;
diff --git a/include/asm-ia64/sn/shub_mmr.h b/include/asm-ia64/sn/shub_mmr.h
index 2f885088e095..323fa0cd8d83 100644
--- a/include/asm-ia64/sn/shub_mmr.h
+++ b/include/asm-ia64/sn/shub_mmr.h
@@ -385,6 +385,17 @@
#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 */
/* ==================================================================== */
@@ -429,6 +440,19 @@
#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 */
diff --git a/include/asm-ia64/sn/shubio.h b/include/asm-ia64/sn/shubio.h
index fbd880e6bb96..831b72111fdc 100644
--- a/include/asm-ia64/sn/shubio.h
+++ b/include/asm-ia64/sn/shubio.h
@@ -3,292 +3,287 @@
* 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 */
diff --git a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
index 685435af170d..20b300187669 100644
--- a/include/asm-ia64/sn/sn_cpuid.h
+++ b/include/asm-ia64/sn/sn_cpuid.h
@@ -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.
*/
@@ -92,24 +92,24 @@
* 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
index 8c21ac3f0156..000000000000
--- a/include/asm-ia64/sn/sn_fru.h
+++ /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 */
-
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
index f914f6da077c..eb0395ad0d6a 100644
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -115,6 +115,13 @@
#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
@@ -342,6 +349,25 @@ ia64_sn_plat_cpei_handler(void)
}
/*
+ * 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.
*/
static inline u64
@@ -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
index aa00d42cde32..000000000000
--- a/include/asm-ia64/sn/sndrv.h
+++ /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
index 000000000000..9902185c0288
--- /dev/null
+++ b/include/asm-ia64/sn/xp.h
@@ -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 */
+
diff --git a/include/asm-m32r/signal.h b/include/asm-m32r/signal.h
index 6e55fd421883..95f69b191953 100644
--- a/include/asm-m32r/signal.h
+++ b/include/asm-m32r/signal.h
@@ -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 {
diff --git a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h
index 1d016e9f19bf..a0cdf9082372 100644
--- a/include/asm-m68k/signal.h
+++ b/include/asm-m68k/signal.h
@@ -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 */
};
diff --git a/include/asm-m68knommu/signal.h b/include/asm-m68knommu/signal.h
index 37c9c8a024ba..1d13187f6062 100644
--- a/include/asm-m68knommu/signal.h
+++ b/include/asm-m68knommu/signal.h
@@ -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 {
diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h
index d81356731eb6..f2c470f1d369 100644
--- a/include/asm-mips/signal.h
+++ b/include/asm-mips/signal.h
@@ -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;
diff --git a/include/asm-parisc/floppy.h b/include/asm-parisc/floppy.h
index 47f53df2cef5..ca3aed768cdc 100644
--- a/include/asm-parisc/floppy.h
+++ b/include/asm-parisc/floppy.h
@@ -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);
diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h
index be27cfa8c5b0..ca9e423307f4 100644
--- a/include/asm-ppc/agp.h
+++ b/include/asm-ppc/agp.h
@@ -10,4 +10,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
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
index 42fd1068cf2a..c5883dbed63f 100644
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -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__ */
diff --git a/include/asm-ppc/m8260_pci.h b/include/asm-ppc/m8260_pci.h
index 163a6b91d5b2..bf9e05dd54b5 100644
--- a/include/asm-ppc/m8260_pci.h
+++ b/include/asm-ppc/m8260_pci.h
@@ -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
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index d820894e5991..89eb8a2ac693 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -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.
diff --git a/include/asm-ppc/sigcontext.h b/include/asm-ppc/sigcontext.h
index f82dcccdee1e..b7a417e0a921 100644
--- a/include/asm-ppc/sigcontext.h
+++ b/include/asm-ppc/sigcontext.h
@@ -2,7 +2,7 @@
#define _ASM_PPC_SIGCONTEXT_H
#include <asm/ptrace.h>
-
+#include <linux/compiler.h>
struct sigcontext {
unsigned long _unused[4];
diff --git a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h
index d890dabd5a69..caf6ede3710f 100644
--- a/include/asm-ppc/signal.h
+++ b/include/asm-ppc/signal.h
@@ -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;
diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h
index be27cfa8c5b0..ca9e423307f4 100644
--- a/include/asm-ppc64/agp.h
+++ b/include/asm-ppc64/agp.h
@@ -10,4 +10,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
diff --git a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h
index 6c42d61bedd1..085eedb956fe 100644
--- a/include/asm-ppc64/elf.h
+++ b/include/asm-ppc64/elf.h
@@ -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)
diff --git a/include/asm-ppc64/iSeries/mf.h b/include/asm-ppc64/iSeries/mf.h
index 2e59a8e15a0b..db333e1ee216 100644
--- a/include/asm-ppc64/iSeries/mf.h
+++ b/include/asm-ppc64/iSeries/mf.h
@@ -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
index 000000000000..3a45e918bf16
--- /dev/null
+++ b/include/asm-ppc64/imalloc.h
@@ -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 */
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
index 188987e9d9d4..c78282a67d8e 100644
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-ppc64/mmu.h
@@ -15,19 +15,10 @@
#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_ */
diff --git a/include/asm-ppc64/mmu_context.h b/include/asm-ppc64/mmu_context.h
index c2e8e0466383..77a743402db4 100644
--- a/include/asm-ppc64/mmu_context.h
+++ b/include/asm-ppc64/mmu_context.h
@@ -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 */
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
index 86219574c1a5..bcd21789d3b7 100644
--- a/include/asm-ppc64/page.h
+++ b/include/asm-ppc64/page.h
@@ -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)
@@ -100,7 +96,6 @@
#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))
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
index b984e2747e0c..264c4f7993be 100644
--- a/include/asm-ppc64/pgtable.h
+++ b/include/asm-ppc64/pgtable.h
@@ -17,16 +17,6 @@
#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
@@ -40,40 +30,30 @@
#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.
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
index 0035efe2db2b..809c634ba1df 100644
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -120,103 +120,18 @@
/* 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 */
@@ -225,23 +140,8 @@
#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 */
@@ -249,9 +149,6 @@
#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 */
@@ -264,50 +161,12 @@
#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
@@ -352,28 +211,19 @@
#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
@@ -389,10 +239,6 @@
#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 */
@@ -436,12 +282,6 @@
#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__ */
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
index 2440a2c90ae9..04b1a84f7ca3 100644
--- a/include/asm-ppc64/prom.h
+++ b/include/asm-ppc64/prom.h
@@ -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);
diff --git a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h
index a2d7bbb4befd..432df7dd355d 100644
--- a/include/asm-ppc64/signal.h
+++ b/include/asm-ppc64/signal.h
@@ -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 */
};
diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
index 037b5e06083c..48b7900e90ec 100644
--- a/include/asm-ppc64/thread_info.h
+++ b/include/asm-ppc64/thread_info.h
@@ -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)
diff --git a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h
index 0027da4364ac..fdec5e7a7af6 100644
--- a/include/asm-ppc64/xics.h
+++ b/include/asm-ppc64/xics.h
@@ -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 */
diff --git a/include/asm-s390/signal.h b/include/asm-s390/signal.h
index bfed83a818cc..3d6e11c6c1fd 100644
--- a/include/asm-s390/signal.h
+++ b/include/asm-s390/signal.h
@@ -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 {
diff --git a/include/asm-s390/user.h b/include/asm-s390/user.h
index c64f8c181df3..1dc74baf03c4 100644
--- a/include/asm-s390/user.h
+++ b/include/asm-s390/user.h
@@ -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
diff --git a/include/asm-sh/floppy.h b/include/asm-sh/floppy.h
index f030ca08052b..38d7a2942476 100644
--- a/include/asm-sh/floppy.h
+++ b/include/asm-sh/floppy.h
@@ -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);
diff --git a/include/asm-sh/signal.h b/include/asm-sh/signal.h
index 29f1ac1bf4df..d6e8eb0e65c7 100644
--- a/include/asm-sh/signal.h
+++ b/include/asm-sh/signal.h
@@ -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 {
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h
index d82f883d8e6d..4bbbd9f3c37e 100644
--- a/include/asm-sh/thread_info.h
+++ b/include/asm-sh/thread_info.h
@@ -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
diff --git a/include/asm-sh64/signal.h b/include/asm-sh64/signal.h
index 864c94ecc98c..2400dc688a65 100644
--- a/include/asm-sh64/signal.h
+++ b/include/asm-sh64/signal.h
@@ -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 {
diff --git a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h
index e65f394da472..8a32d6bd0b79 100644
--- a/include/asm-sh64/thread_info.h
+++ b/include/asm-sh64/thread_info.h
@@ -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 */
diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h
index 780ee7ff9dc3..caf926116506 100644
--- a/include/asm-sparc/floppy.h
+++ b/include/asm-sparc/floppy.h
@@ -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;
}
}
diff --git a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h
index f792e10e704f..aa9960ad0ca9 100644
--- a/include/asm-sparc/signal.h
+++ b/include/asm-sparc/signal.h
@@ -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 {
diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h
index f461144067ee..0a780e84a12b 100644
--- a/include/asm-sparc/uaccess.h
+++ b/include/asm-sparc/uaccess.h
@@ -41,10 +41,11 @@
* 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)
diff --git a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h
index ba05bdf9a211..58f8cb6ae767 100644
--- a/include/asm-sparc64/agp.h
+++ b/include/asm-sparc64/agp.h
@@ -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
diff --git a/include/asm-sparc64/iommu.h b/include/asm-sparc64/iommu.h
index 5fd16e42a045..0de7a3da79cd 100644
--- a/include/asm-sparc64/iommu.h
+++ b/include/asm-sparc64/iommu.h
@@ -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) */
diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h
index ab88349ddadc..b7e635544cec 100644
--- a/include/asm-sparc64/parport.h
+++ b/include/asm-sparc64/parport.h
@@ -13,6 +13,12 @@
#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;
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h
index 92999631c819..4c15610a2bac 100644
--- a/include/asm-sparc64/pbm.h
+++ b/include/asm-sparc64/pbm.h
@@ -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
diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h
index 2c28e1f605b7..b9b1914aae63 100644
--- a/include/asm-sparc64/pgalloc.h
+++ b/include/asm-sparc64/pgalloc.h
@@ -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);
diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
index 466d021d7038..becdf1bc5924 100644
--- a/include/asm-sparc64/signal.h
+++ b/include/asm-sparc64/signal.h
@@ -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;
diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h
index ad78ce64d69e..9d7613eea812 100644
--- a/include/asm-sparc64/spitfire.h
+++ b/include/asm-sparc64/spitfire.h
@@ -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
index 99a9de4728da..000000000000
--- a/include/asm-um/arch-signal-i386.h
+++ /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:
- */
diff --git a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
index 6f78de5b621b..49e89b8d7e58 100644
--- a/include/asm-um/archparam-i386.h
+++ b/include/asm-um/archparam-i386.h
@@ -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 **********/
diff --git a/include/asm-um/archparam-ppc.h b/include/asm-um/archparam-ppc.h
index 0ebced92a762..172cd6ffacc4 100644
--- a/include/asm-um/archparam-ppc.h
+++ b/include/asm-um/archparam-ppc.h
@@ -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;
diff --git a/include/asm-um/archparam-x86_64.h b/include/asm-um/archparam-x86_64.h
index 96321c4892f1..270ed9586b68 100644
--- a/include/asm-um/archparam-x86_64.h
+++ b/include/asm-um/archparam-x86_64.h
@@ -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
diff --git a/include/asm-um/delay.h b/include/asm-um/delay.h
index 40695576ca60..0985bda66750 100644
--- a/include/asm-um/delay.h
+++ b/include/asm-um/delay.h
@@ -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
index 000000000000..9bab712dc5c0
--- /dev/null
+++ b/include/asm-um/elf-i386.h
@@ -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.h b/include/asm-um/elf-ppc.h
index 7908f8fe8231..2998cf925042 100644
--- a/include/asm-um/elf.h
+++ b/include/asm-um/elf-ppc.h
@@ -1,8 +1,7 @@
-#ifndef __UM_ELF_H
-#define __UM_ELF_H
+#ifndef __UM_ELF_PPC_H
+#define __UM_ELF_PPC_H
#include "linux/config.h"
-#include "asm/archparam.h"
extern long elf_aux_hwcap;
#define ELF_HWCAP (elf_aux_hwcap)
@@ -13,7 +12,7 @@ extern long elf_aux_hwcap;
#define elf_check_arch(x) (1)
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_64_BIT
#define ELF_CLASS ELFCLASS64
#else
#define ELF_CLASS ELFCLASS32
@@ -34,4 +33,22 @@ extern long elf_aux_hwcap;
#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
index 000000000000..8a8246d03936
--- /dev/null
+++ b/include/asm-um/elf-x86_64.h
@@ -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/fixmap.h b/include/asm-um/fixmap.h
index 900f3fbb9fab..ae0ca3932d50 100644
--- a/include/asm-um/fixmap.h
+++ b/include/asm-um/fixmap.h
@@ -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
diff --git a/include/asm-um/ipc.h b/include/asm-um/ipc.h
index e2ddc47f3e52..a46e3d9c2a3f 100644
--- a/include/asm-um/ipc.h
+++ b/include/asm-um/ipc.h
@@ -1,6 +1 @@
-#ifndef __UM_IPC_H
-#define __UM_IPC_H
-
-#include "asm/arch/ipc.h"
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-um/linkage.h b/include/asm-um/linkage.h
index 27011652b015..7dfce37adc8b 100644
--- a/include/asm-um/linkage.h
+++ b/include/asm-um/linkage.h
@@ -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
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
index 102eb3df1aaf..5afee8a8cdf3 100644
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -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)
diff --git a/include/asm-um/pgtable-3level.h b/include/asm-um/pgtable-3level.h
index d309f3a9e6f6..65e8bfc55fc4 100644
--- a/include/asm-um/pgtable-3level.h
+++ b/include/asm-um/pgtable-3level.h
@@ -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
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
index 71f9c0c78c0c..a88040920311 100644
--- a/include/asm-um/pgtable.h
+++ b/include/asm-um/pgtable.h
@@ -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)
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
index b953b1ad3b02..b2fc94fbc2d9 100644
--- a/include/asm-um/processor-generic.h
+++ b/include/asm-um/processor-generic.h
@@ -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, \
diff --git a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
index 2deb8f1adbf1..431bad3ae9d7 100644
--- a/include/asm-um/processor-i386.h
+++ b/include/asm-um/processor-i386.h
@@ -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"
diff --git a/include/asm-um/processor-x86_64.h b/include/asm-um/processor-x86_64.h
index a1ae3a4cd938..0beb9a42ae05 100644
--- a/include/asm-um/processor-x86_64.h
+++ b/include/asm-um/processor-x86_64.h
@@ -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; })
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h
index 9e47590ec293..04222f35c43e 100644
--- a/include/asm-um/ptrace-i386.h
+++ b/include/asm-um/ptrace-i386.h
@@ -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"
diff --git a/include/asm-um/ptrace-x86_64.h b/include/asm-um/ptrace-x86_64.h
index c34be39b78b2..be51219a8ffe 100644
--- a/include/asm-um/ptrace-x86_64.h
+++ b/include/asm-um/ptrace-x86_64.h
@@ -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))
diff --git a/include/asm-um/setup.h b/include/asm-um/setup.h
index c85252e803c1..99f086301f4c 100644
--- a/include/asm-um/setup.h
+++ b/include/asm-um/setup.h
@@ -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
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index bffb577bc54e..1feaaf148ef1 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -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
diff --git a/include/asm-v850/signal.h b/include/asm-v850/signal.h
index ec3566c875d9..cb52caa69925 100644
--- a/include/asm-v850/signal.h
+++ b/include/asm-v850/signal.h
@@ -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__
diff --git a/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h
index 0bb9019d58aa..06c52ee9c06b 100644
--- a/include/asm-x86_64/agp.h
+++ b/include/asm-x86_64/agp.h
@@ -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
diff --git a/include/asm-x86_64/apicdef.h b/include/asm-x86_64/apicdef.h
index 3d7627ffe67d..bfebdb690654 100644
--- a/include/asm-x86_64/apicdef.h
+++ b/include/asm-x86_64/apicdef.h
@@ -112,7 +112,7 @@
#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.
diff --git a/include/asm-x86_64/bug.h b/include/asm-x86_64/bug.h
index bdbf66eab6ee..3d2a666a5dd5 100644
--- a/include/asm-x86_64/bug.h
+++ b/include/asm-x86_64/bug.h
@@ -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>
diff --git a/include/asm-x86_64/floppy.h b/include/asm-x86_64/floppy.h
index bca9b28a1a0a..af7ded63b517 100644
--- a/include/asm-x86_64/floppy.h
+++ b/include/asm-x86_64/floppy.h
@@ -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);
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
index 7efc932e8f0b..32573749004c 100644
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -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
index d0d227f45e05..000000000000
--- a/include/asm-x86_64/ioctl32.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <linux/ioctl32.h>
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h
index 21d56b086b9d..d3abfc6a8fd5 100644
--- a/include/asm-x86_64/nmi.h
+++ b/include/asm-x86_64/nmi.h
@@ -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 */
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index f0581c35628e..d641b19f6da5 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -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.
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index d0f8f8b4c394..f2f073642d62 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -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);
diff --git a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h
index 4987ad8082ba..fe9b96d94815 100644
--- a/include/asm-x86_64/signal.h
+++ b/include/asm-x86_64/signal.h
@@ -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;
diff --git a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h
index b0c8d4339906..2872da23fc7e 100644
--- a/include/asm-x86_64/vsyscall.h
+++ b/include/asm-x86_64/vsyscall.h
@@ -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__ */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index aefe6d051ace..b123cc08773d 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -25,6 +25,10 @@
#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*/
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 3628f7cfb178..19f04b049798 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -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). */
@@ -96,6 +100,38 @@
#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
diff --git a/include/linux/awe_voice.h b/include/linux/awe_voice.h
index da0e27de752c..4bf9f33048e2 100644
--- a/include/linux/awe_voice.h
+++ b/include/linux/awe_voice.h
@@ -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
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 54f820832c73..7e736e201c46 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -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);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index f21af067d015..927daa86c9b3 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -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.
*/
diff --git a/include/linux/device.h b/include/linux/device.h
index cf470459fa69..df94c0de53f2 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -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
diff --git a/include/linux/err.h b/include/linux/err.h
index 17c55df13615..ff71d2af5da3 100644
--- a/include/linux/err.h
+++ b/include/linux/err.h
@@ -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 */
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 396c48cbaeb1..a1478258d002 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -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
@@ -56,18 +56,32 @@ static inline int is_zero_ether_addr(const u8 *addr)
}
/**
+ * 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 */
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index c85b210490ea..a0ab26aab450 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -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);
diff --git a/include/linux/fddidevice.h b/include/linux/fddidevice.h
index 2e5ee47f3e1e..002f6367697d 100644
--- a/include/linux/fddidevice.h
+++ b/include/linux/fddidevice.h
@@ -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>
*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4edba067a717..0180102dace1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -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);
diff --git a/include/linux/gameport.h b/include/linux/gameport.h
index b1272f822cfa..cd623eccdbea 100644
--- a/include/linux/gameport.h
+++ b/include/linux/gameport.h
@@ -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.
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index ebc712e91066..8336dba18971 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -43,13 +43,17 @@
#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))
diff --git a/include/linux/hippidevice.h b/include/linux/hippidevice.h
index 89b3a4a5b761..9debe6bbe5f0 100644
--- a/include/linux/hippidevice.h
+++ b/include/linux/hippidevice.h
@@ -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>
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 9cfc0999becb..336d6e509f59 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -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
diff --git a/include/linux/if.h b/include/linux/if.h
index 110282dbd3e0..d73a9d62f208 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -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
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
index bbf49bcd7705..0856548a2a08 100644
--- a/include/linux/if_arp.h
+++ b/include/linux/if_arp.h
@@ -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>
diff --git a/include/linux/if_ltalk.h b/include/linux/if_ltalk.h
index e75e832b7ff0..76525760ba48 100644
--- a/include/linux/if_ltalk.h
+++ b/include/linux/if_ltalk.h
@@ -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
diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h
index 0485b256d043..004e6f09a6e2 100644
--- a/include/linux/if_shaper.h
+++ b/include/linux/if_shaper.h
@@ -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;
};
diff --git a/include/linux/if_tr.h b/include/linux/if_tr.h
index 4fd451f81ccb..3fba9e2f5427 100644
--- a/include/linux/if_tr.h
+++ b/include/linux/if_tr.h
@@ -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
@@ -19,24 +19,18 @@
#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 */
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 6fafb27877a7..7e1e15f934f3 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -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) && \
diff --git a/include/linux/ixjuser.h b/include/linux/ixjuser.h
index 88121166d715..fd1756d3a47e 100644
--- a/include/linux/ixjuser.h
+++ b/include/linux/ixjuser.h
@@ -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>
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index f20c163de4f5..99ddba5a4e00 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -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;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 505160ab472b..b009f801e7c5 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -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;
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 20971fe78a8d..374b615ea9ea 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -65,9 +65,13 @@
#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 */
@@ -84,9 +88,13 @@
/* 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 */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 8b007ad2d450..17518fe0b311 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -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);
diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h
index 7b904c5102f6..896342817b97 100644
--- a/include/linux/mmc/protocol.h
+++ b/include/linux/mmc/protocol.h
@@ -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
diff --git a/include/linux/mpage.h b/include/linux/mpage.h
index dea1b0083661..3ca880463c47 100644
--- a/include/linux/mpage.h
+++ b/include/linux/mpage.h
@@ -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)
diff --git a/include/linux/net.h b/include/linux/net.h
index e5914c1f0c4d..20cb226b2268 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -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;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 8d775be67833..ba5d1236aa17 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -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);
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index f731abdc1a29..b2738ac8bc99 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -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))
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 9303a003e9ab..5937dd6053c3 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -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
index 000000000000..d974a6e92372
--- /dev/null
+++ b/include/linux/patchkey.h
@@ -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 */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 3c89148ae28a..b5238bd18830 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -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) { }
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 5d5820a4cf10..b8b4ebf9abf1 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -854,6 +854,7 @@
#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
@@ -873,6 +874,7 @@
#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
@@ -1229,6 +1231,12 @@
#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
@@ -2063,12 +2071,14 @@
#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
@@ -2088,6 +2098,7 @@
#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
@@ -2372,6 +2383,8 @@
#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
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 73d84c071cb1..1d9da36eb9db 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -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
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 5f868a588581..4dbb109022f3 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -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 */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index c3fb5984f250..d6025af7efac 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -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
*/
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 0a98f5ec5cae..7be18b5e2fb4 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -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__ */
diff --git a/include/linux/sockios.h b/include/linux/sockios.h
index 5eb33205cc04..e6b9d1d36ea2 100644
--- a/include/linux/sockios.h
+++ b/include/linux/sockios.h
@@ -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
diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h
index 28d2d1881978..523d069c862c 100644
--- a/include/linux/soundcard.h
+++ b/include/linux/soundcard.h
@@ -39,6 +39,13 @@
/* 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
/*
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index e895f3eaf53a..d6ba068719b6 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -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)
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 772998147e3e..a17745c80a91 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -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
};
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h
index aa6b48bb4dcd..a6b2cc530af5 100644
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/linux/tc_ematch/tc_em_meta.h
@@ -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)
diff --git a/include/linux/trdevice.h b/include/linux/trdevice.h
index aaa1f337edcb..99e02ef54c47 100644
--- a/include/linux/trdevice.h
+++ b/include/linux/trdevice.h
@@ -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
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 41d1a644c9d4..2d1ac5058534 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -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 */
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 3a358c895188..6409d9cf5965 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -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);
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 17c874a8eb3f..c9486c3efb4a 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -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) \
diff --git a/include/media/video-buf-dvb.h b/include/media/video-buf-dvb.h
index 94bd33619aa5..ad0a07a3a895 100644
--- a/include/media/video-buf-dvb.h
+++ b/include/media/video-buf-dvb.h
@@ -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;
diff --git a/include/net/act_generic.h b/include/net/act_generic.h
index 95b120781c14..c9daa7e52300 100644
--- a/include/net/act_generic.h
+++ b/include/net/act_generic.h
@@ -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;
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index f1e5af4be98e..a0ed93672176 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -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>
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 3fc192478aa2..e5ef0d15fb45 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -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
diff --git a/include/net/ip.h b/include/net/ip.h
index b4db1375da2c..32360bbe143f 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -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
diff --git a/include/net/route.h b/include/net/route.h
index 22da7579d5de..d34ca8fc6756 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -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);
diff --git a/include/net/sock.h b/include/net/sock.h
index cc4c9190b7fd..a9ef3a6a13f3 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -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;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 9355ae5b1d75..e71f8ba3e101 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -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
diff --git a/include/net/udp.h b/include/net/udp.h
index c496d10101db..ac229b761dbc 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -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:
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index e142a256d5dc..d675836ba6c3 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -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)
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
index 6dcf497bf46d..a30d6cd4c0e8 100644
--- a/include/scsi/scsi_transport_spi.h
+++ b/include/scsi/scsi_transport_spi.h
@@ -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)
diff --git a/init/Kconfig b/init/Kconfig
index 40d286d1d118..a7660ccc693f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -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
diff --git a/kernel/Makefile b/kernel/Makefile
index eb88b446c2cc..b01d26fe8db7 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -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
diff --git a/kernel/audit.c b/kernel/audit.c
index ac26d4d960d3..9c4f1af0c794 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -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. */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 6f1931381bc9..37b3ac94bc47 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -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;
}
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 961d74044deb..00e8f2575512 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -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);
}
}
diff --git a/kernel/exit.c b/kernel/exit.c
index 7be283d98983..edaa50b5bbfa 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -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)
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 2fb0e46e11f3..436c7d93c00a 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -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;
}
diff --git a/kernel/itimer.c b/kernel/itimer.c
index e9a40e947e07..1dc988e0d2c7 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -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);
}
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 1627f8d6e0cd..13bcec151b57 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -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;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 1d5dd1337bd1..037142b72a49 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -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 = {
diff --git a/kernel/module.c b/kernel/module.c
index 5734ab09d3f9..83b3d376708c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -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);
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 7960ddf04a57..4cdebc972ff2 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -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);
diff --git a/kernel/printk.c b/kernel/printk.c
index 290a07ce2c8a..01b58d7d17ff 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -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);
@@ -671,6 +635,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.
*
* Acquires a semaphore which guarantees that the caller has
diff --git a/kernel/profile.c b/kernel/profile.c
index 0221a50ca867..ad8cbb75ffa2 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -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",
diff --git a/kernel/sched.c b/kernel/sched.c
index 0dc3158667a2..f12a0c8a7d98 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -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);
/*
diff --git a/kernel/signal.c b/kernel/signal.c
index 8f3debc77c5b..b3c24c732c5a 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -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)) {
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index e15ed17863f1..0c3f9d8bbe17 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -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;
}
diff --git a/kernel/sys.c b/kernel/sys.c
index f64e97cabe25..f006632c2ba7 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -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;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ac23847ce0e3..0c421295e613 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -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.
diff --git a/lib/sort.c b/lib/sort.c
index ea3caedeabdb..b73dbb0e7c83 100644
--- a/lib/sort.c
+++ b/lib/sort.c
@@ -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);
diff --git a/lib/string.c b/lib/string.c
index 4bb93ad23c60..d886ef157c12 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -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;
diff --git a/mm/filemap.c b/mm/filemap.c
index d5fdae2eb183..4a2fee2cb62b 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -29,11 +29,6 @@
#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;
}
}
}
diff --git a/mm/memory.c b/mm/memory.c
index 6bad4c4064e7..d209f745db7f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -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;
}
/*
diff --git a/mm/mmap.c b/mm/mmap.c
index 01f9793591f6..de54acd9942f 100644
--- 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);
diff --git a/mm/mremap.c b/mm/mremap.c
index 0dd7ace94e51..ec7238a78f36 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -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;
diff --git a/mm/nommu.c b/mm/nommu.c
index b293ec1cc4e6..c53e9c8f6b4a 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -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
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index fc1b1064c505..b1061b1962f8 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -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;
diff --git a/mm/rmap.c b/mm/rmap.c
index 378de234c12b..9827409eb7c7 100644
--- 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);
}
diff --git a/mm/swapfile.c b/mm/swapfile.c
index a60e0075d55b..da48405cd9a3 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -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);
}
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 2bd83e5c2bbf..8ff16a1eee6a 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -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;
diff --git a/net/802/fddi.c b/net/802/fddi.c
index f9a31a9f70f1..ebcf4830d6f1 100644
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -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>
diff --git a/net/802/hippi.c b/net/802/hippi.c
index 4eb135c0afbb..051e8af56a77 100644
--- a/net/802/hippi.c
+++ b/net/802/hippi.c
@@ -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>
diff --git a/net/802/tr.c b/net/802/tr.c
index 85293ccf7efc..a755e880f4ba 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -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,
diff --git a/net/appletalk/dev.c b/net/appletalk/dev.c
index 76598445d84b..1237e208e246 100644
--- a/net/appletalk/dev.c
+++ b/net/appletalk/dev.c
@@ -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);
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index d9b72fde433c..f564ee99782d 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -21,10 +21,7 @@
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;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 69872bf3b87e..91bb895375f4 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -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;
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 2b1cce46cab4..8f5f2e730992 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -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 &&
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index f8fb49e34764..917311c6828b 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -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);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 54d63f1372a0..bdf95a74d8cd 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -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);
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index b91a875aca01..d071f1c9ad0b 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -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)))
diff --git a/net/core/dev.c b/net/core/dev.c
index f5f005846fe1..ab935778ce81 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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>
*
@@ -761,6 +761,18 @@ int dev_change_name(struct net_device *dev, char *newname)
}
/**
+ * 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;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index f05fde97c43d..a3eeb88e1c81 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -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);
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 060f703659e8..e2137f3e489d 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -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,
diff --git a/net/core/sock.c b/net/core/sock.c
index 98171ddd7e7d..96e00b08698f 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -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);
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index e6e23eb14428..ee7bf46eb78a 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -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
};
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 16c4234cbe12..6617ea47d365 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -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>
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index cdad47642ae7..03942f133944 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -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);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index abbc6d5c183e..478a30179a52 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -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 = {
{
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 053a883247ba..eae84cc39d3f 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -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);
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 85bf0d3e294b..cb759484979d 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -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) :
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index a0d0833034be..4e47a2658c7c 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -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>
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 24fe3e00b42b..760dc8238d65 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -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! */
diff --git a/net/ipv4/ipvs/Makefile b/net/ipv4/ipvs/Makefile
index a788461a40c9..30e85de9ffff 100644
--- a/net/ipv4/ipvs/Makefile
+++ b/net/ipv4/ipvs/Makefile
@@ -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)
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
index 253c46252bd5..867d4e9c6594 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/ipv4/ipvs/ip_vs_proto.c
@@ -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
index 191e94aa1c1f..000000000000
--- a/net/ipv4/ipvs/ip_vs_proto_icmp.c
+++ /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,
-};
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
index faa6176bbeb1..de21da00057f 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -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;
}
diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c
index 9349686131fc..c9cf8726051d 100644
--- a/net/ipv4/multipath_drr.c
+++ b/net/ipv4/multipath_drr.c
@@ -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");
diff --git a/net/ipv4/multipath_random.c b/net/ipv4/multipath_random.c
index 805a16e47de5..5249dbe7c559 100644
--- a/net/ipv4/multipath_random.c
+++ b/net/ipv4/multipath_random.c
@@ -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");
diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c
index 554a82568160..b6cd2870478f 100644
--- a/net/ipv4/multipath_rr.c
+++ b/net/ipv4/multipath_rr.c
@@ -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>
@@ -47,29 +48,12 @@
#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");
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index 10b23e1bece6..bd7d75b6abe0 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -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");
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 28d9425d5c39..09e824622977 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -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;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 46ca45f74d85..bc59f7b39805 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -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)
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index e5746b674413..eda1fba431a4 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -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);
}
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index 90a587cacaa4..0db405a869f2 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -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:
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 93624a32eb9a..5b1ec586bae6 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -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:
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 199311746932..a682d28e247b 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -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>
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 3aafb298c1c1..23068bddbf0b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -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;
@@ -396,6 +397,14 @@ ctl_table ipv4_table[] = {
.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",
.maxlen = 0,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5cff56af7855..0d9a4fd5f1a4 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -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;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 6984042c0927..5bad504630a3 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -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);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index fd70509f0d53..eea1a17a9ac2 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -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>
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index a12df6979ffd..fa24e7ae1f40 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -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>
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 85b279f1e935..799ebe061e2c 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -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>
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8a213238f287..7c24e64b443f 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -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)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7744a2592693..2720899d516c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -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",
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 8e0f569b883e..ff3ec9822e36 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -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;
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index a93f6dc51979..0e5f7499debb 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -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;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0f0711417c9d..b78a53586804 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -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);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 3b1c9fa184ae..ba3b0c267f75 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -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;
}
diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
index 2f4c91ddc9a3..5ade5a5d1990 100644
--- a/net/ipv6/ipv6_syms.c
+++ b/net/ipv6/ipv6_syms.c
@@ -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);
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 601a148f60f3..6b9867717d11 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -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;
}
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 4429b1a1fe5f..cf1d91e74c82 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -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;
diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c
index d6ccd3239dcf..70543d89438b 100644
--- a/net/irda/irda_device.c
+++ b/net/irda/irda_device.c
@@ -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
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 4ee392066148..e41ce458c2a9 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -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
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 64acea0adaae..0269616e75a1 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -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>
*
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index b0941186f867..b22c9beb604d 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -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
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index cafcb084098d..914c85ff8fe6 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -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;
}
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 0d2d4415f334..dfb300bb6baa 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -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;
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index f1eeaf65cee5..48bb23c2a35a 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -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
{
@@ -284,6 +285,214 @@ META_COLLECTOR(int_rtiif)
}
/**************************************************************************
+ * 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;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 8a3db9d95bab..d8bd2a569c7c 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -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++;
}
}
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index e0c9fbe73b15..bb9bf8d5003c 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -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;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index b719a77d66b4..fffc880a646d 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -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;
}
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index c9d9ea064734..c7e42d125b9c 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -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;
}
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index e42fd8c2916b..98d49ec9b74b 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -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. */
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 2e1f9c3556f5..5135e1a25d25 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -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;
}
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 0b338eca6dc0..2a3c0e08a090 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -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.
*/
diff --git a/net/socket.c b/net/socket.c
index 2cd44990d8d3..cec0cb38b9ce 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -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:
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c478fc8db776..c420eba4876b 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -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)
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 080aae243ce0..2f4531fcaca2 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -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 */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 55ed979db144..d07f5ce31824 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -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) {
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 5ddda2c98af9..97509011c274 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -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;
}
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index fe11df83d1fc..d3d2e5341051 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -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;
}
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 5a5ddc40f36c..09abb891d11f 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -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
index 000000000000..cc94e46a79e8
--- /dev/null
+++ b/scripts/kconfig/POTFILES.in
@@ -0,0 +1,5 @@
+scripts/kconfig/mconf.c
+scripts/kconfig/conf.c
+scripts/kconfig/confdata.c
+scripts/kconfig/gconf.c
+scripts/kconfig/qconf.cc
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index a494d1aeb9f9..70e7264c6942 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -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;
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 1e82ae390a69..2755c459d780 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -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) : "");
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 6fdbe6e3ce0d..ad6b12043874 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -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
index 000000000000..1c88d7c6d5a7
--- /dev/null
+++ b/scripts/kconfig/kxgettext.c
@@ -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;
+}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index b8a67fc9d647..8b84c42b49b5 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -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);
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 730d316fe7fe..e5db10ca9564 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -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;
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 0c13156f3344..8c59b212722d 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -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;
}
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 0cdbf9dbbd51..4590cd31623f 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -26,8 +26,23 @@
#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
diff --git a/scripts/patch-kernel b/scripts/patch-kernel
index 43af01075612..f2d47ca9c8fa 100755
--- a/scripts/patch-kernel
+++ b/scripts/patch-kernel
@@ -46,6 +46,19 @@
# 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>.
@@ -73,6 +86,19 @@ do
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
findFile () {
@@ -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
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 5a820cf88c9c..8449d667b062 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -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;
}
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 4a6be966bd9f..3a3228b18726 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -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,
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index a9602f89d6b1..e537bd66a707 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -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
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
index 124b1e10a13d..3ecef4689f1b 100644
--- a/sound/oss/ac97_codec.c
+++ b/sound/oss/ac97_codec.c
@@ -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},
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index d143d2c78988..8b33b12fa5dc 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -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" },
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index f1ce808501da..9b4d74d49f98 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -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;
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 32d94754acf8..080ef3928465 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -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;
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 84b0bbddbd22..aae66144d411 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -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);
}
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index b06a267e5dac..89ee8b732013 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -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.
@@ -143,7 +148,7 @@
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);
}
}